Use Pseudo Element to Create Background Overlay - html

My goal is to have a div with any background, which then uses a pseudo element to create a transparent white overlay, thus "lightening" the background of the div. The "overlay" must be UNDER the contents of the div, though. So, in the following example:
<div class="container">
<div class="content">
<h1>Hello, World</h1>
</div>
</div>
.container {
background-color: red;
width: 500px;
height: 500px;
position: relative;
}
.content {
background-color: blue;
width: 250px;
}
.container::before {
content:"";
display: block;
height: 100%;
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 1;
background-color: rgba(255, 255, 255, .8);
}
The .content div should not be "underneath" the white overlay, aka .container::before.
I would prefer not having to use z-index on .content, but I can if that is the only solution.
End goal: The red should be covered while the text and blue are not.
JS fiddle: http://jsfiddle.net/1c5j9n4x/

If the pseudo element has a z-index, then you would need to position the .content element and add a z-index value to establish a stacking context.
Updated Example
.content {
background-color: blue;
width: 250px;
position: relative;
z-index: 1;
}
..you could also remove the z-index from the pseudo element and then merely position the .content element. In doing so, none of the elements need a z-index. The reason this works is because the :before pseudo element is essentially a previous sibling element. Thus, the succeeding .content element is positioned on top.
Alternative Example
.content {
background-color: blue;
width: 250px;
position: relative;
}
.container::before {
content:"";
display: block;
height: 100%;
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: rgba(255, 255, 255, .8);
}

Related

Rectangular Overlay Over Image With CSS [duplicate]

My goal is to have a div with any background, which then uses a pseudo element to create a transparent white overlay, thus "lightening" the background of the div. The "overlay" must be UNDER the contents of the div, though. So, in the following example:
<div class="container">
<div class="content">
<h1>Hello, World</h1>
</div>
</div>
.container {
background-color: red;
width: 500px;
height: 500px;
position: relative;
}
.content {
background-color: blue;
width: 250px;
}
.container::before {
content:"";
display: block;
height: 100%;
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 1;
background-color: rgba(255, 255, 255, .8);
}
The .content div should not be "underneath" the white overlay, aka .container::before.
I would prefer not having to use z-index on .content, but I can if that is the only solution.
End goal: The red should be covered while the text and blue are not.
JS fiddle: http://jsfiddle.net/1c5j9n4x/
If the pseudo element has a z-index, then you would need to position the .content element and add a z-index value to establish a stacking context.
Updated Example
.content {
background-color: blue;
width: 250px;
position: relative;
z-index: 1;
}
..you could also remove the z-index from the pseudo element and then merely position the .content element. In doing so, none of the elements need a z-index. The reason this works is because the :before pseudo element is essentially a previous sibling element. Thus, the succeeding .content element is positioned on top.
Alternative Example
.content {
background-color: blue;
width: 250px;
position: relative;
}
.container::before {
content:"";
display: block;
height: 100%;
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: rgba(255, 255, 255, .8);
}

Isolation with CSS Mix-Blend-Modes: how to prevent elements from blending with parent

I have tried this a lot of different ways, and cannot make it so that the .pink and .green divs blend with one another, but not the background color of the parent element, .wrapper.
.wrapper {
background-color: blue;
height: 100vh;
width: 100%;
isolation: isolate;
}
.pink {
background: hotpink;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
left: 10%;
mix-blend-mode: multiply;
}
.green {
background: limegreen;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
right: 10%;
mix-blend-mode: multiply;
}
<div class="wrapper">
<div class="pink"></div>
<div class="green"></div>
</div>
Or, see the fiddle: https://jsfiddle.net/grettynebraska/9dr6vspy/5/#&togetherjs=breFHFSfEd
My goal is simply to have a pink and green div that blend with eachother, and live atop a black background, with whom they do not blend.
I tried using absolute position, and sitting the pink/green divs and the wrapper next to one another, as siblings. However, all elements still blended.
I would consdier an extra wrapper where you set a z-index in order to create a staking context thus the element will no more blend with the blue element:
.wrapper {
background-color: blue;
height: 100vh;
width: 100%;
}
.wrapper > div {
position:absolute;
height: 100vh;
left:0;
right:0;
z-index:0;
top:0;
}
.pink {
background: hotpink;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
left: 10%;
mix-blend-mode: multiply;
}
.green {
background: limegreen;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
right: 10%;
mix-blend-mode: multiply;
}
<div class="wrapper">
<div>
<div class="pink"></div>
<div class="green"></div>
</div>
</div>
Everything in CSS that creates a stacking context must be considered an ‘isolated’ group. HTML elements themselves should not create groups.
An element that has blending applied, must blend with all the underlying content of the stacking context [CSS21] that that element belongs to. ref
So the main trick is to have the elements in a stacking context where the blue element doesn't belong. If the wrapper element is their direct parent element it won't be trivial to make them in different stacking context thus the need of an extra wrapper.
Isolation won't help you, because it will simply make the wrapper creating a stacking context, so it won't isolate the wrapper from its child but from all the elements outside. if you apply it to the extra wrapper it will work exactly like setting z-index or any other property that create a stacking context.
.wrapper {
background-color: blue;
height: 100vh;
width: 100%;
}
.wrapper > div {
position:absolute;
height: 100vh;
left:0;
right:0;
isolation:isolate;
top:0;
}
.pink {
background: hotpink;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
left: 10%;
mix-blend-mode: multiply;
}
.green {
background: limegreen;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
right: 10%;
mix-blend-mode: multiply;
}
<div class="wrapper">
<div>
<div class="pink"></div>
<div class="green"></div>
</div>
</div>

Z-index hierarchy issue with sibling elements

I have two sibling elements one under the other and a :before block, which should be under the first one, but above the second one:
http://jsfiddle.net/fh6rj09n/
HTML:
<div class="foo-1"></div>
<div class="foo-2">
Hover me
</div>
CSS:
div {
width: 300px;
height: 100px;
text-align: center;
position: relative;
}
.foo-1 {
background-color: #333;
}
.foo-1:before {
content: "";
position:absolute;
top: 50%; right: 0; bottom: 0; left: 0;
box-shadow: 0 0 50px red;
z-index: -1;
}
.foo-2 {
background-color: #555;
z-index: -2;
}
a {
line-height: 100px;
color: white;
}
The 2nd block also has an a element, which becomes unclickable, because overlapped by the :before block of the 1st element. What kind of z-index hierarchy should I apply to make the link clickable?
The main problem is that you're setting negative z-index to elements in the same context as the body tag. This makes the bodytag overlap the rest of nodes in the DOM.

Can an :after background-image be used to overlap the next element?

I have an image that I'd like to add as an :after element to a nav bar. The point being that the :after would cover the top portion of the next section (this is part of the design).
The :after is set as position: absolute with a top: 100% and it seems to disappear under the next element and z-index hasn't helped. When the top is set to anything less than 100%, you can see the :after element above the nav.
The markup:
<nav>Contents</nav>
<div>Contents</div>
The CSS:
nav {
width: 100%;
position: relative;
}
nav:after {
content: '';
width: 100%;
height: 66px;
background-image: url('image.png');
background-repeat: repeat-x;
position: absolute;
left: 0;
top: 100%;
}
No CSS for div yet...
Thanks in advance!
All you need is to set the z-index on the Content div to lower than that of the pseudo-element but note that the Content div must have a position setting on anything other than static...position:relative is usually sufficient.
Alternatively, just set the z-index of the pseudo-element to higher than that of the div (which will probably default to 1).
nav {
width: 100%;
position: relative;
height: 50px;
background: lightgreen;
}
nav:after {
content: '';
width: 100%;
height: 66px;
background: rgba(0, 0, 255, 0.5);
background-repeat: repeat-x;
position: absolute;
left: 0;
top: 100%;
z-index: 2;
}
div {
height: 260px;
position: relative;
background: rgba(255, 0, 0, 0.5);
}
<nav>Nav</nav>
<div>Contents</div>

How can I give a child element of one parent a higher z-index than another parent?

I have a sidebar split into two divs with an equal z-index.
The first div, top, has a link that shows another div, hover when you hover over it.
hover extends down into the bottom div, bottom, but since top and bottom have the same z-index, hover is covered by bottom.
No matter how high of a z-index I give bottom, that only affects how it is displayed within top. How can I get it to cover up bottom?
By the way, I also want to do the same thing to bottom, so there will be a bottom-hover that should cover up top.
So giving top and bottom different z-indexes isn't an option.
Here's a fiddle to demonstrate: http://jsfiddle.net/tsnuh7q1/
html:
<div class="top">top
<div class="hover">HOVER</div>
</div>
<div class="bottom">bottom<div>
css:
.top {
width: 200px;
height: 100px;
background: blue;
z-index: 3;
position: relative;
}
.hover {
z-index: 40;
width: 170px;
height: 300px;
position: absolute;
background: red;
left: 30px;
}
.bottom {
width: 200px;
height: 100px;
background: green;
z-index: 3;
position: relative;
}
The child z-index is always in the context of the parent.
Take
#A { z-index: 1; }
#B { z-index: 2; }
#A * { z-index: 1000; }
children of #A will always be under #B and it's children. The context of their z-index is a lower layer.
Came accross this question whilst searching for a solution for my own issue. Couldn't help but giving it a go.
If I understand correctly what you're trying to do why not do it like this?
http://jsfiddle.net/tsnuh7q1/2/
.top,
.bottom {
width: 100%;
height: 100px;
background: lightblue;
position: relative;
}
.bottom {
background: green;
}
.hover {
position: absolute;
top: 0;
left: 10%;
display: none;
width: 100px;
height: 150px;
background: red;
}
a:hover .hover {
display: block;
}
.bottom .hover {
top: initial;
left: initial;
right: 10%;
bottom: 0;
}
.top:hover,
.bottom:hover {
z-index: 1;
}
<div class="top">top
link<div class="hover">HOVER</div>
</div>
<div class="bottom">bottom
link<div class="hover">HOVER</div>
<div>