I have a problem with flex-box. I want a one column with two rows where there are 2 columns on the second row. However I want to use just one wrapper element for it (I do not want to wrap the second row into a div). The issue is that I want only the second row elements to strech.
Here it is https://jsfiddle.net/x8g0wupg/
HTML
<div id="wrap">
<header>text</header>
<div id="a">text</div>
<div id="b">text</div>
</div>
CSS
#wrap {
display: flex;
flex-flow: row wrap;
height: 500px;
border: 3px solid yellow;
}
header {
background-color: white;
width: 50px;
flex: 1 100%;
height: 40px;
}
#a {
background-color: green;
flex-grow: 1;
}
#b {
background-color: red;
flex-grow: 1;
}
I managed to make them the way I want them to be positioned however the first column element just doesnt want to shring to the height I have set to him instead of it it leaves a empty space to the vertical 50% of the wrapper.
Is there any way to do it without extra wrapper for the second row?
Thank you!
A bit hackish, with align-self: flex-end; and a negative top margin on the parent.
See https://jsfiddle.net/C14L/1rj3kdkb/
Related
I am making responsive design where elements wrap to next line in certain way when there is not enough space, however I cannot make it working.
Requirements:
There are 3 elements (actually more, but this is minimal example), all with automatic size depending on their content: one aligned on the left, two - on the right.
They are placed inside container which always spans at least 100% width of parent.
If there is not enough space for elements to be all on one line, then right element should begin to wrap to next line, while still all being to the right of left element.
If there is still not enough space, only then right elements go under left one.
If there is still not enough space, then container expands in size.
Here are examples how it should work (red lines represent viewport borders):
Here is code I come up with so far, but it starts wrapping immediately on outer level, not on innermost as I need:
html, body {
width: 100%;
height: 100%;
}
* {
margin: 0;
padding: 0;
flex: 0 0 auto;
}
#container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
overflow: hidden;
width: 100%;
min-width: min-content;
background-color: rgb(224, 191, 146); /* for visibility */
}
#child-left {
background-color: rgb(92, 189, 40); /* for visibility */
/* imitate content for demo, in actual code size is not set */
width: 50vw;
height: 50px;
}
#child-right {
display: flex;
flex-flow: row wrap;
background-color: rgb(111, 72, 20); /* for visibility */
}
#grandchild-right-1 {
background-color: rgb(40, 102, 189); /* for visibility */
/* imitate content for demo, in actual code size is not set */
width: 200px;
height: 20px;
}
#grandchild-right-2 {
background-color: rgb(189, 40, 112); /* for visibility */
/* imitate content for demo, in actual code size is not set */
width: 200px;
height: 20px;
}
<div id="container">
<div id="child-left">1</div>
<div id="child-right">
<div id="grandchild-right-1">2</div>
<div id="grandchild-right-2">3</div>
</div>
</div>
You can achieve this by using flex: 1.
Remember that flex is a shorthand property for flex: 1 1 0 or flex-grow: 1, flex-shrink: 1 and flex-basis: 0.
As a result, this makes the elements take any empty space in the container, hopping to the next line if theres no space left.
https://css-tricks.com/understanding-flex-grow-flex-shrink-and-flex-basis/
This question already has answers here:
The difference between flex:1 and flex-grow:1
(2 answers)
Closed 3 years ago.
Hello currently I'm learning flexbox, and I've watched a lot tutorials but I couldn't figure out what does flex property do? Some explanation and links that explain what it does would be really helpful. Thanks.
As T. Evans mentioned, the flex property is shorthand for three other properties: flex-grow, flex-shrink, and flex-basis. You can set the values of each property by giving the flex property three values, in this order:
flex: [flex-grow] [flex-shrink] [flex-basis]
For example, flex: 0 1 auto;
Now, let’s briefly review what each of those three properties means.
Flex-grow
We use this property on a child element of a flex-box. It sets how large the element will be in proportion to the other elements. The default value of flex-grow is 0, so setting flex-grow to larger than 0 will make the element larger than other elements. (You can’t set it to a negative number, though.)
Example 1: Here, we use flex-grow to make one element twice as large as the other. A flex-grow of 2 on one element and 1 on the other element means that the elements will have a 2-to-1 size ratio. Setting one flex-grow to 8 and the other to 4 would do the exact same thing, since 2:1 is the same ratio as 8:4.
#flexbox {
display: flex;
width: 100%;
height: 300px;
border: 1px solid black;
}
#big {
flex-grow: 2;
background-color: lavender;
}
#small {
flex-grow: 1;
background-color: lightblue;
}
<div id="flexbox">
<div id="big">BIG</div>
<div id="small">SMALL</div>
</div>
JSFiddle
Example 2: Here, we set flex-grow on only one element while leaving the other at its default of 0. This makes the element grow to fill as much space as possible. We can use any value for flex-grow and it will work exactly the same, as long as the other element has flex-grow: 0;
#flexbox {
display: flex;
width: 100%;
height: 300px;
border: 1px solid black;
}
#big {
flex-grow: 5;
background-color: lavender;
}
#small {
/* flex-grow is 0 by default */
background-color: lightblue;
}
<div id="flexbox">
<div id="big">BIG</div>
<div id="small">SMALL</div>
</div>
JSFiddle
Flex-shrink
This property works similarly to flex-grow, but the ratio describes how much smaller one element should be than another. Also, the default value is one.
Example: If we set one element’s flex-shrink to 2 and the others' to 1, when the parent element is too small to fit every element comfortably and the children must shrink, that element will shrink more than the other elements.
#flexbox {
display: flex;
width: 100%;
height: 300px;
border: 1px solid black;
}
#flexbox div {
flex-grow: 1;
border: 1px solid purple;
background-color: lavender;
}
#flexbox #small {
flex-shrink: 4;
background-color: lightblue;
}
<div id="flexbox">
<div>NORMAL</div>
<div id="small">SMALL</div>
<div>NORMAL</div>
<div>NORMAL</div>
<div>NORMAL</div>
</div>
JSFiddle
Flex-basis
This property sets the initial size of the element. Its value can be either auto, which sets the initial size automatically, or a number of pixels or other size units (like % or vw, for example.) The default value is auto.
Example: Here, we set most of the elements to have an initial size of 50px and set their flex-grow to 1 so that they will grow to fill the space. However, one element has a flex-basis of 100px, so it will be larger than the other elements. Try resizing the window to see how this example behaves.
#flexbox {
display: flex;
width: 100%;
height: 300px;
border: 1px solid black;
}
#flexbox div {
flex-grow: 1;
flex-basis: 50px;
border: 1px solid purple;
background-color: lavender;
}
#flexbox #large {
flex-basis: 100px;
background-color: lightblue;
}
<div id="flexbox">
<div>NORMAL</div>
<div id="large">LARGE</div>
<div>NORMAL</div>
<div>NORMAL</div>
<div>NORMAL</div>
</div>
JSFiddle
Putting it all together
As we mentioned before, the flex property combines all three of those properties into one. If we wanted to set the flex-grow of an element to 1, the flex-shrink to 2, and the flex-basis to 100px, we could use flex and shorten this:
#child {
flex-grow: 1;
flex-shrink: 2;
flex-basis: 100px;
}
To this:
#child {
flex: 1 2 100px;
}
Flex Property is referring to a shorthand.
Basically it looks like this : flex: <flex-grow> <flex-shrink> <flex-basis>
This refers to how the items work more in a display: flex...
For more on this I would suggest looking at the following links:
W3 Schools
CSS Tricks
MDN
What I want to achieve (but without the media query):
JsFiddle
#media all and (max-width: 600px) {
#wrapper {
flex-wrap:wrap;
height: 100px;
}
.center {
width: 100%;
order: 3;
}
.left{
width: 50%;
}
.right {
width:50%;
order:2;
}
}
I have 3 elements inside a wrapper, all shrinked. At desktop size, there is some space left over, however when I resize my window to a smaller dimension, at some point, elements run out of space. When that happens, I want to put the middle element to the next line. I have a solution, where the third element goes to the next line, and JSFiddle solution, where the second element goes to the next line, but always at the same static width.
So is it possible to put the middle element to the next line, when all three shrinked elements run out of space?
You can definitely wrap the line without media queries by using flex-wrap, flex-grow, flex-shrink and flex-basis to specify a minimum width that any given item should have:
#wrapper{
display: flex;
width: 100%;
height: 50px;
align-items: center;
text-align: center;
flex-wrap: wrap;
}
.right{
width: 20%;
background-color: blue;
order: 3;
flex-grow: 1;
flex-shrink: 0;
flex-basis: 200px;
}
But it's not possible to change the flex-order based solely on whether the elements "fit". For that you definitely need a media query.
I'm trying to make a chat layout. So i have 3 divs, activeUSer - top, messages middle (has to fill the space between 1 and 3), actions - bottom
Now, I've put flex-direction row. and it works fine. I needed the bottom div to grow if the input grows (if you have 2 or more lines of writing)
It worked ok untill I added display:flex to the Actions div (bottom). I needed another flex layout for input and buttons. Now it does not care for the padding i've set on the last div
Here is my codepen https://codepen.io/capraruioan/pen/XKWxrV
#content {
height: 300px;
display: flex;
flex-direction: column;
}
.activeUser {
height: 66px;
background-color: yellow;
}
.Messages {
flex: 1 1 100%;
}
.Actions {
flex-grow: 1;
display: flex;
padding-top: 2px;
padding-bottom: 20px;
}
.aa { //the inputbox
border: 1px solid black;
min-height: 10px
}
fixed it by letting display default on the 3rd div and placing a div with display flex inside
(I'm using Chrome v.39+)
I'm trying to use the flex-wrap property to stack child divs both horizontally and vertically, but I'm seeing some very strange behaviors. For example, if there's 3 child divs and the last is given a width of 100% (causing it to wrap) there will be unwanted gaps introduced.
Sometimes I can force the first 2 divs to honor align-items: stretch by giving them height: 100% or height: calc(100% - 1px), other times they won't stretch passed the mysterious gap, and sometimes they'll even disappear all together if I try to force them to stretch.
Here's a simplified example of the problem. They grey shouldn't be visible.
Why are these gaps appearing in flex-wrapped divs and how can I prevent them?
The gray area is still visible at the bottom because you set a height on the parent container.
If you don't want to see that gray area, remove the height from the container and add a fixed height that you require on one of the elements in the first row
DEMO
.a {
width: 300px;
display: flex;
flex-wrap: wrap;
position: relative;
top: 100px;
left: 200px;
background-color: #999;
}
.b {
height: 150px;
background-color: #00ff00;
}
.c {
background-color: #0000ff;
}
.d {
background-color: #ff0000;
}
.b {
flex-grow: 1;
flex-shrink: 0;
}
.c {
width: 5px;
flex-shrink: 0;
}
.d {
width: 100%;
height: 10px;
flex-shrink: 0;
}
<div class='a'>
<div class='b'></div>
<div class='c'></div>
<div class='d'></div>
</div>
Note: If you want to avoid fixed dimensions - just remove the height:10px from the red div.
This will ensure that there are no gaps and that each row has equal height
DEMO