Reputation: 943
it's been a while! I am currently trying to solve a problem and I was hoping somebody could help me out. I have a fixed sidebar and a header. Both cast dropshadow. However, I don't want the header to cast shadow on the sidebar (I want them to be on the same level). At the same time, header contains drop-downs and these need to hover over everything. Since it's rather complex, I've created a jsfiddle.
I've been forced to paste the code here as well for some reason (SO input validation).
<div class="layout">
<div class="header z-depth-2">
<div class="dropdown-toogle">
<div class="dropdown-menu">
</div>
</div>
</div>
<div class="page-wrapper">
<div class="sidebar z-depth-2">
</div>
<div class="content">
</div>
</div>
</div>
And css
.layout {
width: 100%;
height: 100%;
position: relative;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 70px;
background-color: blue;
z-index: 101;
}
.sidebar {
position: fixed;
top: 70px;
left: 0;
width: 200px;
background-color: green;
bottom: 0;
z-index:101;
}
.content {
padding-left: 200px;
width: 100%;
height: 100%;
}
.page-wrapper {
padding-top: 70px;
height: 100%;
}
.dropdown-toogle {
margin-right: 100px;
float: right;
position: relative;
height: 100%;
width: 50px;
background-color: yellow;
}
.dropdown-menu {
position: absolute;
top: 100%;
right: 0;
width: 400px;
height: 200px;
background-color: grey;
z-index:1000;
}
.z-depth-2 {
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
}
Notice how when you change view-port width, drop-down slides behind sidebar even when it's z-index is greater.
If I increase z-index of header, it starts casting shadow on the sidebar (drop-down starts working) which I want to avoid. I've been playing with different combination but was unable to sort it out properly.
Hope I managed to make it clear, help much appreciated!
Upvotes: 1
Views: 1584
Reputation: 943
First of all, big thanks goes to Don, his approach is totally valid, clever and possibly even better than what I used. However I figured I'll post my final solution as well as somebody might value having 2 approaches. All I did is I've added a "fake" gradient absolutely positioned bellow the header and to the right of sidebar. The reason why I've done so is basically I used technologies that I know and can rely on. I didn't like the overflow auto on the content as well. Anyways, this is it:
https://jsfiddle.net/79gykeu3/11/
<div class="layout">
<div class="header">
<div class="header__shadow">
</div>
<div class="dropdown-toogle">
<div class="dropdown-menu">
</div>
</div>
</div>
<div class="page-wrapper">
<div class="sidebar">
<div class="sidebar__shadow">
</div>
</div>
<div class="content">
</div>
</div>
</div>
Css
.layout {
width: 100 %;
height: 100 %;
position: relative;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 70px;
background - color: blue;
z - index: 103;
}
.sidebar {
position: fixed;
top: 70px;
left: 0;
width: 200px;
background - color: green;
bottom: 0;
z - index:101;
}
.content {
padding - left: 200px;
height: 8000px;
}
.page - wrapper {
padding - top: 70px;
height: 100 %;
}
.dropdown - toogle {
margin - right: 100px;
float: right;
position: relative;
height: 100 %;
width: 50px;
background - color: yellow;
}
.dropdown - menu {
position: absolute;
top: 100 %;
right: 0;
width: 400px;
height: 200px;
background - color: grey;
z - index:1000;
}
.header__shadow {
position: absolute;
height: 7px;
left: 200px;
right: 0;
top: 100 %;
background: linear - gradient(to bottom, rgba(0, 0, 0, 0.35) 0%,rgba(0, 0, 0, 0) 100%);
}
.sidebar__shadow {
position: absolute;
left: 100 %;
top: 0;
bottom: 0;
width: 7px;
background: linear - gradient(to right, rgba(0, 0, 0, 0.35) 0%,rgba(0, 0, 0, 0) 100%);
}
Upvotes: 0
Reputation: 4157
With your current layout this isn't possible. Since the header is set to a z-index behind the sidebar essentially any child of the header will also be behind the sidebar. (Read more on stacking contexts)
In order to solve this issue what you can do is use an inset box-shadow
on the content pane. This will make it so there is a shadow as if it's being cast by the header and sidebar but it's really the container casting it on itself. This way you don't need to worry about the header casting onto the sidebar and the sidebar can safely sit "behind" the header. With this you don't need to fiddle with z-index at all (though I didn't remove them in case it's needed for other things on the page).
In order to get this to work properly I had to change the padding
you were using to position the content element with margin
but honestly this is a better property to use for adding space around an element. I recommend you also read up a bit on when to use padding
vs margin
.
https://jsfiddle.net/79gykeu3/6/
HTML
<div class="layout">
<div class="header z-depth-2">
<div class="dropdown-toogle">
<div class="dropdown-menu">
</div>
</div>
</div>
<div class="page-wrapper">
<div class="sidebar z-depth-2">
</div>
<div class="content">
</div>
</div>
</div>
CSS
The thing to note is the .content
class now has the box-shadow
html {
height: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
}
.layout {
width: 100%;
height: 100%;
position: relative;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 70px;
background-color: blue;
z-index: 103;
}
.sidebar {
position: fixed;
top: 70px;
left: 0;
width: 200px;
background-color: green;
bottom: 0;
z-index:101;
}
.content {
margin-left: 200px;
width: 100%;
height: 100%;
box-shadow: inset 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
}
.page-wrapper {
margin-top: 70px;
height: 100%;
}
.dropdown-toogle {
margin-right: 100px;
float: right;
position: relative;
height: 100%;
width: 50px;
background-color: yellow;
}
.dropdown-menu {
position: absolute;
top: 100%;
right: 0;
width: 70%;
height: 200px;
background-color: grey;
z-index:1000;
}
.z-depth-2 {
}
Upvotes: 2