Stretch columns in two columns layout with shared header using flexbox - html

I'm using flexbox to create a two-columns layout with a header row.
* {
box-sizing: border-box;
position: relative;
}
.container {
border: 2px solid gray;
display: flex;
flex-wrap: wrap;
height: 300px;
}
.header {
flex-basis: 100%;
border: 2px solid magenta;
height: 50px;
line-height: 50px;
text-align: center;
}
.column1 {
flex-basis: 150px;
/* height: calc(100% - 50px); */
border: 2px solid green;
}
.column2 {
/* height: calc(100% - 70px); */
flex: 1;
border: 2px solid orange;
}
<div class='container'>
<div class='header'>it's a header</div>
<div class='column1'>column 1</div>
<div class='column2'>column 2</div>
</div>
Feel free to see the full example here.
As you can see in the example there is a gap between columns and header. My aim is to stretch columns vertically to fill whole empty space in the container.
I can achieve it by setting height property like calc(100% - <header-height>). Is it the correct way?
I just tried to use "flex" style and set align-items: stretch to the container and align-self: stretch to columns but without success. Did I probably miss something trying to implement it this way?

I think specifying flex-direction as column is appropriate in this case.
The second row is itself a flex element with the flex-direction: row. You can fill the rest of the remaining space using flex: 1, which is equivalent to flex-grow: 1.
* {
box-sizing: border-box;
}
.container {
border: 2px solid gray;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 300px;
}
.header {
border: 2px solid magenta;
height: 50px;
line-height: 50px;
text-align: center;
}
.subcontainer {
display: flex;
flex-direction: row;
flex: 1;
}
.column1 {
flex-basis: 150px;
border: 2px solid green;
}
.column2 {
flex: 1;
border: 2px solid orange;
}
<div class='container'>
<div class='header'>it's a header</div>
<div class="subcontainer">
<div class='column1'>column 1</div>
<div class='column2'>column 2</div>
</div>
</div>

Do it like shown below
* {
box-sizing: border-box;
}
body,
html {
height: 100%;
}
.container {
border: 2px solid gray;
display: flex;
flex-direction: column;
height: 100%;
}
.header {
width: 100%;
border: 2px solid magenta;
height: 50px;
line-height: 50px;
text-align: center;
}
.body-container {
display: flex;
width: 100%;
flex: 1;
}
.column1 {
width: 50%;
border: 2px solid green;
}
.column2 {
width: 50%;
border: 2px solid orange;
}
<div class='container'>
<div class='header'>it's a header</div>
<div class="body-container">
<div class='column1'>column 1</div>
<div class='column2'>column 2</div>
</div>
</div>

Related

Align multiple elements with flex

I want to do something like that with flexbox:
.wrap {
display: flex;
flex-wrap: wrap;
}
.elem1 {
width: 20%;
height: 100px;
border: 1px solid red;
}
.elem2, .elem3 {
width: 75%;
border: 1px solid red;
}
<div class="wrap">
<div class="elem1">1</div>
<div class="elem2">2</div>
<div class="elem3">3</div>
</div>
JSFIDDLE
Switch to flex-direction: column.
Add flex-wrap: wrap.
Define a height for the container (so the flex items know where to wrap).
Box #1 will consume all space in the first column, forcing the following boxes to wrap to a new column.
No changes to the HTML.
.wrap {
display: flex;
flex-wrap: wrap;
flex-direction: column; /* NEW */
height: 100px; /* NEW */
justify-content: space-between; /* NEW */
}
.elem1 {
width: 20%;
flex-basis: 100%; /* NEW */
border: 1px solid red;
}
.elem2,
.elem3 {
width: 75%;
flex-basis: 40%; /* NEW */
border: 1px solid red;
}
<div class="wrap">
<div class="elem1">1</div>
<div class="elem2">2</div>
<div class="elem3">3</div>
</div>
Something like this maybe (tweak values as desired):
1. Using your height (100px) & widths (20% & 75%):
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
.wrap {
height: 100px;
display: flex;
flex-flow: row wrap;
}
.row {
width: 75%;
display: flex;
flex-flow: column wrap;
}
.elem1 {
width: 20%;
border: 1px solid lightgray;
}
.elem2 {
height: 50%;
border: 1px solid lightgray;
flex: 1;
margin: 10px;
}
.elem3 {
height: 50%;
border: 1px solid lightgray;
flex: 1;
margin: 10px;
}
<div class="wrap">
<div class="elem1">1</div>
<div class="row">
<div class="elem2">2</div>
<div class="elem3">3</div>
</div>
</div>
2. Full width & height option:
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
.wrap {
height: 100%;
display: flex;
flex-flow: row wrap;
justify-content: center;
}
.row {
width: 80%;
display: flex;
flex-flow: column wrap;
}
.elem1 {
width: 20%;
border: 1px solid lightgray;
}
.elem2 {
height: 50%;
border: 1px solid lightgray;
flex: 1;
}
.elem3 {
height: 50%;
border: 1px solid lightgray;
flex: 1;
}
<div class="wrap">
<div class="elem1">1</div>
<div class="row">
<div class="elem2">2</div>
<div class="elem3">3</div>
</div>
</div>

How can I prevent flexboxes from taking the remaining width of the row?

I want every cell to be 1/3 of the row. I tried achieving this with flexbox but the boxes with the css property "flex:1" act like they have "width:50%".
Fiddle example: http://jsfiddle.net/skip405/NfeVh/1073/
Html:
<div class="container">
<div class="row">
<div class="cell">
</div>
<div class="cell">
</div>
</div>
</div>
Css:
.container {
width: 100%;
background-color: gray;
}
.row {
background: #ccc;
display: flex;
flex: 3;
flex-direction: row;
}
.cell {
width: 50px;
height: 50px;
background-color: white;
border:1px solid black;
display: flex;
flex: 1;
}
Use this:
.cell {
width: 50px;
height: 50px;
background-color: white;
border:1px solid black;
display: flex;
flex: 0 0 calc(100%/3);
}
Use flex: 0 0 calc(100%/3)
See the fiddle: http://jsfiddle.net/NfeVh/1394/

Flexbox: scrollable content with sticky footer

I want to make a box (flex-item in this case) which always stays in the middle of it's container. In that box, there is a header, footer and content section. If the size of the content grows too big in height, I want the content section to be scrollable. The header and footer should always be visible and the box should always stay in it's container.
Here is what I have been able to write:
HTML
<div class="flex-container">
<div class="flex-item">
<header>Header</header>
<div class="content">
A
<br>B
<br>C
<br>D
<br>E
<br>F
<br>G
<br>H
<br>I
<br>J
<br>K
</div>
<footer>Footer</footer>
</div>
</div>
CSS
body {
margin: 120px;
}
.flex-container {
display: flex;
width: 200px;
height: 200px; /* We can assume that the container's height is hardcoded in this example, but the end solution should work even if this value is changed*/
border: 1px solid black;
justify-content: center;
}
.flex-item {
box-sizing: border-box;
width: 150px;
border: 5px solid blue;
align-self: center;
background-color: red;
display: flex;
flex-flow: column;
max-height: 100%;
}
.content {
/* It should be possible to scroll this element when it get too big in height*/
background-color: grey;
flex: 1;
}
The code is hosted on JSFiddle: https://jsfiddle.net/9fduhpev/3/
To explain the same thing visually, here is the current situation:
Here is what I want:
Use overflow-y: auto;.
Read this: http://www.w3schools.com/cssref/css3_pr_overflow-y.asp
body {
margin: 120px;
}
.flex-container {
display: flex;
width: 200px;
height: 200px;
border: 1px solid black;
justify-content: center;
}
.flex-item {
box-sizing: border-box;
width: 150px;
border: 5px solid blue;
align-self: center;
background-color: red;
display: flex;
flex-flow: column;
max-height: 100%;
}
.content {
background-color: grey;
flex: 1;
overflow-y: auto;
}
<div class="flex-container">
<div class="flex-item">
<header>Header</header>
<div class="content">
A
<br>B
<br>C
<br>D
<br>E
<br>F
<br>G
<br>H
<br>I
<br>J
<br>K
<br>L
</div>
<footer>Footer</footer>
</div>
</div>
I suggest you give it overflow: auto. With that it will be scrollable when needed.
body {
margin: 20px;
}
.flex-container {
display: flex;
width: 200px;
height: 200px;
border: 1px solid black;
justify-content: center;
}
.flex-item {
box-sizing: border-box;
width: 150px;
border: 5px solid blue;
align-self: center;
background-color: red;
display: flex;
flex-flow: column;
max-height: 100%;
}
.content {
background-color: grey;
flex: 1;
overflow: auto;
}
<div class="flex-container">
<div class="flex-item">
<header>Header</header>
<div class="content">
A
<br>B
<br>C
<br>D
<br>E
<br>F
<br>G
<br>H
<br>I
<br>J
<br>K
<br>L
</div>
<footer>Footer</footer>
</div>
</div>
I would do something like this:
.content {
height: 100%;
overflow:auto;
background-color: grey;
flex: 1;
}
https://jsfiddle.net/9fduhpev/4/

Max Height not working on flexing child with overflow

I have an element with 2 children.
I'm trying to have:
div grow as much as it needs based on 1 of its children
the other always fit the parents height
Thus, I want to avoid setting a height on the parent.
The problem arises when trying to handle overflow of the second child.
Here's the code:
.banner {
display: flex;
background-color: lightblue;
overflow: auto;
border: 4px solid black;
//max-height: 120px; // 1) IF I'M NOT SET THE SCROLL WON'T WORK
}
.constant {
color: white;
flex: 0 0 auto;
width: 200px;
// height: 150px; 2) DISABLED FOR NOW
border: 4px solid yellow;
background-color: olive;
border: 2px solid red;
}
.container {
display: flex;
text-align: center;
}
.main {
max-height: 100%; // 3) I SHOULD STOP MYSELF FROM GROWING MORE THAN MY PARENT
flex: 1;
overflow-y: scroll;
border: 2px solid white;
display: flex;
flex-direction: row-reverse;
align-items: flex-end;
flex-wrap: wrap;
}
.main div {
text-align: center;
width: 200px;
height: 80px;
}
.main-side {
flex: 0 0 auto;
color: white;
background-color: grey;
border: 2px solid yellow;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
background-repeat: no-repeat !important;
min-width: 0px;
min-height: 0px;
}
<div class="banner">
<div class="container">
<div class="main">
<div style="background-color:coral;">A</div>
<div style="background-color:lightgoldenrodyellow;">B</div>
<div style="background-color:khaki;">C</div>
<div style="background-color:pink;">D</div>
<div style="background-color:lightgrey;">E</div>
<div style="background-color:lightgreen;">F</div>
</div>
<div class="main-side">I've a fixed size</div>
</div>
<div class="constant">I can grow...and my parent should grow if I grow</div>
</div>
If I set a fixed height on .banner everything works out, but I would like to avoid doing so if possible.
jsfiddle
Thank you.

Howto scroll a context flex div

I have a simple site layout of Header and a 3 columns main section. The middle column should contain a lengthy content so I would like it to scroll, I can't make it happen.
Here is a prototype of the problem:
http://codepen.io/ValYouW/pen/GZxKBa
UPDATE: Sorry for not mentioning, but I meant for horizontal-scroll, not vertical...
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
display: flex;
box-sizing: border-box;
}
#layout {
display: flex;
flex: 1;
flex-direction: column;
border: 4px solid red;
}
#header {
border: 2px solid yellow;
}
#main {
border: 2px solid green;
display: flex;
flex: 1;
flex-direction: row;
}
#facets{
border: 2px solid pink;
display: flex;
width: 100px;
}
#report {
border: 2px solid pink;
display: flex;
flex: 1;
flex-direction: column;
}
#rightside {
border: 2px solid pink;
display: flex;
width: 100px;
}
#chips {
border: 2px solid orange;
}
#leads-grid {
border: 4px solid orange;
display: flex;
flex: 1;
overflow: auto;
}
#grid1 {
border: 2px solid black;
width: 1000px;
}
<div id="layout">
<div id="header">Header</div>
<div id="main">
<div id="facets">Facets</div>
<div id="report">
<div id="chips">Chips</div>
<div id="leads-grid">
<div id="grid1">How to make my parent (#leads-grid) scroll?</div>
</div>
</div>
<div id="rightside">Right side</div>
</div>
<div>
Any ideas how to make #leads-grid to scroll?
Thx.
for the leads-grid have scroll his son (grid1) needs to surpass the content. try to put a lot of br's into the content of grid1 and leads-grid will create a scroll.
Your #leads-grid is scrolling already.
You just need to add more content to #leads-grid.
See code below. I have added height: 5000px to #grid1 as inline style. Scroll appears.
html,
body {
height: 100%;
}
body {
margin: 0;
padding: 0;
display: flex;
box-sizing: border-box;
}
#layout {
display: flex;
flex: 1;
flex-direction: column;
border: 4px solid red;
}
#header {
border: 2px solid yellow;
}
#main {
border: 2px solid green;
display: flex;
flex: 1;
flex-direction: row;
}
#facets {
border: 2px solid pink;
display: flex;
width: 100px;
}
#report {
border: 2px solid pink;
display: flex;
flex: 1;
flex-direction: column;
}
#rightside {
border: 2px solid pink;
display: flex;
width: 100px;
}
#chips {
border: 2px solid orange;
}
#leads-grid {
border: 4px solid orange;
display: flex;
flex: 1;
overflow: auto;
}
#grid1 {
border: 2px solid black;
width: 1000px;
}
<div id="layout">
<div id="header">Header</div>
<div id="main">
<div id="facets">Facets</div>
<div id="report">
<div id="chips">Chips</div>
<div id="leads-grid">
<div id="grid1" style="height: 5000px;">How to make my parent (#leads-grid) scroll?</div>
</div>
</div>
<div id="rightside">Right side</div>
</div>
<div>