Reputation: 169
I'm trying to make a sliding door sort of effect that reveals the main page of a site, but I'm having some problems with the z-index's of the images used. Basically, the z-index of the images needs to be higher than that of their parent containers in order to prevent part of the images from being cut off. It's kind of hard to explain, so please take a look at this codepen I threw together to demonstrate. The problem will be obvious, but it's just that the images should interlock, but part of one is being covered by the parent z-index of the other. The HTML and CSS are pretty straightforward, it's just a matter of getting the z-indices of the images higher than that of their parent containers which isn't working and I'm not sure why.
Edit: I should mention explicitly that the problem is that the left part of the bottom image in the symbol is being cutoff by the container of the left image. This would be solved by making the z-indices of the images higher than that of the containers, but I'm not sure why that's not working.
.curtain {
width: 100%;
height: 100vh;
overflow: hidden;
}
.right-panel {
width: 50%;
height: 100vh;
float: left;
z-index: 2;
position: relative;
background-color: #333;
transition: transform 5s;
}
.left-panel {
width: 50%;
height: 100vh;
float: left;
z-index: 3;
position: relative;
background-color: #333;
transition: transform 5s;
}
.content {
position: absolute;
width: 100%;
top: 50%;
background: 333;
z-index: 1;
text-align: center;
}
.left-img {
right: 0%;
margin-right: -12.5%;
width: 25%;
height: 50%;
z-index: 2;
position: absolute;
}
.right-img {
float: left;
width: 25%;
height: 50%;
margin-left: -12.5%;
position: absolute;
}
.curtain:hover .left-panel {
transform: translateX(-130%);
}
.curtain:hover .right-panel {
transform: translateX(130%);
}
<div class="curtain">
<div class="left-panel">
<img src="https://i.ibb.co/30TCGB3/logo-top.png" class="left-img">
</div>
<div class="right-panel">
<img src="https://i.ibb.co/GFCwpF0/logo-bottom.png" class="right-img">
</div>
<div class="content">
<p>main site stuff</p>
</div>
</div>
Upvotes: 0
Views: 203
Reputation: 11533
This approach keeps your floats, but adds additional markup to hold the image elements to stack above the background pieces.
The z-index
wasn't working for you because the stacking context of children elements. The other answer points this out.
.curtain {
width: 100%;
height: 100vh;
overflow: hidden;
z-index: 1;
position: relative;
}
.panel {
width: 50%;
height: 100vh;
z-index: 2;
position: absolute;
transition: transform 5s;
}
.left-panel,
.left-image-panel {
left: 0;
}
.right-panel,
.right-image-panel {
right: 0;
}
.left-panel,
.right-panel {
background-color: #333;
}
.left-image-panel,
.right-image-panel {
background-color: transparent;
z-index: 10;
}
.content {
position: absolute;
width: 100%;
top: 50%;
background: 333;
z-index: 1;
text-align: center;
}
.left-img {
right: 0%;
margin-right: -12.5%;
width: 25%;
height: 50%;
z-index: 2;
position: absolute;
}
.right-img {
float: left;
width: 25%;
height: 50%;
margin-left: -12.5%;
position: absolute;
}
.curtain:hover .left-image-panel,
.curtain:hover .left-panel {
transform: translateX(-130%);
}
.curtain:hover .right-image-panel,
.curtain:hover .right-panel {
transform: translateX(130%);
}
<div class="curtain">
<div class="left-image-panel panel">
<img src="https://i.ibb.co/30TCGB3/logo-top.png" class="left-img">
</div>
<div class="right-image-panel panel">
<img src="https://i.ibb.co/GFCwpF0/logo-bottom.png" class="right-img">
</div>
<div class="left-panel panel">
</div>
<div class="right-panel panel">
</div>
<div class="content">
<p>main site stuff</p>
</div>
</div>
Upvotes: 0
Reputation: 5156
Your .left-panel
has a higher z-index, so it overlaps the image inside .right-panel
. And z-index
creates a new stacking context, which prevents the images within from interlocking. Essentially, z-index is relative to the stacking context, not an absolute number.
I would recommend you structure your z-indices such that the panel backgrounds have the same z-index, and the images have a higher one (essentially creating 3 layers: content, cover-background, cover-images).
To do that, you need to reorganize your markup such that the background is a sibling of each panel's images, such that its z-index
does not affect the images'. You can do that with an actual element, but I will demonstrate using a ::before
:
body {
overflow: hidden;
}
.curtain {
width: 100vw;
height: 100vh;
overflow: hidden;
z-index: 0;
/* CSS variables to prevent duplication below */
--piece-width: 100px;
}
.curtain .content {
/* I used flex since I'm more comfortable with that, but you can use floats if you prefer. */
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
z-index: 0;
}
.curtain-panel {
display: flex;
align-items: center;
position: absolute;
width: 50%;
height: 100%;
transition: left, right;
transition-duration: 3s;
}
.curtain-panel.left {
left: 0;
justify-content: end;
}
.curtain-panel.right {
right: 0;
}
.curtain-panel::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
background-color: #333;
}
.curtain-piece {
width: var(--piece-width);
height: auto;
z-index: 2;
margin: calc(var(--piece-width) / -2);
}
.curtain:hover .left {
left: -100%;
}
.curtain:hover .right {
right: -100%;
}
<div class="curtain">
<div class="curtain-panel left">
<img src="https://i.ibb.co/30TCGB3/logo-top.png" class="curtain-piece">
</div>
<div class="curtain-panel right">
<img src="https://i.ibb.co/GFCwpF0/logo-bottom.png" class="curtain-piece">
</div>
<div class="content">
<p>main site stuff</p>
</div>
</div>
Additionally, you cannot use a transform
in the panels, since that would also create a stacking context. I highly recommend you read the page I linked to understand it better if you want.
Upvotes: 2