glasses
glasses

Reputation: 763

CSS Flexbox app layout issues

I have two separate codepens I have been working with, one with the main layout of the site, which works fine, and second is a component that I would like to add inside the left sidebar of the main layout.

The component works perfectly when inside of a container with a set height, it will shrink and stretch just the way I want if inside this type of parent div.

When I add the component into the main layout however it expands the left sidebar, breaking the perfect layout, I want the main layout to be the size of the current browser window, and the page to never scroll. is there a way to tell these sidebars ".layout-left" ".layout-stage" and ".layout-right" to not expand?

here are the codepens I was talking about:

Main Layout working: http://codepen.io/AlexBezuska/pen/KwOagy

Working sidebar: http://codepen.io/AlexBezuska/pen/ZYgWYp

Combined (not working): http://codepen.io/AlexBezuska/pen/LEwGJj

Layout CSS I am using:

body  {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
  width: 100%;
  margin: 0 auto;
}

.layout-middle{
  display: flex;
  flex: 1;
}

.layout-stage{
  flex: 1 0 320px;
  background: #ffc94e;
}

.layout-left, .layout-right{
  flex: 0 0 320px;
  background: #c9ea5d;
}

.layout-left{
  background: #85d6e4;
}

.layout-header{
  height: 100px;
  background: #92e4c9;
}

.layout-footer{
  height: 150px;
  background: #f7846a;
}

Upvotes: 6

Views: 431

Answers (4)

Denys Séguret
Denys Séguret

Reputation: 382304

Fixed CodePen (also works on Firefox)

I made 3 changes :

1) I've set the height of the body to the desired one :

body {
  height: 100vh;
}

2) I've given to the left container the right boxing model :

.layout-left, .layout-right{
  display: flex;
  flex-direction: column;
}

3) In order for the panels to not overflow on Firefox, I've added this :

div {
  min-height: 0;
}

This last setting is explained in this question by a developer who works on the flex model at Mozilla. Of course you'd better set it only on the relevant parent divs but this was simpler.

Upvotes: 1

Hidden Hobbes
Hidden Hobbes

Reputation: 14183

You currently have .layout-header, .layout-middle and .layout-footer set to fill the available vertical space, the issue is the length of content within .layout-left. There are a couple of ways you can stop the content of .layout-left spilling out of the container.

Overflow method

By adding .overflow-y: auto; to .layout-left you can ensure that a scrollbar is shown if its content is longer than its height, stopping the content from spilling out.

.panel {
  display: flex;
  flex-flow: column;
  /*padding: 1em;*/
  overflow: hidden;
  flex: 1;/*Add this*/
}
header {
  min-height: 32px;/*Add this*/
  height: 32px; /*must be 32px*/
  background: #c0c0c0;
}
footer {
  background: #cfcfcf;
  height: 32px;/*must be 32px*/
}
.select-list {
  /*flex: 1;*/
  overflow-y: scroll;
  /*max-height:16vh; Remove this*/
}
.select-list-item {
  background: white;
  border: 1px solid black;
  height: 32px;/*must be 32px*/
}

/*===============================================*/
body {
  display: flex;
  min-height: 100vh;
  max-height: 100vh;
  flex-direction: column;
  width: 100%;
  margin: 0 auto;
}
.layout-middle {
  display: flex;
  flex: 1;
}
.layout-stage {
  flex: 1 0 320px;
  background: #ffc94e;
}
.layout-left,
.layout-right {
  flex: 0 0 320px;
  background: #c9ea5d;
}
.layout-left {
  background: #85d6e4;
  overflow-y: auto;/*Add this*/
}
.layout-header {
  height: 100px;/*must be 100px*/
  background: #92e4c9;
}
.layout-footer {
  height: 150px;/*must be 150px*/
  background: #f7846a;
}
<div class="layout-header">
  <h1></h1>
</div>
<div class="layout-middle">
  <div class="layout-left">
    <!-- start content -->
    <div class="panel">
      <header>panel header</header>
      <div class="select-list" id="select-list">
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
      </div>
      <footer></footer>
    </div>
    <div class="panel">
      <header>Entities</header>
      <div class="select-list" id="select-list">
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
      </div>
      <footer></footer>
    </div>
    <div class="panel">
      <header>Entities</header>
      <div class="select-list" id="select-list">
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
      </div>
      <footer></footer>
    </div>
    <!-- end content -->
  </div>
  <main class="layout-stage">
    <h2>stage</h2>
  </main>
  <aside class="layout-right">
    <h2>right</h2>

  </aside>
</div>
<div class="layout-footer">
  <h2>Footer</h2>
</div>

http://codepen.io/anon/pen/gppPrp

Flex method

By adding display: flex; and flex-direction: column; to .layout-left you can get its contents to fit the available space.

.panel {
  display: flex;
  flex-flow: column;
  /*padding: 1em;*/
  overflow: hidden;
  flex: 1;/*Add this*/
}
header {
  min-height: 32px;/*Add this*/
  height: 32px;/*must be 32px*/
  background: #c0c0c0;
}
footer {
  background: #cfcfcf;
  height: 32px;/*must be 32px*/
}
.select-list {
  /*flex: 1;*/
  overflow-y: scroll;
  /*max-height:16vh; Remove this*/
}
.select-list-item {
  background: white;
  border: 1px solid black;
  height: 32px;/*must be 32px*/
}

/*===============================================*/

body {
  display: flex;
  min-height: 100vh;
  max-height: 100vh;
  flex-direction: column;
  width: 100%;
  margin: 0 auto;
}
.layout-middle {
  display: flex;
  flex: 1;
}
.layout-stage {
  flex: 1 0 320px;
  background: #ffc94e;
}
.layout-left,
.layout-right {
  flex: 0 0 320px;
  background: #c9ea5d;
}
.layout-left {
  background: #85d6e4;
  display: flex;/*Add this*/
  flex-direction: column;/*Add this*/
}
.layout-header {
  height: 100px;/*must be 100px*/
  background: #92e4c9;
}
.layout-footer {
  height: 150px;/*must be 150px*/
  background: #f7846a;
}
<div class="layout-header">
  <h1></h1>
</div>
<div class="layout-middle">
  <div class="layout-left">
    <!-- start content -->
    <div class="panel">
      <header>panel header</header>
      <div class="select-list" id="select-list">
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
      </div>
      <footer></footer>
    </div>
    <div class="panel">
      <header>Entities</header>
      <div class="select-list" id="select-list">
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
      </div>
      <footer></footer>
    </div>
    <div class="panel">
      <header>Entities</header>
      <div class="select-list" id="select-list">
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
        <div class="select-list-item selected">0: bg</div>
      </div>
      <footer></footer>
    </div>
    <!-- end content -->
  </div>
  <main class="layout-stage">
    <h2>stage</h2>
  </main>
  <aside class="layout-right">
    <h2>right</h2>

  </aside>
</div>
<div class="layout-footer">
  <h2>Footer</h2>
</div>

http://codepen.io/anon/pen/qddEoz

Upvotes: 1

Olivia O.
Olivia O.

Reputation: 11

.layout-left needs display: flex; and flex-flow: column; I also added a .container wrapper with display: flex; flex-direction: column; height: 100vh; and removed most properties from body. forked pen: http://codepen.io/oosby/pen/GJJqvP

Upvotes: 0

Marco Bernardini
Marco Bernardini

Reputation: 705

I want the main layout to be the size of the current browser window, and the page to never scroll.

In this case you need to set a max-height for the elements, too, at least for layout-middle.

Upvotes: 0

Related Questions