Word-wrap in flexbox is not respecting 100% width limit [duplicate] - html

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 5 years ago.
I have 2 flexboxes and a flexbox inside one.
I want the text to break into multiple lines if it is bigger than it's parent. For some reason it works if I sent a fixed value (e.g. 250px) as width. If I set the width to 100%, it will not break into multiple lines.
This is the code I have:
#flexparent {
display: flex
}
#flexchild1 {
flex: 1;
background-color: green;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column
}
#flexchild3 {
background-color: purple;
width: 100%;
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
</div>
</div>
</div>
This is how I want it but without the spaces in the long sentence.
#flexparent {
display: flex
}
#flexchild1 {
flex: 1;
background-color: green;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column
}
#flexchild3 {
background-color: purple;
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
Thisisasuperlongsentence Loremipsum dolorsitametcon secteturadipisicingelitAsperi resnecessitatibusneu eodioImpeditistenes ciuntescorru ptiessecumrepudia ndaequidolor umIllumtempori busquoerrorcumqu eeximpeditmagnam Lore mipsumdo lorsitam etconsecteturadipisicing elitAsperioresne cessitatibusneueodi oImpeditisten esciuntescorruptiessecumrepudia ndaequidolorumIll umtemporibusq uoerrorc umqueeximpe ditmagn amtstLoremipsu mdolorsitametcon secteturadipisici ngelitAsperio resnecessitati busn
</div>
</div>
</div>
Here are the codepens I made for this.
The code I have: https://codepen.io/tomzz/pen/mpJMow
How I want it but without the 250px width: https://codepen.io/tomzz/pen/VyLMaW
How I want it but without the spaces in the sentence: https://codepen.io/tomzz/pen/vpOeJp

This is a min-width issue, where a flex item can't be smaller than its content.
The default value of min-width is auto, and in this case it happens to the flex item #flexchild2
Give it min-width: 0 and it will work.
Also, the width: 100% is not needed, since a flex "column" item's align-items default to stretch, and as such automatically take full width of its parent, and can be removed.
Stack snippet
#flexparent {
display: flex
}
#flexchild1 {
flex: 1;
background-color: green;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column;
min-width: 0; /* added */
}
#flexchild3 {
background-color: purple;
/*width: 100%; removed */
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
</div>
</div>
</div>

The problem is that percentage-based widths are based off of the immediate parent. If the immediate parent has no width, the child cannot know what 100% of an arbitrary value is. flex: 1 is shorthand that contains flex-grow: 1, meaning that #flex2 can grow infinitly without setting this width constraint.
Percentage-based widths bubble up to the point a fixed width is known, so all you have to do is set a width of 100% of #flexchild2 as well in order for #flexchild3 to inherit the width of #flexparent:
This can be seen in the following:
#flexparent {
display: flex;
}
#flexchild1 {
flex: 1;
background-color: green;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column;
width: 100%;
}
#flexchild3 {
background-color: purple;
width: 100%;
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
</div>
</div>
</div>
However, note that due to you using two columns, you'll probably want to give #flexparent a width of 100%, and set your two columns to 20% and 80% respectively. Note that #flexchild3 still inherits 100% of the width of #flexchild2 (which is 80% of the width of #flexparent):
#flexparent {
display: flex;
width: 100%;
}
#flexchild1 {
flex: 1;
background-color: green;
width: 20%;
}
#flexchild2 {
flex: 1;
background-color: red;
display: flex;
flex-flow: column;
width: 80%;
}
#flexchild3 {
background-color: purple;
width: 100%;
word-wrap: break-word;
}
<div id="flexparent">
<div id="flexchild1">
FLEXCHILD1
</div>
<div id="flexchild2">
FLEXCHILD2
<div id="flexchild3">
ThisisasuperlongsentenceLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtstLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamLoremipsumdolorsitametconsecteturadipisicingelitAsperioresnecessitatibusneueodioImpeditistenesciuntescorruptiessecumrepudiandaequidolorumIllumtemporibusquoerrorcumqueeximpeditmagnamtst
</div>
</div>
</div>
Hope this helps! :)

Related

Flex box isn't filling remaining space when using flex-grow 1

I am trying to fill the remaining space of a containing flex box with the green div. I want the top flex row (blue) to only be the height of its contents and then the row below (green) to fill the rest. For some reason it just seems to split the flex rows evenly down the div. I have read a few questions on here already which all say to make sure the containing div has its height set to 100%. I have set the containing div height to 200px as this is my desired height, but I have also tried adding another container within this to 100% to no avail. I've also made sure to set the flex-grow property on the second row to 1. Every time I think I'm beginning to understand flex it throws another curve ball and it's driving me up the wall. Please help! Thank you.
P.S. for some reason the HTML code snippet below refuses to include the first line of my html but it is contained in the following div: <div class="rmCtrlList_item"
.rmCtrlList_item {
width: 80vw;
margin: 3vw 8.5vw;
height: 200px;
background-color: $primary-color;
border-radius: 10px;
padding: 5px;
display: flex;
flex-flow: row;
flex-wrap: wrap;
// ROWS
&_row {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#row-1 {
//max-height: 20px;
background-color: blue;
}
#row-2 {
flex-grow: 1;
align-items: center;
justify-content: center;
background-color: green;
}
// COLUMNS
&_col {
text-align: left;
flex-direction: column;
}
#col-1b {
flex-grow: 1;
}
}
<div class="rmCtrlList_item">
<div class="rmCtrlList_item_row" id="row-1">
<div class="rmCtrlList_item_col" id="col-1a">
<i class="icon__panel-2 fas fa-lightbulb"></i>
</div>
<div class="rmCtrlList_item_col" id="col-1b">
<a href="lights.html">
<h1 class="panel__title">Lights</h1>
</a>
</div>
<div class="rmCtrlList_item_col" id="col-1c">
<i class="icon__enlarge fas fa-plus-circle"></i>
</div>
</div>
<div class="rmCtrlList_item_row" id="row-2">
div to fill remaining space
</div>
</div>
how about to use flex-direction and below code what I used? green will fill ramaining space automatically, if you use its height's 100%
.container{
display: flex;
flex-direction: column;
width: 200px;
height: 300px;
border: 1px solid black;
}
.blue{
width: 100%;
height: 90px; /*change only blue's height size, green will be filled automatically*/
background: blue;
}
.green{
width: 100%;
height: 100%;
background: green;
}
<div class="container">
<div class="blue"></div>
<div class="green"></div>
</div>

Safari: Min-height 100% doesn't work inside a flex-grow child [duplicate]

This question already has answers here:
Chrome / Safari not filling 100% height of flex parent
(5 answers)
Closed 3 years ago.
In Chrome, Edge, and FireFox, the below code produces the (correct) output where the innermost div fills it's parent using min-height: 100%. However, in Safari this does not occur. I expect the green div to be completely covered by its children.
Why is that? / How can I obtain the correct behavior?
.container {
display: flex;
flex-direction: column;
height: 80vh;
}
.item1 {
flex-shrink: 0;
background: red;
}
.item2 {
flex-grow: 1;
background: green;
}
.inner {
background: blue;
min-height: 100%;
}
<div class="container">
<div class="item1">Random text for size</div>
<div class="item2">
<div class="inner"></div>
</div>
</div>
StackBlitz
This can be fixed by setting an explicit height for every parent element of .inner.
<div class="container">
<div class="item1">Random text for size</div>
<div class="item2">
<div class="inner"></div>
</div>
</div>
<style>
.container {
display: flex;
flex-direction: column;
height: 80vh;
}
.item1 {
flex-shrink: 0;
background: red;
}
.item2 {
flex-grow: 1;
height: 100%;
background: green;
}
.inner {
background: blue;
min-height: 100%;
}
</style>
Background info and more possible fixes: Chrome / Safari not filling 100% height of flex parent

How can I accomplish this design with flexbox?

I'm trying to accomplish this design by using flexbox:
It's supposed to be a one page website.
.container {
display: flex;
}
.big {
flex: 2;
height: 70vh;
background: gray;
}
.small {
flex: 1;
height: 70vh;
background: gray;
}
<div class="container">
<div class="small">
</div>
<div class="smallest">
</div>
<div class="big">
</div>
</div>
I have no idea how to implement the "smallest" div to be 25% of the big, let alone make the "small" 75% of the big one.
Also the height really confuses me, I need them to always have the same height.
With flexbox you can wrap the small and the smallest into a separate div and use column flexbox on the left section.
I have no idea how to implement the "smallest" div to be 25% of the big
25% to 75% ratio means 1:3 ratio - and in flexbox language that is flex: 1 to the small element and flex: 3 to the big element.
Also the height really confuses me, I need them to always have the same height.
You can set the height of the container to the container element - your flexbox will fill to this height.
See demo below:
.container {
display: flex;
height: 70vh;
}
.big {
flex: 3;
background: gray;
margin-left: 5px;
}
.left {
flex: 1;
display: flex;
flex-direction: column;
}
.left .small {
background: gray;
flex: 3;
}
.left .smallest {
margin-top: 5px;
background: gray;
flex: 1;
}
<div class="container">
<div class="left">
<div class="small">
</div>
<div class="smallest">
</div>
</div>
<div class="big">
</div>
</div>

Scrollbar and its content is hidden outside of div

So I have a problem where I have 2 divs inside of another div with a fixed size. I the second of the two is too large to fit in the fixed height div so I want a scroll bara to appear. But the scrollbar goes outside of the content. How do I fix this?
html:
<div class="main">
<div class="first-child">
<div class="small-content">
Content
</div>
</div>
<div class="second-child">
<div class="large-content">
Content
</div>
</div>
</div>
css:
.main {
height: 250px;
overflow: hidden;
}
.first-child {
background-color: red;
}
.second-child {
max-height: 100%;
background-color: blue;
overflow-y: scroll;
}
.large-content {
padding-top: 300px;
}
.small-content {
padding: 10px;
}
https://codepen.io/RilleJ/pen/JeBVpz
I added an example as well to show what I mean. Basically I want to be able to scroll all the way down in the blue box and see the content without setting a fixed height. (Not that the content above, the red box, can be different sizes)
Use flexbox to divide the space of the container among the children.
Add flex-grow: 0, and flex-shrink: 0 for a child that just needs to take the space it needs for its content.
Add flex-grow: 1, and flex-shrink: 1 on the other children to divide the remaining space equally (each child will take at least the size of its content).
.main {
height: 250px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.first-child {
flex-grow: 0;
flex-shrink: 0;
background-color: red;
}
.second-child {
flex-grow: 1;
flex-shrink: 1;
background-color: blue;
overflow-y: scroll;
}
.large-content {
padding-top: 300px;
}
.small-content {
padding: 10px;
}
<div class="main">
<div class="first-child">
<div class="small-content">
Content
</div>
</div>
<div class="second-child">
<div class="large-content">
Content
</div>
</div>
</div>

A flexbox grid of two flex items next to one [duplicate]

This question already has answers here:
Is it possible for flex items to align tightly to the items above them?
(5 answers)
Make a div span two rows in a grid
(2 answers)
Closed 5 years ago.
I am trying to have one div on the left and two on the right. The bottomright should always be below the topRight div. The topRight is the only div with a variable height.
I am currently trying to achieve this using flexbox als you can see in my code below.
I would like to have some directions.
.wrapper {
display: flex;
height: 100px;
}
.left {
background-color: green
}
.topRight {
background-color: yellow
}
.bottomright {
background-color: red
}
<div class="wrapper">
<div class="left">Left</div>
<div class="topRight">TopRight</div>
<div class="bottomright">Bottom</div>
</div
With a fixed height on the container, as you have in your code, you can use flex-direction: column and flex-wrap: wrap. The fixed height serves as a break point, telling flex items where to wrap.
.wrapper {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100px;
}
.left {
flex: 0 0 100%; /* consumes full height of first column; forces siblings to wrap */
background-color: lightgreen
}
/* variable height div */
.topRight {
background-color: yellow
}
.bottomright {
flex: 1; /* consumes remaining space in column */
background-color: red
}
<div class="wrapper">
<div class="left">Left</div>
<div class="topRight">TopRight<br>variable height</div>
<div class="bottomright">Bottom</div>
</div>
On html put a div with a class called right wrapping both topRight and bottomRight and use this css on css:
.wrapper {
display: flex;
height: 100px;
}
.right {
display: flex-flow;
}
.left {
background-color: green
}
.topRight {
background-color: yellow;
height: 50px;
}
.bottomright {
background-color: red;
height: 50px;
}
I hope that helps you :)
For infos
display:grid is made for this .... very soon available for most browsers and yet for a few
A tutorial among others : https://css-tricks.com/snippets/css/complete-guide-grid/
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* any height s */
background-color: green;
}
.leftspan {
grid-row: span 2;/* if 2 rows avalaible */
}
.topRight {
background-color: yellow;
grid-column: 2 /-1
}
.bottomright {
background-color: red;
grid-column: 2 /-1
}
.bottomfull {
background-color: red;
grid-column: 1 /-1
}
<div class="wrapper">
<div class="leftspan">Left spanning 2 rows</div>
<div class="topRight">Top <br/>Right</div>
<div class="bottomright">Bottom <br/>Right</div>
</div>
<p> or did you mean ?
<div class="wrapper">
<div class="left">Left</div>
<div class="topRight">Top Right</div>
<div class="bottomfull">Bottom <br/>Right</div>
</div>
render if your browsers understand grid: