Howto scroll a context flex div - html

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>

Related

Stretch columns in two columns layout with shared header using flexbox

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>

Flexbox Text wrapping

I have the following layout:
.main {
height: 200px;
width: 300px;
border: 1px solid black;
background-color: rgba(255, 46, 0, 0.5);
}
.container {
height: 200px;
width: 200px;
margin: auto;
border: 1px solid black;
z-index: 2;
background-color: white;
display: flex;
align-items: stretch;
justify-content: center;
}
.text1 {
border: 1px solid red;
flex-wrap: nowrap;
flex-grow: 1;
}
.text2 {
border: 1px solid blue;
flex-wrap: nowrap;
flex-grow: 2;
}
<div class="main">
<div class="container">
<div class="text1">Lorem impsum pimpsum</div>
<div class="text2">Tex2</div>
</div>
</div>
I would like my text to wrap inside the div .text1 and .text2 without disturbing the flexgrow. In other words, is there any way to force flexbox to stay at the same size no matter the text in it?
I'm using Chrome. Codepen link: https://codepen.io/Konrad29/pen/Oxbmqx
By setting the flex-basis to 0, you control the width (distribute the space) with flex-grow
Update these rules
.text1{
border: 1px solid red;
flex-wrap:nowrap;
flex:1 1 0; /* updated */
min-width: 0; /* might be needed as well */
}
.text2{
border: 1px solid blue;
flex-wrap:nowrap;
flex:2 2 0; /* updated */
min-width: 0; /* might be needed as well */
}
This will make the text1 to take 1/3 of the available space and the text2 2/3.
Based on what content you will put in each text1/2, you might also need to set min-width, which defaults to auto, to 0 to allow it the be smaller than its content
Updated codepen
Stack snippet
.main{
height: 200px;
width: 300px;
border: 1px solid black;
background-color :rgba(255, 46, 0, 0.5);
}
.container{
height: 200px;
width: 200px;
margin: auto;
border: 1px solid black;
z-index:2;
background-color: white;
display: flex;
align-items: stretch;
justify-content:center;
}
.text1{
border: 1px solid red;
flex-wrap:nowrap;
flex:1 1 0;
}
.text2{
border: 1px solid blue;
flex-wrap:nowrap;
flex:2 2 0;
}
<div class="main">
<div class="container">
<div class="text1">Lorem impsum pimpsum</div>
<div class="text2">Tex2</div>
</div>
</div>

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 does CSS flex-basis affect the width calculation of its container?

In the following example, the flex-basis: 30px and width: 30px of a flex item will result in different container width(flex-basis is shorter).
How does flex-basis affect its parent width in the following example:
.flex-container {
padding: 0;
margin: 0;
display: flex;
border: 1px solid blue;
}
.grand {
display: flex;
border: 1px solid green;
}
.flex-item {
background: tomato;
padding: 10px;
border: 1px solid red;
color: white;
font-size: 2em;
}
.flex1 {
flex-shrink: 0; /* added according to Michael_B's answer */
flex-basis: 100px;
}
<div class="grand">
<div class="flex-container">
<div class="flex-item flex1">1</div>
<div class="flex-item flex2">22222 222222222</div>
</div>
</div>
The is the expected behavior:
.flex-container {
padding: 0;
margin: 0;
display: flex;
border: 1px solid blue;
}
.grand {
display: flex;
border: 1px solid green;
}
.flex-item {
background: tomato;
padding: 10px;
border: 1px solid red;
color: white;
font-size: 2em;
}
.flex1 {
/* flex-basis: 100px; */
width: 100px;
}
<div class="grand">
<div class="flex-container">
<div class="flex-item flex1">1</div>
<div class="flex-item flex2">22222 222222222</div>
</div>
</div>
In the flex-basis version, the flex2 item will wrap the text, while the width version will not. How did that happen.

Nested Flexbox Breaking Parent

I've been trying to implement a simple nested flexbox function. I'm having an issue where it appears that I can have two levels (vertical columns -> horizontal rows), but if I try to extend beyond that, (vertical -> horizontal -> vertical) it breaks the containers height.
I have a CodePen hosted here that better describes my question.
http://codepen.io/FrederickGeek8/pen/xGoPXd
Compiled HTML:
<div class="workspace">
<div class="vertical">
<div class="item">
<div class="horizontal">
<div style="background:pink" class="item"><a>Up</a></div>
<div class="item">
<div class="vertical">
<div style="background:red" class="item"><a>Left</a></div>
<div style="background:orange" class="item"><a>Strange</a></div>
</div>
</div>
<div style="background:blue" class="item"><a>Another</a></div>
</div>
</div>
<div class="item"><a>Right</a></div>
<div style="background:green" class="item"><a>Dang</a></div>
</div>
</div>
Compiled CSS (autoprefixed on CodePen):
.workspace {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.vertical {
flex: 1;
display: flex;
flex-direction: row;
background: grey;
width: 100%;
height: 100%;
}
.vertical > .item {
flex: 1;
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
margin: auto;
border-left: 1px solid #181a1f;
border-bottom: 1px solid #181a1f;
flex-grow: 1;
}
.horizontal {
flex: 1;
display: flex;
flex-direction: column;
background: grey;
width: 100%;
height: 100%;
}
.horizontal > .item {
flex: 1;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
margin: auto;
border-left: 1px solid #181a1f;
border-bottom: 1px solid #181a1f;
flex-grow: 1;
}
PS: The platform I will be running the finished product on is a packaged Chromium instance.
I removed some unnecessary height: 100% and the margin: auto
http://codepen.io/anon/pen/waLPzR
.workspace {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
}
.vertical {
flex:1;
display: flex;
flex-direction: row;
background:grey;
width:100%;
height: 100%;
> {
.item {
flex:1;
display: flex;
flex-direction: row;
width:100%;
border-left: 1px solid #181a1f;
border-bottom: 1px solid #181a1f;
flex-grow: 1;
}
}
}
.horizontal {
flex:1;
display: flex;
flex-direction: column;
background:grey;
width:100%;
> {
.item {
flex:1;
display: flex;
flex-direction: column;
width:100%;
border-left: 1px solid #181a1f;
border-bottom: 1px solid #181a1f;
flex-grow: 1;
}
}
}