skip to Main Content

I am facing the problem with possibility to make only one area sticky in the CSS grid.

How it looks in the code:

.wrapper {
    display: grid;
    gap: 32;
    grid-template-columns: 1fr 478px;
    grid-template-areas:
        'Images Details'
        'Tabs Tabs';
}
.child1 {
    grid-area: Images;
}
.child2 {
    align-self: flex-start;
    grid-area: Details;
    position: sticky;
    top: 0;
}
.child3 {
    grid-area: Tabs;
}

So the section Images is much bigger (bigger height) than Details and what I want to achieve is to make Details sticky when scrolling down, but once I reach the bottom of Images it should stop moving down. For now area Images overlaps Tabs because it is sticky for the wrapper.

Any idea how to fix it?

Demo
https://stackblitz.com/edit/web-platform-a8znlr?file=styles.css

2

Answers


  1. I think this will fix your problem.

    .wrapper {
      display: grid;
      gap: 32px;
      grid-template-columns: 1fr 478px;
      grid-template-areas:
        'Images Details'
        'Tabs Tabs';
    }
    
    .child1 {
      grid-area: Images;
      display: flex;
      flex-wrap: wrap;
    }
    
    .child1 img {
      width: 350px;
      height: 200px;
      margin-bottom: 16px;
    }
    
    .child2 {
      grid-area: Details;
      position: sticky;
      top: 0;
    }
    
    .child3 {
      grid-area: Tabs;
    }
    
    .child2 img {
      width: 350px;
      height: 200px;
      margin-bottom: 16px;
    }
    Login or Signup to reply.
  2. The solution you request is not achievable with pure css and html, however you can do this with some javascript:

    window.addEventListener('DOMContentLoaded', () => {
      const images = document.querySelector('.child1');
      const details = document.querySelector('.child2');
    
      const handleScroll = () => {
        const imagesRect = images.getBoundingClientRect();
        const detailsHeight = details.offsetHeight;
    
        if (imagesRect.bottom - detailsHeight < 0) {
          details.style.position = 'absolute';
          details.style.top = `${images.offsetHeight - detailsHeight}px`;
        } else {
          details.style.position = 'sticky';
          details.style.top = '0';
        }
      };
    
      window.addEventListener('scroll', handleScroll);
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search