[css] Scrolling a flexbox with overflowing content

enter image description here

Here's the code I'm using to achieve the above layout:

_x000D_
_x000D_
.header {_x000D_
  height: 50px;_x000D_
}_x000D_
_x000D_
.body {_x000D_
  position: absolute;_x000D_
  top: 50px;_x000D_
  right: 0;_x000D_
  bottom: 0;_x000D_
  left: 0;_x000D_
  display: flex;_x000D_
}_x000D_
_x000D_
.sidebar {_x000D_
  width: 140px;_x000D_
}_x000D_
_x000D_
.main {_x000D_
  flex: 1;_x000D_
  display: flex;_x000D_
  flex-direction: column;_x000D_
}_x000D_
_x000D_
.content {_x000D_
  flex: 1;_x000D_
  display: flex;_x000D_
}_x000D_
_x000D_
.column {_x000D_
  padding: 20px;_x000D_
  border-right: 1px solid #999;_x000D_
}
_x000D_
<div class="header">Main header</div>_x000D_
<div class="body">_x000D_
  <div class="sidebar">Sidebar</div>_x000D_
_x000D_
  <div class="main">_x000D_
    <div class="page-header">Page Header. Content columns are below.</div>_x000D_
    <div class="content">_x000D_
      <div class="column">Column 1</div>_x000D_
      <div class="column">Column 1</div>_x000D_
      <div class="column">Column 1</div>_x000D_
    </div>_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

I omitted the code used for styling. You can see all of it in the pen.


The above works, but when the content area's content overflows, it makes the whole page scroll. I only want the content area itself to scroll, so I added overflow: auto to the content div.

The problem with this now is that the columns themselves don't extend beyond their parents height, so the borders are cut off there too.

Here's the pen showing the scrolling issue.

How can I set the content area to scroll independently, while still having its children extend beyond the content box's height?

This question is related to css layout multiple-columns flexbox

The answer is


A little late but this could help: http://webdesign.tutsplus.com/tutorials/how-to-make-responsive-scrollable-panels-with-flexbox--cms-23269

Basically you need to put html,body to height: 100%; and wrap all your content into a <div class="wrap"> <!-- content --> </div>

CSS:

html, body {
  height: 100%;
}

.wrap {
  height: 100vh;
  display: flex;
}

Worked for me. Hope it helps


Add this:

align-items: flex-start;

to the rule for .content {}. That fixes it in your pen for me, at least (in both Firefox & Chrome).

By default, .content has align-items: stretch, which makes it size all of its auto-height children to match its own height, per http://dev.w3.org/csswg/css-flexbox/#algo-stretch. In contrast, the value flex-start lets the children compute their own heights, and align themselves at its starting edge (and overflow, and trigger a scrollbar).


You can simply put overflow property to "auto"

_x000D_
_x000D_
     .contain{
          background-color: #999999;
          margin: 5px; 
          padding: 10px 5px;
          width: 20%;
          height: 20%;
          overflow: auto;
      }              
       
_x000D_
_x000D_
_x000D_

contain is one of my flex-item class name

result :

scroll bar seen properly


.list-wrap {
  width: 355px;
  height: 100%;
  position: relative;

  .list {
    position: absolute;
    top: 0;
    bottom: 0;
    overflow-y: auto;
    width: 100%;
  }
}

You can use a position: absolute inside a position: relative

https://codepen.io/Iquixe/pen/RwRzGrM


I just solved this problem very elegantly after a lot of trial and error.

Check out my blog post: http://geon.github.io/programming/2016/02/24/flexbox-full-page-web-app-layout

Basically, to make a flexbox cell scrollable, you have to make all its parents overflow: hidden;, or it will just ignore your overflow settings and make the parent larger instead.


The solution for this problem is just to add overflow: auto; to the .content for making the content wrapper scrollable.

Furthermore, there are circumstances occurring along with Flexbox wrapper and overflowed scrollable content like this codepen.

The solution is to add overflow: hidden (or auto); to the parent of the wrapper (set with overflow: auto;) around large contents.


Working with position:absolute; along with flex:

Position the flex item with position: relative. Then inside of it, add another <div> element with:

position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;

This extends the element to the boundaries of its relative-positioned parent, but does not allow to extend it. Inside, overflow: auto; will then work as expected.

  • the code snippet included in the answer - Click on enter image description here and then click on Full Page after running the snippet OR
  • Click here for the CODEPEN
  • The result: enter image description here

_x000D_
_x000D_
.all-0 {_x000D_
  top: 0;_x000D_
  bottom: 0;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
}_x000D_
p {_x000D_
  text-align: justify;_x000D_
}_x000D_
.bottom-0 {_x000D_
  bottom: 0;_x000D_
}_x000D_
.overflow-auto {_x000D_
  overflow: auto;_x000D_
}
_x000D_
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/>_x000D_
_x000D_
_x000D_
<div class="p-5 w-100">_x000D_
  <div class="row bg-dark m-0">_x000D_
    <div class="col-sm-9 p-0 d-flex flex-wrap">_x000D_
      <!-- LEFT-SIDE - ROW-1 -->_x000D_
      <div class="row m-0 p-0">_x000D_
        <!-- CARD 1 -->_x000D_
        <div class="col-md-8 p-0 d-flex">_x000D_
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">_x000D_
            <img class="img img-fluid" src="https://via.placeholder.com/700x250">_x000D_
            <h4>Heading 1</h4>_x000D_
            <p>_x000D_
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old..._x000D_
          </div>_x000D_
        </div>_x000D_
        <!-- CARD 2 -->_x000D_
        <div class="col-md-4 p-0 d-flex">_x000D_
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">_x000D_
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">_x000D_
            <h4>Heading 1</h4>_x000D_
            <p>_x000D_
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old..._x000D_
          </div>_x000D_
        </div>_x000D_
      </div>_x000D_
      <div class="row m-0">_x000D_
        <!-- CARD 3 -->_x000D_
        <div class="col-md-4 p-0 d-flex">_x000D_
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">_x000D_
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">_x000D_
            <h4>Heading 1</h4>_x000D_
            <p>_x000D_
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old..._x000D_
          </div>_x000D_
        </div>_x000D_
        <!-- CARD 4 -->_x000D_
        <div class="col-md-4 p-0 d-flex">_x000D_
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">_x000D_
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">_x000D_
            <h4>Heading 1</h4>_x000D_
            <p>_x000D_
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old..._x000D_
          </div>_x000D_
        </div>_x000D_
        <!-- CARD 5-->_x000D_
        <div class="col-md-4 p-0 d-flex">_x000D_
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">_x000D_
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">_x000D_
            <h4>Heading 1</h4>_x000D_
            <p>_x000D_
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old..._x000D_
          </div>_x000D_
        </div>_x000D_
      </div>_x000D_
    </div>_x000D_
    <div class="col-sm-3 p-0">_x000D_
      <div class="bg-white m-2 p-2 position-absolute all-0 d-flex flex-column">_x000D_
        <h4>Social Sidebar...</h4>_x000D_
        <hr />_x000D_
        <div class="d-flex overflow-auto">_x000D_
          <p>_x000D_
            Topping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart._x000D_
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart._x000D_
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart._x000D_
            Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream_x000D_
            chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate_x000D_
            bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva_x000D_
        </div>_x000D_
      </div>_x000D_
    </div>_x000D_
  </div>
_x000D_
_x000D_
_x000D_

Good Luck...


The following CSS changes in bold (plus a bunch of content in the columns to test scrolling) will work. See the result in this Pen.

.content { flex: 1; display: flex; height: 1px; }

.column { padding: 20px; border-right: 1px solid #999; overflow: auto; }

The trick seems to be that a scrollable panel needs to have a height literally set somewhere (in this case, via its parent), not just determined by flexbox. So even height: 1px works. The flex-grow:1 will still size the panel to fit properly.


One issue that I've come across is that to have a scrollbar a n element needs a height to be specified (and not as a %).

The trick is to nest another set of divs within each column, and set the column parent's display to flex with flex-direction: column.

<style>
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }

    body {
        overflow-y: hidden;
        overflow-x: hidden;
        color: white;
    }

    .base-container {
        display: flex;
        flex: 1;
        flex-direction: column;
        width: 100%;
        height: 100%;
        overflow-y: hidden;
        align-items: stretch;
    }

    .title {
        flex: 0 0 50px;
        color: black;
    }

    .container {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
    }

        .container .header {
            flex: 0 0 50px;
            background-color: red;
        }

        .container .body {
            flex: 1 1 auto;
            display: flex;
            flex-direction: row;
        }

            .container .body .left {
                display: flex;
                flex-direction: column;
                flex: 0 0 80px;
                background-color: blue;
            }
                .container .body .left .content,
                .container .body .main .content,
                .container .body .right .content {
                    flex: 1 1 auto;
                    overflow-y: auto;
                    height: 100px;
                }
                .container .body .main .content.noscrollbar {
                    overflow-y: hidden;
                }

            .container .body .main {
                display: flex;
                flex-direction: column;
                flex: 1 1 auto;
                background-color: green;
            }

            .container .body .right {
                display: flex;
                flex-direction: column;
                flex: 0 0 300px;
                background-color: yellow;
                color: black;
            }

    .test {
        margin: 5px 5px;
        border: 1px solid white;
        height: calc(100% - 10px);
    }
</style>

And here's the html:

<div class="base-container">
    <div class="title">
        Title
    </div>
    <div class="container">
        <div class="header">
            Header
        </div>
        <div class="body">
            <div class="left">
                <div class="content">
                    <ul>
                        <li>1</li>
                        <li>2</li>
                        <li>3</li>
                        <li>4</li>
                        <li>5</li>
                        <li>6</li>
                        <li>7</li>
                        <li>8</li>
                        <li>9</li>
                        <li>10</li>
                        <li>12</li>
                        <li>13</li>
                        <li>14</li>
                        <li>15</li>
                        <li>16</li>
                        <li>17</li>
                        <li>18</li>
                        <li>19</li>
                        <li>20</li>
                        <li>21</li>
                        <li>22</li>
                        <li>23</li>
                        <li>24</li>
                    </ul>
                </div>
            </div>
            <div class="main">
                <div class="content noscrollbar">
                    <div class="test">Test</div>
                </div>
            </div>
            <div class="right">
                <div class="content">
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>End</div>
                </div>
            </div>
        </div>
    </div>
</div>

https://jsfiddle.net/LiamFlavelle/czpjdfr4/


Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to layout

This view is not constrained What's the difference between align-content and align-items? CSS Flex Box Layout: full-width row and columns Fill remaining vertical space with CSS using display:flex What is setContentView(R.layout.main)? How to change line color in EditText Scrolling a flexbox with overflowing content UICollectionView - Horizontal scroll, horizontal layout? How to style a div to be a responsive square? 100% width Twitter Bootstrap 3 template

Examples related to multiple-columns

How to make div same height as parent (displayed as table-cell) Scrolling a flexbox with overflowing content How do I change Bootstrap 3 column order on mobile layout? Bootstrap 3 Multi-column within a single ul not floating properly Multiple input box excel VBA Unique Key constraints for multiple columns in Entity Framework Combine two or more columns in a dataframe into a new column with a new name Apply pandas function to column to create multiple new columns? mysqli_fetch_array while loop columns MySQL ORDER BY multiple column ASC and DESC

Examples related to flexbox

Force flex item to span full row width vuetify center items into v-flex Equal height rows in CSS Grid Layout display: flex not working on Internet Explorer Center the content inside a column in Bootstrap 4 Vertical Align Center in Bootstrap 4 How to use zIndex in react-native Bootstrap 4 align navbar items to the right Does 'position: absolute' conflict with Flexbox? Make flex items take content width, not width of parent container