guy
guy

Reputation: 112

How can I create independently scrollable columns with Bootstrap 4?

I'm trying to get some fixed-height content at the top, with 2 columns below that are separately scrollable. I want them to take up whatever screen-height is available, so I can't use fixed height or max-height.

I'm using Bootstrap 4.5 so my markup looks like:

<body>

    <div class="container">

        <div class="row">
            <div class="col-12">
                <h1>h1</h1>
                ...main nav...
            </div>
        </div>

        <div class="row">
            <div class="col-7">
                ...crumbtrail...
            </div>
        </div>

        <div class="row">
            <div id="col-left" class="col-7">
                ...left-content...
            </div>

            <div id="col-right" class="col-5">
                ...right-content...
            </div>
        </div>

    </div>

</body>

It's those columns col-left and col-right that I want to scroll independently. I've tried 2 ways with flexbox and in both cases...nothing. No scrollbars. No visible difference at all.

Clearly I'm missing some basic bit of understanding here.

I'm not hung up on a flexbox solution. Some other CSS solution would be fine, or even JS if necessary.


Way 1: flexbox on the top-level container

The idea is to make all the content flexible, but prevent the two header rows from shrinking. I'm going to do this all with Bootstrap 4 classes, so no flex-basis. But that's automatic by default which is what I want. I think.

Here's how I thought about it:

And as I said above, nothing happens.

<body>

    <div class="container d-flex flex-column">

        <div class="row flex-grow-0 flex-shrink-0">
            <div class="col-12">
                <h1>h1</h1>
                ...main nav...
            </div>
        </div>

        <div class="row flex-grow-0 flex-shrink-0">
            <div class="col-7">
                ...crumbtrail...
            </div>
        </div>

        <div id="col-left" class="row flex-grow-0 flex-shrink-1">
            <div id="col-left" class="col-7 flex-grow-0 flex-shrink-1">
                ...left-content...
            </div>

            <div id="col-right" class="col-5 flex-grow-0 flex-shrink-1">
                ...right-content...
            </div>
        </div>

    </div>

</body>

Way 2: flexbox only on the row containing the two columns

Maybe flexbox on everything is overkill and that's messing things up? Let's try to be more focused.

Now I want my scrollbars on the cross-axis. align-stretch will stretch them on the cross-axis, but there's no align-shrink?

And that's where I get stuck.

<body>

    <div class="container">

        <div class="row">
            <div class="col-12">
                <h1>h1</h1>
                ...main nav...
            </div>
        </div>

        <div class="row">
            <div class="col-7">
                ...crumbtrail...
            </div>
        </div>

        <div class="row d-flex flex-row">
            <div id="col-left" class="col-7 flex-grow-0 flex-shrink-0">
                ...left-content...
            </div>

            <div id="col-right" class="col-5 flex-grow-0 flex-shrink-0">
                ...right-content...
            </div>
        </div>

    </div>

</body>

Upvotes: 1

Views: 3947

Answers (2)

guy
guy

Reputation: 112

Very simple solution. Flexbox is unnecessary. The columns need some CSS that I don't think is available as a Bootstrap utility class, so it involves a small amount of custom CSS.

Markup:

<body>
    <div class="container">

        <div class="row">
            <div class="col-12">
                ...main nav...
            </div>
        </div>

    <div class="row">
        <div class="col-7">
                ...crumbtrail...
        </div>
    </div>

    <div class="row">
        <div id="col-left" class="col-7">
                ...left-content...
        </div>

        <div id="col-right" class="col-5">
                ...right-content...
        </div>
    </div>

    </div>
</body>

CSS:

div#col-left, div#col-right {
    max-height: 100vh;          /* not available in Bootstrap */
    overflow-y: scroll;
}

This gives me the two independently scrollable columns within a page that is itself scrollable. They don't lose any available height to the header material or when I add footer material.

Upvotes: 2

Carol Skelly
Carol Skelly

Reputation: 362780

If I understand your question, the issue is a matter of height and overflow...

<div class="container d-flex flex-column vh-100 mh-100 overflow-hidden">
    <div class="row flex-shrink-1">
        <div class="col-12">
            <h1>h1</h1> ...main nav...
        </div>
    </div>
    <div class="row flex-shrink-1">
        <div class="col-7"> ...crumbtrail... </div>
    </div>
    <div class="row flex-grow-1 overflow-hidden">
        <div id="col-left" class="col-7 mh-100 overflow-auto"> 
          ...left-content...
        </div>
        <div id="col-right" class="col-5 mh-100 overflow-auto">
          ...right-content...
        </div>
    </div>
</div>

https://codeply.com/p/B3qD9n4Vyy

Upvotes: 1

Related Questions