Flexbox Text wrapping - html

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>

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>

Prevent double borders around side-by-side elements

If you have multiple containers with 1px border, all containers next to each other generate a 2px border. So in order to get rid of that you always set e.g. border-right: none; and then add border-right: 1px; to the last child to make all containers have 1px border in all sides.
But if you use flexbox flex-basis rule to break containers into next line, it breaks whole border-right idea, the last container in the line before the break always stays left out with no border.
e.g. in this example I have 5 containers, but I want 4 per line and when it breaks into new line, you can see the border-right issue:
.wrapper {
display: flex;
flex-wrap: wrap;
width: 400px;
}
.container {
flex-basis: 20%;
border: 1px solid #000;
border-right: none;
margin-bottom: 1px;
min-height: 100px;
width: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.container:last-child {
border-right: 1px solid #000;
}
<div class="wrapper">
<div class="container">1</div>
<div class="container">2</div>
<div class="container">3</div>
<div class="container">4</div>
<div class="container">5</div>
</div>
https://jsfiddle.net/45kngj9p/
Since you know how many flex items there are in each row, you can use the :nth-child() selector to apply borders to items missed by the main rule.
.wrapper {
display: flex;
flex-wrap: wrap;
width: 400px;
}
.container {
flex-basis: 20%;
border-top: 1px solid #000;
border-bottom: 1px solid #000;
border-right: 1px solid #000;
margin-bottom: 1px;
min-height: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.container:nth-child(4n + 1) { /* add border to first child in each row */
border-left: 1px solid red;
}
<div class="wrapper">
<div class="container">1</div>
<div class="container">2</div>
<div class="container">3</div>
<div class="container">4</div>
<div class="container">5</div>
</div>
<hr>
<div class="wrapper">
<div class="container">1</div>
<div class="container">2</div>
<div class="container">3</div>
</div>
<hr>
<div class="wrapper">
<div class="container">1</div>
<div class="container">2</div>
<div class="container">3</div>
<div class="container">4</div>
<div class="container">5</div>
<div class="container">6</div>
<div class="container">7</div>
<div class="container">8</div>
<div class="container">9</div>
<div class="container">10</div>
</div>
Remove Border:none; and add margin-left:-1px;
.container {
flex-basis: 20%;
border: 1px solid #000;
margin-left:-1px;
margin-bottom: 1px;
min-height: 100px;
width: 100px;
display: flex;
justify-content: center;
align-items: center;
}
That's it!
You can try these solutions:
1
Here you don't need the .container:last-child styles.
.container {
flex-basis: 20%;
border: 1px solid #000;
margin-bottom: 1px;
margin-right: -1px;
min-height: 100px;
width: 100px;
display: flex;
justify-content: center;
align-items: center;
}
2
This one works for boxes number 4, 8, 12, etc.
.container {
flex-basis: 20%;
border: 1px solid #000;
border-right: none;
margin-bottom: 1px;
min-height: 100px;
width: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.container:last-child,
.container:nth-child(4n) {
border-right: 1px solid #000;
}

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.

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.

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>