Reputation: 449
I'm trying to build a layout with CSS Grid. I want the header element to be 'sticky'. That is, when the user scrolls, the header stays fixed to top of viewport and other content scrolls up and underneath header. I'd like to give this header a background image.
I've assigned a background image to the header, given it a position value of fixed and applied a z-index value of 999. Other elements below have been positioned and given lower z-index values.
My problem is that this setup doesn't work. I tried a few variations on the CSS but the background image either completely disappears or, on scroll, the header does not stay above other elements as they move up the screen.
What am I doing wrong? I browsed other questions in this forum and also on the web in general but can't find an answer.
Any suggestions much appreciated.
My code is shown below (including various changes to CSS - commented out in most cases).
body {
display: grid;
grid-template-areas: "header header header" "nav article ads" "footer footer footer";
grid-template-rows: 250px 900px 70px;
grid-template-columns: 20% 1fr 15%;
grid-row-gap: 10px;
grid-column-gap: 10px;
height: 100vh;
margin: 0;
}
header {
/* position:fixed;
z-index:999;*/
}
footer, article, nav, div {
padding: 1.2em;
background: gold;
}
#pageHeader {
grid-area: header;
padding: 1.2em;
background: url(https://placeimg.com/50/250/arch) left top repeat-x fixed;
}
#pageFooter {
grid-area: footer;
}
#mainArticle {
grid-area: article;
position: relative;
z-index: 9;
}
#mainNav {
grid-area: nav;
position: relative;
z-index: 8;
}
#siteAds {
grid-area: ads;
position: relative;
z-index: 7;
}
/* Stack the layout on small devices. */
@media all and (max-width: 575px) {
body {
grid-template-areas: "header" "article" "ads" "nav" "footer";
grid-template-rows: 80px 1fr 70px 1fr 70px;
grid-template-columns: 1fr;
}
}
<body>
<header id="pageHeader">Header</header>
<article id="mainArticle">Article</article>
<nav id="mainNav">Nav</nav>
<div id="siteAds">Ads</div>
<footer id="pageFooter">Footer</footer>
</body>
Upvotes: 0
Views: 2358
Reputation: 934
Use this Jsfiddle...
I have added some css styles and jQuery
CSS
#pageHeader.fixed {
position: fixed;
top:0;
left:0;
width: 100%;
z-index: 99;
}
jQuery
$(window).scroll(function(){
var sticky = $('#pageHeader'),
scroll = $(window).scrollTop();
if (scroll >= $('#pageHeader').height()){
sticky.addClass('fixed');
$('#pageHeader').addClass('fixed');
} else {
sticky.removeClass('fixed');
$('#pageHeader').removeClass('fixed');
}
});
Upvotes: 0
Reputation: 1453
Remove other elements z-index
. add position: fixed
on your header
and give it a width
and height
then also z-index
of 1
Element positioned absolute works kinda like layers. The DOM and z-index (x and y axis is 2d coords and z axis is for the stacking) tells it where to sit depending on where it is on the DOM.
Read through this for a detailed explination...I will most likely screw it up if I try explain any further.
Upvotes: 1
Reputation: 220
Your <header>
element needs to be placed outside of your grid. Currently, the grid encompasses everything, including the header, since it's on the body tag. Instead of using display: grid;
on the body, make a container within the body that has display: grid;
, and make the header live outside of that container. For example:
HTML:
<body>
<header>Header content!</header>
<div class="container">
<div class="mainNav"></div>
<div class="sidebar"></div>
<div class="siteAds"></div>
<!-- etc. -->
</div>
</body>
And the CSS:
body {
/* your normal body styles go here */
/* but display: grid; should no longer be here */
}
header {
position: fixed;
z-index: 10;
height: 100px;
}
.container {
display: grid;
margin-top: 100px; /* to offset the header's height */
/* and all the rest of your grid styles */
}
What's important to remember here is that the header must not be part of the grid layout.
Upvotes: 0