I would like to create a menu that consists of three layers.
The menu is supposed to stretch over the entire screen width.
The first layer is an image that contains a gradient. Since the menu is stretched over the width the amount of change/width in color depends. It looks something like this:
The second layer looks just like the first layer, but lets say blue instead of red. So it contains that same gradient. I want to overlay parts of this layer with the first to highlight a selected menu item.
The third layer contains the menu items.
Here's a jsfiddle: http://jsfiddle.net/UrVq2/9/
and it's corresponding code:
HTML:
<div id="firstLayer"></div>
<div id="secondLayer"></div>
<div id="thirdLayer">Click me</div>
CSS:
#firstLayer {
background-image:url('http://s21.postimg.org/imynbhjo7/example.jpg');
background-size: 100% 100%;
width: 100%;
height: 100px;
min-width:900px;
position:absolute;
left:0;
top:0
}
#secondLayer {
background-image:url('http://s13.postimg.org/5o17i8wwn/example2.jpg');
background-size: 100% 100%;
width: 100%;
height: 100px;
min-width:900px;
position:absolute;
left:0;
top:0
}
#thirdLayer {
position:absolute;
top: 50px;
left: 50%;
}
When something in the menu is to highlight, and to get a match between the first layer gradient and the second layer gradient, I stretch both first and second layer over the entire width of the screen. Then I try to make the parts of the second layer that are not to highlight transparent. However, I fail doing so. Is there a way to achieve it, or should I take another approach?
e.g. I have tried following https://stackoverflow.com/a/8422890/1419386, however I cannot apply 1. and 3. suggestion, due to the gradient. 2. suggestion I don't believe I can apply, I want a sudden transparency at a point in the image and not some gradient into transparency.
(just splitting the gradient off from both layers does not work for me because it actually also difuses with the color beneath it (red or blue), so it is a little bit a simplified example).
There are 3 different posibilities that I can think of to solve your problem.
All of them are based on clipping instead of transparency, so the first thing that we need to do is to change the order of the divs:
HTML:
<div id="thirdLayer">hover me</div>
<div id="secondLayer"></div>
<div id="firstLayer"></div>
I have moved also the third layer in the front so that I can use the hover state without script, but this is not important.
The first posibility uses clip. Css:
#firstLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,red,red);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
width: 100%;
height: 100px;
min-width:900px;
position:absolute;
left:0;
top:0;
clip: rect(10px,0px,80px,0px);
-webkit-transition: all 2s;
}
#secondLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,blue,blue);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
width: 100%;
height: 100px;
min-width:900px;
position:absolute;
left:0;
top:0
}
#thirdLayer {
position:absolute;
top: 110px;
left: 50%;
}
#thirdLayer:hover ~ #firstLayer {
clip: rect(10px,800px,80px,400px);
}
Most of the CSS is standard stuff. I have replaced youyr images with gradients, so that the example does not depend on the availability of them. The key issue is using
clip: rect(10px,800px,80px,400px);
To show only the part of the div that you want. The main problem with this solution is that it is not posible to use percentages in that property, so it is of limited use if you want it to be flexible.
demo 1
The second posibility is to play with the background-size:
#firstLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,red,red);
background-size: 1000% 40%, 1000% 100%;
background-repeat: no-repeat;
backgrond-position: -10% 0%;
width: 10%;
height: 100px;
position:absolute;
left:-10%;
top:0;
-webkit-transition: all 3s;
transition: all 3s;
}
#secondLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,blue,blue);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
width: 100%;
height: 100px;
position:absolute;
left:0;
top:0
}
#thirdLayer {
position:absolute;
top: 110px;
left: 50%;
}
#thirdLayer:hover ~ #firstLayer {
left: 47%;
background-position: 47% 0%, 47% 0%;
}
demo 2
Notice that to compensate that the width of the background is now 10%, the background size is now 1000%, so the porportion is the same:
There can be slight offsets in rendering, due to the different calculus, but the system is quiet good.
The third posibility is to use a clipping mask (with limited browser support)
#firstLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,red,red);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
background-position: 0% 0%;
width: 100%;
height: 100px;
position:absolute;
left:0;
top:0px;
-webkit-transition: all 3s;
transition: all 3s;
}
#secondLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,blue,blue);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
width: 100%;
height: 100px;
position:absolute;
left:0;
top:0;
}
#thirdLayer {
position:absolute;
top: 110px;
left: 50%;
}
#firstLayer {
-webkit-mask-position: -15% 0px;
-webkit-mask-size: 84px 100%;
-webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, 1), rgba(0, 0, 0, 1));
-webkit-mask-repeat: no-repeat;
}
#thirdLayer:hover ~ #firstLayer {
-webkit-mask-position: 52% 0px;
}
We define a mask, and the only remaining issue is to set the position
demo3
Related
I am trying to add this animation to my background, but when going on mobile device, the background triples even when I set the background size cover, on pc version it works fine, only one background. Why is this happening?
.main {
background-image: url("~#/assets/main-bg.png");
background-position: center;
background-size: cover;
width: 100%;
height: 100vh;
overflow-y: scroll;
animation: shrink 5s infinite alternate;
box-shadow: inset 0 0 0 2000px rgba(0, 0, 0, 0.4);
}
#keyframes shrink {
0% {
background-size: 110%;
}
100% {
background-size: 100%;
}
}
You can keep the cover property if you use scale instead of changing background size. Obviously you don't want the whole of main to scale in and out - only the image - so put that as background on the before pseudo element, set it as cover and to transform between scale 1.1 and 1.
That way you get both effects and it's fully responsive.
.main {
width: 100%;
height: 100vh;
overflow-y: scroll;
position: relative;
}
.main::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
animation: shrink 5s infinite alternate;
background-image: url("https://picsum.photos/id/259/1024/768");
background-position: center;
background-size: cover;
box-shadow: inset 0 0 0 2000px rgba(0, 0, 0, 0.4);
}
#keyframes shrink {
0% {
transform: scale(1.1);;
}
100% {
transform: scale(1.0);
}
}
<div class="main"></div>
Add in this css property background-repeat: no-repeat;
This will stop the background image from appearing more than once.
Also, your keyframes changes the background size from cover to 100/110%. Over riding the property.
I am trying to set my HTML background in a way that it looks like it consists of two triangles but I cannot seem to get it to fully fit the page. How would I accomplish that and additionally be able to set a custom color for both?
Here is the code I am working with:
#container {
position: relative;
height: 800px;
width: 800px;
overflow: hidden;
background: grey;
margin-left: -0.4%;
margin-top: -0.4%;
}
#container:before {
content: '';
position: absolute;
left: 28%;
top: 28%;
width: 1200px;
height: 1200px;
background-color: rgb(255, 255, 255); /* fallback */
background-color: rgba(255, 255, 255, 0.5);
-webkit-transition: all 1s;
-moz-transition: all 1s;
transition: all 1s;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
transform: rotate(45deg);
}
<div id="container"></div>
I tried changing all the height and width to 100vh and 100vw but that did not seem to help and there is no option to get the colors changed. Any help would be appreciated!
You can do it with the background: linear-gradient():
html, body {margin: 0; width: 100vw; height: 100vh}
body {
background: -webkit-gradient(linear, left top, right bottom, color-stop(50%, Salmon), color-stop(50%, Khaki));
background: -webkit-linear-gradient(top left, Salmon 50%, Khaki 50%);
background: -o-linear-gradient(top left, Salmon 50%, Khaki 50%);
background: linear-gradient(to bottom right, Salmon 50%, Khaki 50%);
}
http://jsfiddle.net/Liamm12/kkt1kd34/
I hope this what are you looking to do
I just set up the body height:100%; and Width:100%; the page will take the full screen
We should add min-height: 100% to the container it will helps the body to be full screen
And finally I just added padding-bottom to container:after it will makes the design as triangles
html, body {
height: 100%;
width:100%;
margin: 0;
}
#container {
position: relative;
min-height: 100%;
overflow: hidden;
background-color: #645384;
}
#container:after {
content: '';
position: absolute;
padding-bottom: 141.42136%;
left: 30%;
width: 100%;
background-color: #f37638;
-webkit-transition: all 1s;
-moz-transition: all 1s;
transition: all 1s;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
transform: rotate(45deg);
}
<!doctype html>
<html>
<head>
<title></title>
</head>
<body>
<div id="container"></div>
</body>
</html>
In order to answer this question, I have used multiple techniques:
Create the aspect ratio box: This is necessary for second steps (since I need a square for this to work.
For more information, you can look through this: Aspect Ratio Boxed
I have used CSS border triangle in order to provide what you are requesting. Look for more detail here: CSS Triangle
So what I have done is, creating a square box, setting the border to make the arrow. I have also made the jsfiddle for you to look through.
https://jsfiddle.net/vqmjyjhw/
I have also add css variable on top to help you modify the box fast if you need to:
:root {
--width: 100%;
--halfWidth: 242px;
--topColor: red;
--bottomColor: blue;
}
With width variable, you can use %. But in order for the trick to work, halfWidth need to be in px. You can use some extra javascript to calculate exactly what is the width of your container to set halfWidth properly.
Currently working on a web design project for a client where I designed a multi-layered diagonal background. I solved a single diagonal with;
background-color: #dbebde;
background-image: -webkit-linear-gradient(120deg, #dbebde 50%, #f8f8f8 45%);
min-height: 400px;
However, as seen in the image below, I need to add a smaller diagonal on the left side.
Does anyone have an idea on how to solve this specific issue?
You can use a single HTML element, let's say a <div>, and use pseudo-elements, particularly ::before and ::after, to create those shapes, without writing additional HTML elements.
You would draw the red one first:
body {
margin: 0;
}
.fullBox {
position: relative;
height: 100vh;
}
.diagonalBox {
background: #FFF;
overflow: hidden;
}
.diagonalBox::before,
.diagonalBox::after {
content: '';
position: absolute;
width: 200%;
height: 200%;
left: 0;
}
.diagonalBox::before {
background: #D00;
top: 10%;
transform: rotate(30deg);
transform-origin: top left;
}
<div class="fullBox diagonalBox"></div>
And then add the light mint green one on top of that:
body {
margin: 0;
}
.fullBox {
position: relative;
height: 100vh;
}
.diagonalBox {
background: #FFF;
overflow: hidden;
}
.diagonalBox::before,
.diagonalBox::after {
content: '';
position: absolute;
width: 200%;
height: 200%;
left: 0;
}
.diagonalBox::before {
background: #D00;
top: 10%;
transform: rotate(30deg);
transform-origin: top left;
}
.diagonalBox::after {
background: #DFD;
top: 100%;
transform: rotate(-30deg);
transform-origin: bottom left;
}
<div class="fullBox diagonalBox"></div>
Keep in mind that your may need to adjust the dimensions and positions of the pseudo-elements.
I suggest you using 2 DIVs and give one of them a gradient with transparent color.
HTML :
<div class="outer">
<div class="inner"></div>
</div>
CSS:
.outer,.inner{
position:fixed;
top:0;
bottom:0;
left:0;
right:0;
}
.outer {
background-color: #dbebde;
background-image: -webkit-linear-gradient(50deg, red 70%, #f8f8f8 65%);
background-image: -moz-linear-gradient(50deg, red 70%, #f8f8f8 65%);
background-image: -o-linear-gradient(50deg, red 70%, #f8f8f8 65%);
background-image: -ms-linear-gradient(50deg, red 70%, #f8f8f8 65%);
}
.inner{
background-color: transparent;
background-image: -webkit-linear-gradient(120deg, #dbebde 60%, transparent 55%);
background-image: -moz-linear-gradient(120deg, #dbebde 60%, transparent 55%);
background-image: -o-linear-gradient(120deg, #dbebde 60%, transparent 55%);
background-image: -ms-linear-gradient(120deg, #dbebde 60%, transparent 55%);
}
You can see it in action:
https://codepen.io/FaridNaderi/pen/LLBVqw
Hope at least it helps you.
A little while back with some great help from SO I was able to create an effect where a mouse over causes the background to do an animated underline effect:
.box{
height:30px;
background-color : white;
}
.simulate_border {
position : relative;
height : 35px;
background: linear-gradient(to right, red 50%, grey 50%);
background-size: 200% 100%;
background-position:right bottom;
transition:all 500ms ease;
}
.simulate_border:hover{
background-position:left bottom;
}
Seen in action here: http://jsfiddle.net/9a4MW/
Now I wanted to see if I could do the same but above the content rather than below. But after much fiddling can't get the effect to be above rather than below?
TIA
Just position your .box differently: Jsfiddle.
.box {
height:30px;
background-color : white;
position: absolute;
width: 100%;
bottom: 0;
}
I'm trying to achieve a small animated intro to a website. Basically I want a centralised image to crop equally from top and bottom and then move up to the top of the screen.
So far I have the following: http://dk8.co/animation.html
This is using the following CSS:
#pic {
position:absolute;
top:0%;
width: 100%;
height: 200px;
left: 0px;
background:url(web/images/AM-title.jpg) no-repeat;
-moz-background-size:100% auto;
-webkit-background-size:100% auto;
-webkit-background-position:0% auto;
background-size:100% auto;
-o-background-size: 100% auto;
-webkit-animation-name: move;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in;
}
#-webkit-keyframes move {
0% {
top: 50%;
height: 400px;
}
50% {
top: 50%;
height: 300px;
}
}
However, the problem is that the "cropping" is occurring from just the bottom up rather than from top and bottom.
Is there any way of achieving an equal cropping effect on the top and the bottom?
The very simple solution is to assign 50% to the background-position property, or simply add 50% to the shorthand you have above:
background: url(web/images/AM-title.jpg) 50% 50% no-repeat;
Here is a working example: http://jsfiddle.net/sl1dr/L3sQW/
I wrote this five years ago for Prototype.js. You can scoop the code and see how it works.
Basically you move the position and background position of the element at the same time.