Reputation: 703
I have a div called scrollable-container
that holds an empty header div, and its scrollable content. Then, I have a div floating-button
in front of the scrollable-container
.
<div id="wrapper">
<div id="scrollable-container">
<div id="header">I am Header</div>
<div id="scrollable-content">...</div>
</div>
<div id="floating-button">Float</div>
</div>
See fiddle below:
The float button currently overlaps both the header
and scrollable-content
, and is in front as expected because it has a higher z-index value than scrollable-container
. Also, scrollable-container
has its own stacking context, so its children should never be able to go in front of anything outside of the parent.
However, what is unexpected to me was that if I applied transform: rotate(90deg)
on the wrapper
div, then the div scrollable-content
now appears in front of floating-button
!
After transform rotate(90) applied
Could anyone please point out to me why is it displaying as such when rotated 90deg?
If you look at the 2nd fiddle, notice how the floating button is still in front of the div header
, which is expected, but only appears behind scrollable-content
.
EDIT:
My original question asked if there were known methods to fix the issue such that any divs that was originally and intentionally placed in front of the scrollable-content could still appear in front even after rotated 90deg.
F.Muller has kindly provided some workarounds in his answer.
However, I would like to know why the div with property overflow: auto
when inherits a transform: rotate(90deg)
could superseded its parent's stacking context and appear in front of everything else that's supposed to have a z-index order higher than it.
Some interesting notes:
wrapper
to be 80deg, it would still display the floating-button
in front correctly. Only when it reaches 90deg, it would disappear behind the scrollable-content
.overflow: hidden
at the wrapper
div can remedy the situation... but why is that so?Upvotes: 1
Views: 721
Reputation: 4062
It is probably ignoring the z-index
because the overlay-elements are not child-elements of the parent container: #scrollable-container
.
I kinda fixed it by setting the z-index
of #scrollable-container
to -1
. It seems to be working just fine in Firefox 83.0 (64-Bit)
and in Chrome V. 87.0.4280.67
too, after the adjustments.
The overflow: auto
property on the #scrollable-content
and/or overflow: hidden
property on the #wrapper
element will cause this visual behaviour in Chrome
.
Edit:
It might just help, if you apply position: relative
on the wrapper element. Relative containers will setup a layered stack. And we have 3 children now - the content and the two overlays. See: Alternative II.
Solution with negative z-index:
#wrapper {
height: 300px;
width: 400px;
position: absolute;
z-index: 0;
top: 0px;
left: 0px;
margin: 20px;
background-color: #E2DCDE;
overflow: hidden;
transform: rotate(90deg);
}
#scrollable-container {
width: 100%;
height: 100%;
position: relative;
z-index: -1;
}
#scrollable-content {
height: 100%;
overflow: auto;
}
#header {
height: 50px;
width: 100%;
text-align: center;
line-height: 50px;
}
#front-overlay1 {
width: 100%;
height: 100%;
background-color: blue;
position: absolute;
z-index: 2;
top: 0;
left: 0;
opacity: 0.5;
}
#front-overlay2 {
width: 50%;
height: 100%;
background-color: #B97375;
position: absolute;
z-index: 3;
top: 0;
left: 0;
opacity: 0.8;
}
.row1 {
height: 100px;
width: 100%;
background-color: #2D2D34;
color: white;
text-align: center;
line-height: 100px;
}
.row2 {
height: 100px;
width: 100%;
background-color: #686878;
color: white;
text-align: center;
line-height: 100px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="wrapper">
<div id="scrollable-container">
<div id="header">I am Header</div>
<div id="scrollable-content">
<div class="row1">Column 1</div>
<div class="row2">Column 2</div>
<div class="row1">Column 3</div>
<div class="row2">Column 4</div>
<div class="row1">Column 5</div>
<div class="row2">Column 6</div>
</div>
</div>
<div id="front-overlay1"></div>
<div id="front-overlay2"></div>
</div>
</body>
</html>
Alternative (removed an overflow property):
#wrapper {
height: 300px;
width: 400px;
position: absolute;
z-index: 0;
top: 0px;
left: 0px;
margin: 20px;
background-color: #E2DCDE;
overflow: hidden;
transform: rotate(90deg);
}
#scrollable-container {
width: 100%;
height: 100%;
position: relative;
z-index: 1;
}
#scrollable-content {
height: 100%;
/*overflow: auto;*/
}
#header {
height: 50px;
width: 100%;
text-align: center;
line-height: 50px;
}
#front-overlay1 {
width: 100%;
height: 100%;
background-color: blue;
position: absolute;
z-index: 2;
top: 0;
left: 0;
opacity: 0.5;
}
#front-overlay2 {
width: 50%;
height: 100%;
background-color: #B97375;
position: absolute;
z-index: 3;
top: 0;
left: 0;
opacity: 0.8;
}
.row1 {
height: 100px;
width: 100%;
background-color: #2D2D34;
color: white;
text-align: center;
line-height: 100px;
}
.row2 {
height: 100px;
width: 100%;
background-color: #686878;
color: white;
text-align: center;
line-height: 100px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="wrapper">
<div id="scrollable-container">
<div id="header">I am Header</div>
<div id="scrollable-content">
<div class="row1">Column 1</div>
<div class="row2">Column 2</div>
<div class="row1">Column 3</div>
<div class="row2">Column 4</div>
<div class="row1">Column 5</div>
<div class="row2">Column 6</div>
</div>
<div id="front-overlay1"></div>
<div id="front-overlay2"></div>
</div>
</div>
</body>
</html>
Alternative II (position: relative on the wrapper)
#wrapper {
position: relative;
height: 300px;
width: 400px;
margin: 20px;
background-color: #E2DCDE;
overflow: hidden;
transform: rotate(90deg);
z-index: 0;
}
#scrollable-container {
width: 100%;
height: 100%;
z-index: 1;
}
#header {
height: 50px;
width: 100%;
text-align: center;
line-height: 50px;
}
#scrollable-content {
width: 100%;
height: 100%;
overflow: hidden;
}
#front-overlay1, #front-overlay2 {
position: absolute;
top: 0;
left: 0;
}
#front-overlay1 {
width: 100%;
height: 100%;
background-color: blue;
opacity: 0.5;
z-index: 2;
}
#front-overlay2 {
width: 50%;
height: 100%;
background-color: #B97375;
opacity: 0.8;
z-index: 3;
}
.row1,
.row2 {
height: 100px;
width: 100%;
color: white;
text-align: center;
line-height: 100px;
}
.row1 {
background-color: #2D2D34;
}
.row2 {
background-color: #686878;
}
<div id="wrapper">
<div id="scrollable-container">
<div id="header">I am Header</div>
<div id="scrollable-content">
<div class="row1">Column 1</div>
<div class="row2">Column 2</div>
<div class="row1">Column 3</div>
<div class="row2">Column 4</div>
<div class="row1">Column 5</div>
<div class="row2">Column 6</div>
</div>
</div>
<div id="front-overlay1"></div>
<div id="front-overlay2"></div>
</div>
Upvotes: 1