totalnoob
totalnoob

Reputation: 2741

sticky position on css grid items

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

Answers (3)

honk31
honk31

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

JPC
JPC

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

James Trenda
James Trenda

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

Related Questions