Phantom
Phantom

Reputation: 443

Position Sticky for Flexbox containers

I have built a horizontal flexbox layout with two items, each of which is a vertical flexbox.

Here is the current behaviour: As I am scrolling down, the red container scrolls normally. The blue container would stick, and then scroll along with the red at some point. This is a problem because the last few blue items would never be visible unless I scroll to the bottom of the page. But if I add a scroll event to add more red containers, then it would never happen.

Here is the intended behaviour: Both container will scroll normally, until the last blue box is visible. Then blue container would stop scrolling.

Questions:

  1. How do I achieve the intended behaviour?

  2. Currently, why did the scrolling for the blue container stop, then started again in order to align with the red container.

.wrapper{
    display: flex;
    justify-content: space-around;
    align-items: flex-start;
    border: 2px dashed rgba(114, 186, 94, 0.35);
    background: rgba(114, 186, 94, 0.05);
}

.item{
    display: flex;
    flex-direction: column;
}

div{
    min-width: 100px;
    min-height: 100px;
    margin: 10px;
}

.red{
    background-color: red;
}
.blue{
    background-color: blue;
}
.sticky{
    position: -webkit-sticky;
    position: sticky;
    top: 0;
}
<div class="wrapper">
        <div class="item">
            <div class="red">First</div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red">Last</div>
        </div>
        <div class="item sticky">
            <div class="blue">1</div>
            <div class="blue">2</div>
            <div class="blue">3</div>
            <div class="blue">4</div>
            <div class="blue">5</div>
            <div class="blue">6</div>
            <div class="blue">7</div>
            <div class="blue">8</div>
            <div class="blue">9</div>
            <div class="blue">10</div>
        </div>
        
    </div>

Upvotes: 2

Views: 412

Answers (1)

Temani Afif
Temani Afif

Reputation: 272734

To achieve what you want you need to have a negative value for top equal to the difference between the screen height and the element height.

I don't know if you will have a dynamic number of element but if I consider the fact that you will have a known number of blue element you can easily do it like below

.wrapper{
    display: flex;
    justify-content: space-around;
    align-items: flex-start;
    border: 2px dashed rgba(114, 186, 94, 0.35);
    background: rgba(114, 186, 94, 0.05);
}

.item{
    display: flex;
    flex-direction: column;
}

div{
    min-width: 100px;
    min-height: 100px;
    margin: 10px;
}

.red{
    background-color: red;
}
.blue{
    background-color: blue;
}
.sticky{
    position: sticky;
    top: calc(100vh - 10*(100px + 20px));
}
<div class="wrapper">
        <div class="item">
            <div class="red">First</div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red"></div>
            <div class="red">Last</div>
        </div>
        <div class="item sticky">
            <div class="blue">1</div>
            <div class="blue">2</div>
            <div class="blue">3</div>
            <div class="blue">4</div>
            <div class="blue">5</div>
            <div class="blue">6</div>
            <div class="blue">7</div>
            <div class="blue">8</div>
            <div class="blue">9</div>
            <div class="blue">10</div>
        </div>
        
    </div>

Upvotes: 1

Related Questions