Z-index hierarchy issue with sibling elements - html

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.

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);
}

How to create a shifted border?

I am trying to achieve something like this:
I tried to use the pseudo-element :after like this:
.drink {
background-color: $drink-bg;
max-width: 50%;
position: relative;
&:after {
position: absolute;
top: -10px;
left: 10px;
right: 10px;
bottom: 10px;
border: 1px solid black;
}
img {
max-width: 100%;
}
}
It doesn't seem to work. Do I have to use 2 elements to achieve this? Or I can use just 1 element?
Because the image is responsive, the border should "follow" the width and height of the image element.
Your pseudo-element is actually styled correctly, and you are one small step away to get it to work: you just need to declare content: '' on it. Without a defined content property, the pseudo-element will not be rendered. This is because:
On elements, content always computes to normal. On ::before and ::after, if normal is specified, computes to none.
By extension of logic, an element without any content will not be rendered.
.drink {
background-color: $drink-bg;
max-width: 50%;
position: relative;
}
.drink:after {
content: ''; /* Added this rule */
position: absolute;
top: -10px;
left: 10px;
right: 10px;
bottom: 10px;
border: 1px solid black;
}
.drink img {
max-width: 100%;
}
<div class="drink">
<img src="http://via.placeholder.com/300x500" />
</div>

Overflow only certain elements

I've got a div with overflow: hidden, and a fairly large collection of elements inside it, which I want to be hidden while overflowing their parent. However I've also got two custom dropdowns, which I'd like to overlap and exit the div while open. Is there anyway to avoid the overflow hidden effect for specific elements? Here's an example. Say I want the blue square to go over the red border and overflow it's parent's bounds, but want the green one to remain cut off and hidden.
YOu can overlap/hidden of certain element with pseudo elements see this example.
html
<div class="red">
<div class="blue"></div>
<div class="green"></div>
</div>
css
* {
box-sizing: border-box;
}
.red {
position: relative;
border: 3px solid red;
width: 300px;
height: 300px;
}
.red:after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 70px;
background: rgb(243, 245, 246);
bottom: -70px;
z-index: -1;
}
.blue,.green {
position: absolute;
width: 70px;
height: 70px;
bottom: -40px;
}
.blue {
background-color: blue;
z-index: 1;
left: 40px;
}
.green {
background-color: green;
z-index: -1;
right: 40px;
}
here is fiddle

Why does a nested element of display table-cell show over a higher outer element?

I have an element that's nested inside an element of z-index: 0 that is underneath an element of z-index: 1. That parent element *does correctly** show under the other element. But, when I make the child element display: table-cell; z-index: 2 it jumps out of it's parent (on a vertical z axis) and above the higher, outer element! Why does this happen and how do I stop it?
Example: http://jsfiddle.net/5x8jy74o/
Example with parent as display: table, same issue: http://jsfiddle.net/5x8jy74o/1/
HTML:
<div class="hover">
HOVER IN HERE
</div>
<div class="container">
<div class="tc">
This should be under
</div>
</div>
CSS:
.hover
{
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100px;
background-color: #e8e8e8;
z-index: 1;
}
.container
{
position: relative;
top: 0px;
left: 0px;
width: 100px;
height: 100px;
background-color: red;
}
.tc
{
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 50px;
background-color: blue;
display: table-cell;
z-index: 2;
}
This is completely unrelated to the fact that the element has a display of table-cell.
It's because the .container element isn't actually establishing a stacking context. Despite the fact that the .container element is relatively positioned, it still has a default z-index of auto, not 0.
If you want to establish a stacking context, and prevent the child element from appearing above the previous sibling, add z-index: 0. Otherwise .tc will continue appearing above .hover because a z-index of 2 is clearly higher than 1.
Updated Example
.container {
position: relative;
z-index: 0;
/* .. */
}

Use Pseudo Element to Create Background Overlay

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);
}