1

I'm trying to create 2 column full height design by using flexbox. When I add scrolling to whole middle part then I have a strange behavior. It seems that flex-grow/stretch doesn't grow/stretch other items if parent container has a scrollbar.

Here is my fiddle. Code also given below:

html, body {
    height: 100%;    
}
#container {
    display: flex;
    flex-direction: column;
    height: 100%;
    
    width: 50%;
    background-color: red;
}

#container header {
    background-color: gray;
}
#container section {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 0px;
}
#container footer {
    background-color: gray;
}
aside {
  width : 100px;
  background-color: blue;
}
article{
  width: 100%;
  display:flex;
  flex-direction: column;
}
article > div{
  flex: 1 1 auto;
}

#content {
  display:flex;   
}
<section id="container" >
<header id="header" >This is a header</header>
<section id="content">
  <aside>
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
    test<br />
  </aside>
  <article id="article" >
    <div>               
      This is the content that
      <br />
      With a lot of lines.
      <br />
      With a lot of lines.
      <br />
      This is the content that
      <br />
      With a lot of lines.
      <br />
      <br />
      This is the content that
      <br />
      With a lot of lines.
      <br />
      <br />
      This is the content that
      <br />
      With a lot of lines.
      <br />
    </div>
    <footer id="footer" >This is a page footer</footer>      
  </article>
</section>
<footer id="footer" >This is a footer</footer>
</section>

Basically i'm trying to cover 2 scenarios. It works fine if i don't need to scroll but once i have a scroll the items doesn't stretch correctly:

1. Main content 'smaller' than left

2. Main content 'bigger' than left

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Vi_Ros
  • 49
  • 5

1 Answers1

1

To make this layout work in latest Firefox & Chorme as of today (revising this answer from 2016), I made the following changes:

  1. Added margin: 0 to body to allow the container to flex to the viewport height.

  2. Wrap you the contents on #content element in another section and make it a column flexbox.

  3. Make the inner sectiona full-height flexbox and give min-height: max-content and flex: 1.

See demo below:

html,
body {
  height: 100%;
  margin: 0; /* ADDED */
}

#container {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 50%;
  background-color: red;
}

#container header {
  background-color: gray;
}

#container > section { /* ADDED > selector */
  display: flex; /* ADDED */
  flex-direction: column; /* ADDED */
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0px;
}

#container > section > section{ /* ADDED */
  display: flex;
  height: 100%;
  min-height: max-content; /* fixes chrome */
  flex: 1; /* fixes firefox */
}

#container footer {
  background-color: gray;
}

aside {
  width: 100px;
  background-color: blue;
  min-height: content;
}

article {
  width: 100%;
  display: flex;
  flex-direction: column;
}

article>div {
  flex: 1 1 auto;
}
<section id="container">
  <header id="header">This is a header</header>
  <section id="content">
    <section>
      <aside>
        test<br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br /> test
        <br />
      </aside>
      <article id="article">
        <div>
          This is the content that
          <br /> With a lot of lines.
          <br /> With a lot of lines.
          <br /> This is the content that
          <br /> With a lot of lines.
          <br />
          <br /> This is the content that
          <br /> With a lot of lines.
          <br />
          <br /> This is the content that
          <br /> With a lot of lines.
          <br />
        </div>
        <footer id="footer">This is a page footer</footer>
      </article>
    </section>
  </section>
  <footer id="footer">This is a footer</footer>
</section>

The above solution is hacky at best and shows us why a flexbox is weak in 2D layouts. The answer is it is just not designed for it. But CSS Grids are - see how easily everything falls into place:

  1. Make #container a full viewport high grid element.

  2. Make the middle section a grid container with grid-template-columns: 100px 1fr along with overflow property and you are almost done.

See demo below:

body {
  margin: 0;
}

#container {
  display: grid;
  width: 50%;
  height: 100vh;
  background-color: red;
}

header, footer {
  background-color: gray;
}

#container section {
  display: grid;
  grid-template-columns: 100px 1fr;
  overflow-y: auto;
}

aside {
  background-color: blue;
}

article {
  display: flex;
  flex-direction: column;
}

article > div {
  flex: 1 1 auto;
}
<section id="container">
  <header id="header">This is a header</header>
  <section id="content">
    <aside>
      test<br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br /> test
      <br />
    </aside>
    <article id="article">
      <div>
        This is the content that
        <br /> With a lot of lines.
        <br /> With a lot of lines.
        <br /> This is the content that
        <br /> With a lot of lines.
        <br />
        <br /> This is the content that
        <br /> With a lot of lines.
        <br />
        <br /> This is the content that
        <br /> With a lot of lines.
        <br />
      </div>
      <footer id="footer">This is a page footer</footer>
    </article>
  </section>
  <footer id="footer">This is a footer</footer>
</section>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
  • It doesn't work. If i remove height from container then i have one big scroll. I want add scroll only to the middle part and keep header and the common footer statick – Vi_Ros Sep 13 '16 at 12:52
  • 1
    @Vi_Ros have edited the answer... please check and let me know if this is what you needed. Thanks! – kukkuz Sep 15 '16 at 10:45
  • Now i have 2 separate scrollbars for left and right parts. But i'm trying to reach one scrollbar for both blocks. I've attached the image what i'm trying to fix. – Vi_Ros Sep 15 '16 at 18:04
  • @Vi_Ros have edited the answer... Check it out now if it works and let me know... :) – kukkuz Sep 16 '16 at 02:12
  • Now it works exactly as in my example. Please try your changes yourself and try to scroll down. – Vi_Ros Sep 16 '16 at 18:04
  • Well, it works for me in chrome... could you please check? – kukkuz Sep 16 '16 at 18:08
  • It doesn't work for me even in chrome. Try run your code snippet and scroll down you will see exactly the same behavior that i'm trying to fix. see screenshot in description – Vi_Ros Sep 20 '16 at 12:49
  • @Vi_Ros sorry there... I had checked in my desktop chrome and it was working... just checked in firefox and chrome in my office system (which had latest chrome) and was not working! Will look for a solution later and let you know... – kukkuz Sep 20 '16 at 15:18
  • @Vi_Ros well, I tried... I don't think there is a solution for this with pure CSS using flexbox without using the less supported `min-content` property... :( I'll update here if I get any more ideas.... – kukkuz Sep 20 '16 at 17:21
  • Yesterday i played with min-content and it perfectly does what i need. But min-content not supported in many browsers, so i need to find an alternative solution. – Vi_Ros Sep 21 '16 at 16:23