Flexbox layout structure overflow

Viewed 21

I am trying to create a flexbox layout using the following HTML and CSS styling. I would like the header and footer to be always visible as they are right now and also the main content to have the same size always.

As I have it right now, the main content is displayed correctly, but the side divs are being scrolled too when I scroll the main content. I would like to scroll only inside the main content div (orange one), ocuppying the whole height (even if it doesn't have enough characters to fill it), I don't want to scroll outside the main content div.

In other words, I would like to scroll only tha main content div (orange one) without the header, sidenavs and footer to be scrolled too.

body {
    margin: 0;
    padding: 0;
}

.flex-container {
    display: flex;
    flex-direction: column;
    height: 100vh;
    background-color: lightblue;
}

header {
    background-color: lightcoral;
    width: 100%;
    align-self: flex-start;
}

main {
    background-color: lightcyan;
    width: 100%;
    flex: 1 1 auto;
    overflow-y: auto;
}

footer {
    background-color: lightgoldenrodyellow;
    width: 100%;
    align-self: flex-end;
}

.flex-column-container {
    display: flex;
    align-items: flex-start;
}

.col1 {
    flex-grow: 1;
    background-color: lightgray;
}

.col2 {
    flex-grow: 4;
    background-color: lightgreen;
    padding: 20px;
}

.col3 {
    flex-grow: 1;
    background-color: lightpink;
}

.content {
    background-color: lightsalmon;
    min-height: 100%;
    padding: 20px;
    overflow-y: auto;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flexbox Layout</title>
    <link rel="stylesheet" href="styles.css">
</head>

<body>
    <div class="flex-container">
        <header>This is a header</header>
        <main>
            This is the main content
            <div class="flex-column-container">
                <div class="col1">
                    Left sidenav
                </div>
                <div class="col2">
                    Main
                    <div class="content">
                        Main content div.
                        <br>
                        I want this div to occupy the remaining height
                        without expanding the flexbox layout. I would
                        like the div to have an overflow when the content
                        is bigger than the layout space available.
                        I don't want the sidenavs to be scrolled too as they
                        scroll right now.
                        <br><br><br><br><br><br><br><br><br><br><br><br><br>
                        <br><br><br><br><br><br><br><br><br><br><br><br><br>
                        <br><br><br><br><br><br><br><br><br><br><br><br><br>
                        <br><br><br><br><br><br><br><br><br><br><br><br><br>
                        End of this section.
                    </div>
                </div>
                <div class="col3">
                    Right sidenav
                </div>
            </div>
        </main>
        <footer>This is the footer</footer>
    </div>
</body>

</html>

1 Answers

You can set position: sticky on your side navs to give the appearance of the main content scrolling.

I added comments to the CSS to show what I changed.

Another helpful link from CSS Tricks

body {
    margin: 0;
    padding: 0;
}

.flex-container {
    display: flex;
    flex-direction: column;
    height: 100vh;
    background-color: lightblue;
}

header {
    background-color: lightcoral;
    width: 100%;
    align-self: flex-start;
}

main {
    background-color: lightcyan;
    width: 100%;
    flex: 1 1 auto;
    overflow-y: auto;
}

footer {
    background-color: lightgoldenrodyellow;
    width: 100%;
    align-self: flex-end;
}

.flex-column-container {
    display: flex;
    align-items: flex-start;
    /* added to make sure sticky elements have a parent position */
    position: relative;
}

.col1 {
    flex-grow: 1;
    background-color: lightgray;
    /* add sticky and top to stop them from scrolling */
    position: sticky;
    top: 0;
}

.col2 {
    flex-grow: 4;
    background-color: lightgreen;
    padding: 20px;
}

.col3 {
    flex-grow: 1;
    background-color: lightpink;
    /* add sticky and top to stop them from scrolling */
    position: sticky;
    top: 0;
}

.content {
    background-color: lightsalmon;
    min-height: 100%;
    padding: 20px;
    overflow-y: auto;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flexbox Layout</title>
    <link rel="stylesheet" href="styles.css">
</head>

<body>
    <div class="flex-container">
        <header>This is a header</header>
        <main>
            This is the main content
            <div class="flex-column-container">
                <div class="col1">
                    Left sidenav
                </div>
                <div class="col2">
                    Main
                    <div class="content">
                        Main content div.
                        <br>
                        I want this div to occupy the remaining height
                        without expanding the flexbox layout. I would
                        like the div to have an overflow when the content
                        is bigger than the layout space available.
                        I don't want the sidenavs to be scrolled too as they
                        scroll right now.
                        <br><br><br><br><br><br><br><br><br><br><br><br><br>
                        <br><br><br><br><br><br><br><br><br><br><br><br><br>
                        <br><br><br><br><br><br><br><br><br><br><br><br><br>
                        <br><br><br><br><br><br><br><br><br><br><br><br><br>
                        End of this section.
                    </div>
                </div>
                <div class="col3">
                    Right sidenav
                </div>
            </div>
        </main>
        <footer>This is the footer</footer>
    </div>
</body>

</html>

Related