Reputation: 2741
I've looked at other examples of this on here but can't find one that makes this work. I want the sidebar (section) to be sticky while the page scrolls. the position: sticky works if I put it on the nav, so my browser def supports it.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
position: sticky;
top: 0;
left: 0;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
<main>
<nav></nav>
<section>
hi
</section>
<article>
<p>hi</p>
</article>
</main>
Upvotes: 63
Views: 67282
Reputation: 4347
the problem you are facing here is, that your section block consumes the full height. so it won't stick, since it is too large to do so. you would need to put a child element inside your section and give that your sticky attributes, to make it work. based on your example, i simply wrapped your 'hi' inside a div.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
min-height: 1000px;
}
nav {
background: blue;
height: 100%;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
}
section div {
position: sticky;
top: 0;
}
article {
background: yellow;
grid-column: 2 / 4;
}
<main>
<nav></nav>
<section>
<div>
<p>one</p>
</div>
</section>
<article>
<p>two</p>
</article>
</main>
EDIT: and here is the reason for the problem: elements with display: grid
have a default attribute for align-items
to stretch
, meaning all children have the same height. you can avoid this by setting align-items: start;
following is another example without the additional div.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
min-height: 1000px;
align-items: start;
}
nav {
background: blue;
height: 100%;
grid-column: 1 / 4;
}
section {
position: sticky;
top: 0;
background: grey;
grid-column: 1 / 2;
grid-row: 2;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
<main>
<nav></nav>
<section>
<p>one</p>
</section>
<article>
<p>two</p>
</article>
</main>
Upvotes: 49
Reputation: 1
Update with complete code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
top: 0;
left: 0;
}
.fixed-section {
position: fixed;
z-index: 1;
overflow-x: hidden;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
</style>
</head>
<body>
<main>
<nav></nav>
<section>
<div class='fixed-section'>
<a href="#">Hi 1</a>
<div>
</section>
<article>
<p>hi</p>
</article>
</main>
</body>
</html>
Upvotes: 0
Reputation: 1277
You need to use align-self: start
on the thing you want to be sticky
.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
background: grey;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
position: sticky;
top: 0;
left: 0;
align-self: start;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
<main>
<nav></nav>
<section>
hi
</section>
<article>
<p>hi</p>
</article>
</main>
Upvotes: 82