Flex basis shrinks element but not parent - html

I am dealing with a flex-box issue. It seems that a flex item with flex basis is shrunk accordingly but the parent maintains its size as if the child still occupied its full size.
These two images are the exact same code except the .earnings-claim-wrapper in the second one does not have the flex property. The last image shows how chrome "represents" that empty space.
Expected behaviour:
I've reduced the code to this:
div{
padding:10px;
}
.earnings-container {
display: flex;
background-color: red;
}
.earnings-info-container {
background-color: orange;
}
.earnings-info {
display: flex;
flex-wrap: wrap;
justify-content: left;
align-items: flex-start;
background-color: green;
}
.earnings-info .earnings-claim {
align-self: flex-start;
background-color: yellow;
}
.earnings-claim-wrapper {
flex: 0 1 100px;
position: relative;
display: flex;
display: flex;
flex-direction: column;
background-color: purple;
}
<div class="earnings-container">
<div class="earnings-info-container">
<div class="earnings-info">
<div class="earnings-icon student-points"></div>
<div class="earnings-title">earnings-title</div>
<div class="earnings-claim-wrapper">
<div class="earnings-claim not-enough-effort">earnings-claim</div>
<span class="effort-message">Some long text text text text text text long text</span>
</div>
</div>
</div>
<div class="earnings-info-container">
<div class="earnings-info">
<div class="earnings-icon diamonds"></div>
<div class="earnings-title">earnings-title</div>
</div>
</div>
</div>

Instead of using flex: 0 1 100px; on earnings-claim-wrapper class, use width:100px;
div{
padding:10px;
}
.earnings-container {
display: flex;
background-color: red;
}
.earnings-info-container {
background-color: orange;
}
.earnings-info {
display: flex;
flex-wrap: wrap;
justify-content: left;
align-items: flex-start;
background-color: green;
}
.earnings-info .earnings-claim {
align-self: flex-start;
background-color: yellow;
}
.earnings-claim-wrapper {
width:100px;
position: relative;
display: flex;
display: flex;
flex-direction: column;
background-color: purple;
}
<div class="earnings-container">
<div class="earnings-info-container">
<div class="earnings-info">
<div class="earnings-icon student-points"></div>
<div class="earnings-title">earnings-title</div>
<div class="earnings-claim-wrapper">
<div class="earnings-claim not-enough-effort">earnings-claim</div>
<span class="effort-message">Some long text text text text text text long text</span>
</div>
</div>
</div>
<div class="earnings-info-container">
<div class="earnings-info">
<div class="earnings-icon diamonds"></div>
<div class="earnings-title">earnings-title</div>
</div>
</div>
</div>

I've got to be honest that I can't fully reproduce what happens in your code that makes .earning-info expand. But I did find out it has to do with setting a flex-basis on the .earnings-claim-wrapper elements.
Giving all it's parents a flex-basis as well did the trick here.
Also, I think you can remove some properties, I've commented them out in the snippet.
div{
padding:10px;
}
.earnings-container {
display: flex;
background-color: red;
}
.earnings-info-container {
flex: 0 1 1%;
background-color: orange;
display: flex;
align-items: flex-start;
}
.earnings-info {
flex: 0 1 1%;
display: flex;
/*flex-wrap: wrap;*/
/*justify-content: left;*/
/*align-items: flex-start;*/
background-color: green;
}
.earnings-info .earnings-claim {
/*align-self: flex-start;*/
background-color: yellow;
}
.earnings-claim-wrapper {
flex: 0 1 100px;
/*position: relative;
display: flex;*/
display: flex;
flex-direction: column;
background-color: purple;
}
<div class="earnings-container">
<div class="earnings-info-container">
<div class="earnings-info">
<div class="earnings-icon student-points">x</div>
<div class="earnings-title">earnings-title</div>
<div class="earnings-claim-wrapper">
<div class="earnings-claim not-enough-effort">earnings-claim</div>
<span class="effort-message">Some long text text text text text text long text</span>
</div>
</div>
</div>
<div class="earnings-info-container">
<div class="earnings-info">
<div class="earnings-icon diamonds">x</div>
<div class="earnings-title">earnings-title</div>
</div>
</div>
</div>

Related

Shrink flexbox to the size of its children

I need to arrange a bunch of blocks of fixed size into a grid. I am using flex-wrap: wrap to get as many in each row as will fit. But, I would like this whole wrapped column to be centered in the page. Ideally, I would like it to look something like this:
But, in the snippet I have below, the green flexbox fills to fit any space it can, so all the blue boxes are pushed all the way to the left. I don't want to set the flexbox to a fixed width because I want it to be able to flow to fit as many boxes in a row as possible, but I just don't want it to take up any more space beyond that.
Obviously, I could use justify-content: center to center the boxes within the container, but the incomplete row at the bottom gets out of alignment, which I don't want.
Is there any way to achieve the effect I am looking for with CSS?
I saw this question which suggested using display: inline-flex. That does seem to work when you are not wrapping, but as soon as you put on flex-wrap: wrap and add enough items to make it wrap, it jumps back to filling the full width.
.page {
width: 100%;
background-color: pink;
padding: 10px;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
}
.flex-column {
display: flex;
flex-direction: row;
flex-wrap: wrap;
background-color: green;
justify-content: flex-start;
gap: 10px;
}
.flex-child {
display: block;
width: 200px;
height: 100px;
background-color: blue;
}
.button {
display: inline-block;
padding: 20px;
background-color: red;
}
.
<div class='page'>
<div class="flex-column">
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
</div>
<div class="button">Load more</div>
</div>
Since the width is always the same, CSS grid can help you here:
.page {
background-color: pink;
display: grid;
grid-template-columns:repeat(auto-fit,200px); /* same width as child */
gap:10px; /* the same gap here */
justify-content:center; /* center everything */
}
.flex-column {
display: flex;
flex-direction: row;
flex-wrap: wrap;
background-color: green;
grid-column:1/-1; /* take all the columns */
gap: 10px;
}
.flex-child {
width: 200px;
height: 100px;
background-color: blue;
}
.button {
padding: 20px;
background-color: red;
grid-column:1/-1; /* take all the columns */
margin:auto; /* center the button */
}
<div class='page'>
<div class="flex-column">
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
</div>
<div class="button">Load more</div>
</div>
In mine it is working like this you can see:
.page {
width: 100%;
background-color: pink;
padding: 10px;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
}
.flex-column {
display: flex;
flex-direction: row;
flex-wrap: wrap;
background-color: green;
justify-content: flex-start;
gap: 10px;
display: flex;
padding: 20px;
}
.flex-child {
display: block;
width: 200px;
height: 100px;
background-color: blue;
flex: 0 1 auto;
}
.button {
display: inline-block;
padding: 20px;
background-color: red;
}
.
<div class='page'>
<div class="flex-column">
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
<div class="flex-child"></div>
</div>
<div class="button">Load more</div>
</div>

How to apply flex-grow?

I'm trying to create a flex row with a growth of 2 and then a wrap but can't understand why it is not working properly.
Here is the CSS and HTML.
.flex {
height: 50px;
width: 50px;
background-color: black;
}
.flex1 {
height: 50px;
width: 50px;
background-color: yellow;
margin-left: 50px;
}
.flex2 {
height: 50px;
width: 50px;
background-color: green;
margin-left: 50px;
}
.flexcontainer {
display: flex;
flex-wrap: wrap;
flex-grow: 2;
flex-direction: row;
}
<div class="flexcontainer">
<div class="flex">
<div class="flex1">
<div class="flex2">
</div>
</div>
</div>
</div>
The way you implement the flex-grow is totally wrong because the flex-grow have to be applied to child elements as shown in below code snippet as a example.
#content {
display: flex;
justify-content: space-around;
flex-flow: row wrap;
align-items: stretch;
}
.box {
flex-grow: 1;
border: 3px solid rgba(0,0,0,.2);
}
.box1 {
flex-grow: 2;
border: 3px solid rgba(0,0,0,.2);
}
<h4>This is a Flex-Grow</h4>
<div id="content">
<div class="box" style="background-color:red;">A</div>
<div class="box" style="background-color:lightblue;">B</div>
<div class="box" style="background-color:yellow;">C</div>
<div class="box1" style="background-color:brown;">D</div>
<div class="box1" style="background-color:lightgreen;">E</div>
<div class="box" style="background-color:brown;">F</div>
</div>
To read more about flex-grow, you should learn from there : https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow

How to set a row height in flex box?

How can I increase the height of a row in flex (the div that contains has the class "row")? I have one row with two columns.
.body2 {
display: flex;
}
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
}
.column {
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
}
.blue-column {
background-color: blue;
height: 100px;
}
.green-column {
background-color: green;
height: 100px;
}
<section class="body2">
<div class='row'>
<div class='column'>
<div class='blue-column'>
Some Text in Column One
</div>
</div>
<div class='column'>
<div class='green-column'>
Some Text in Column Two
</div>
</div>
</div>
</section>
How can I increase the height of that row? I already tried height:something in .row but it doesn't work
If you set a height on the container, the height will apply to the container, but not necessarily to the content of the container, so it may not look like you've added height.
In this example, a height is added to the container, as illustrated with the red border:
.body2 {
display: flex;
}
.row {
display: flex;
flex: 1;
height: 150px;
border: 1px dashed red;
}
.column {
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
}
.blue-column {
background-color: aqua;
height: 100px;
}
.green-column {
background-color: lightgreen;
height: 100px;
}
<section class="body2">
<div class='row'>
<div class='column'>
<div class='blue-column'>
Some Text in Column One
</div>
</div>
<div class='column'>
<div class='green-column'>
Some Text in Column Two
</div>
</div>
</div>
</section>
If you want to add height to the descendants, use height or flex-basis (since the nested flex container is in column-direction).
.body2 {
display: flex;
}
.row {
display: flex;
flex: 1;
height: 150px;
border: 1px dashed red;
}
.column {
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
}
.blue-column {
background-color: aqua;
height: 75px;
}
.green-column {
background-color: lightgreen;
flex-basis: 125px;
}
<section class="body2">
<div class='row'>
<div class='column'>
<div class='blue-column'>
Some Text in Column One
</div>
</div>
<div class='column'>
<div class='green-column'>
Some Text in Column Two
</div>
</div>
</div>
</section>
If you want the descendants to take full height, use flex: 1 instead of an explicit height.
.body2 {
display: flex;
}
.row {
display: flex;
flex: 1;
height: 150px;
border: 1px dashed red;
}
.column {
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
}
.blue-column {
background-color: aqua;
/* height: 75px; */
flex: 1;
}
.green-column {
background-color: lightgreen;
/* flex-basis: 125px; */
flex: 1;
}
<section class="body2">
<div class='row'>
<div class='column'>
<div class='blue-column'>
Some Text in Column One
</div>
</div>
<div class='column'>
<div class='green-column'>
Some Text in Column Two
</div>
</div>
</div>
</section>

CSS flex grow does not work with added div on top

Consider the following fiddle: https://jsfiddle.net/7naxprzd/1/
Requirements are:
two columns with header and contents
tops of columns should align
bottom of columns should align
on top of each column there should be a horizontally centered arrow
The code is working properly if the arrows are eliminated by deleting the div with class .arrow-wrapper, but I need the arrows.
A solution could be to absolute position the arrow, but is there a way to solve this layout issue with flex without absolute positioning the arrow?
Should work for modern browsers and IE11.
.row-wrapper {
display: flex;
}
.col-wrapper-outer {
display: flex;
flex-wrap: wrap;
}
.arrow-wrapper {
width: 100%;
text-align: center;
font-size: 30px;
}
.col-wrapper {
width: 100%;
display: flex;
flex-direction: column;
border: 2px solid red;
color: white;
}
.col-wrapper .header {
background: blue;
}
.col-wrapper .contents {
flex: 1 0 auto;
background: green;
}
<div class="row-wrapper">
<div class="col-wrapper-outer">
<div class="arrow-wrapper">
↓
</div>
<div class="col-wrapper">
<div class="header">Please align tops.</div>
<div class="contents">Let me grow.</div>
</div>
</div>
<div class="col-wrapper-outer">
<div class="arrow-wrapper">
↓
</div>
<div class="col-wrapper">
<div class="header">please align tops.</div>
<div class="contents">Let me grow.<br>Please<br>align<br>bottoms.</div>
</div>
</div>
</div>
In your div with class col-wrapper-outer, instead of this:
.col-wrapper-outer {
display: flex;
flex-wrap: wrap;
}
Use this:
.col-wrapper-outer {
display: flex;
flex-direction: column;
}
Then add flex: 1 to .col-wrapper so it takes the full height of the container.
revised fiddle
.row-wrapper {
display: flex;
}
.col-wrapper-outer {
display: flex;
/* flex-wrap: wrap; */
flex-direction: column; /* NEW */
}
.arrow-wrapper {
width: 100%;
text-align: center;
font-size: 30px;
}
.col-wrapper {
flex: 1; /* NEW */
width: 100%;
display: flex;
flex-direction: column;
border: 2px solid red;
color: white;
}
.col-wrapper .header {
background: blue;
}
.col-wrapper .contents {
flex: 1 0 auto;
background: green;
}
<div class="row-wrapper">
<div class="col-wrapper-outer">
<div class="arrow-wrapper">
↓
</div>
<div class="col-wrapper">
<div class="header">Please align tops.</div>
<div class="contents">Let me grow.</div>
</div>
</div>
<div class="col-wrapper-outer">
<div class="arrow-wrapper">
↓
</div>
<div class="col-wrapper">
<div class="header">please align tops.</div>
<div class="contents">Let me grow.
<br>Please
<br>align
<br>bottoms.</div>
</div>
</div>
</div>

Flexbox column direction same width

How can I make my flexbox with column direction children be same width.
JSFiddle Example:
https://jsfiddle.net/6ynofan5/
<div class="block">
<div class="title">Some dummy text here, huh</div>
<div class="info">
<div class="text">1</div>
<div class="text">2</div>
<div class="text">3</div>
</div>
</div>
 
.block {
display: flex;
flex-direction: column;
align-items: center;
}
.block .title {
font-size: 30px;
}
.block .info {
display: flex;
justify-content: space-between;
}
Div with class .info should be the same width as .title, there should not be fixed width.
The equalising of widths is managed by align-items where the default is stretch. In this instance you have over-ridden this and so a wrapper is needed.
Then the two inner divs can be their natural 100% width.
.block {
display: flex;
flex-direction: column;
border: 1px solid grey;
justify-content: center;
align-items: center;
}
.title {
font-size: 30px;
background: lightblue;
}
.info {
display: flex;
justify-content: space-between;
background: plum;
}
<div class="block">
<div class="wrap">
<div class="title">Some dummy text here, huh</div>
<div class="info">
<div class="text">1</div>
<div class="text">2</div>
<div class="text">3</div>
</div>
</div>
</div>
.block {
display: table;
flex-direction: column;
align-items: center;
}
https://jsfiddle.net/1mz9f8p0/1/