This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Why are flex items not wrapping?
(2 answers)
Closed 1 year ago.
I am doing some exercises to learn how flexbox works, and there is something that is bugging me and I would like to know how this works. For some reason, when I apply display:flex; to my container, when I reduce the screen size the elements go out of the div as you can see in this picture.
This one here is the mobile view, look how the border dissapears:
.box {
color: white;
font-size: 60px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, .1);
}
.box1 {
background-color: rgb(0, 118, 57);
}
.box2 {
background-color: blueviolet;
}
.box3 {
background-color: chartreuse;
}
.box4 {
background-color: darkgoldenrod;
}
.box5 {
background-color: darkolivegreen;
}
.box6 {
background-color: dodgerblue;
}
.box7 {
background-color: greenyellow;
}
.box8 {
background-color: mediumseagreen;
}
.box9 {
background-color: orange;
}
.box10 {
background-color: steelblue;
}
.container {
display: flex;
border: 7px solid black;
margin: 22px 10px;
width: 80%;
}
.box {
flex: 1;
width: 50%;
padding: 20px;
/* flex-flow: row wrap; */
/* margin: 22px; */
}
<body>
<div class="container">
<div class="box box1">one 👌</div>
<div class="box box2">two 😒</div>
<div class="box box3">three 😁</div>
<div class="box box4">four 🏙</div>
<div class="box box5">five 💪</div>
<div class="box box6">six 😂</div>
<!-- <div class="box box7">7</div> -->
<!-- <div class="box box8">8</div> -->
<!-- <div class="box box9">9</div> -->
<!-- <div class="box box10">10</div> -->
</div>
</body>
How Can I prevent this from happening? I have tried using percentage width and also properties as flex shrink, but there are no changes.
Please note that when you use flex mode, especially in mobile size, you have to control the size of the children, but this is not done and you have a very large size of the children in the font size. The solution is to use media query to control this.
#media screen and (max-width: 678px) {
.box {
flex: 1 1 16%;
font-size: 15px;
}
.container{
width:100%;
}
}
if you want the child elements to wrap, use flex-wrap: wrap; in the parent element.
.container{
display: flex;
flex-wrap: wrap;
}
use flex-wrap to wrap.
.container {
...
flex-wrap: wrap;
}
.box {
color: white;
font-size: 60px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, .1);
}
.box1 {
background-color: rgb(0, 118, 57);
}
.box2 {
background-color: blueviolet;
}
.box3 {
background-color: chartreuse;
}
.box4 {
background-color: darkgoldenrod;
}
.box5 {
background-color: darkolivegreen;
}
.box6 {
background-color: dodgerblue;
}
.box7 {
background-color: greenyellow;
}
.box8 {
background-color: mediumseagreen;
}
.box9 {
background-color: orange;
}
.box10 {
background-color: steelblue;
}
.container {
display: flex;
border: 7px solid black;
margin: 22px 10px;
width: 80%;
flex-wrap: wrap;
}
.box {
flex: 1;
width: 50%;
padding: 20px;
/* flex-flow: row wrap; */
/* margin: 22px; */
}
<body>
<div class="container">
<div class="box box1">one 👌</div>
<div class="box box2">two 😒</div>
<div class="box box3">three 😁</div>
<div class="box box4">four 🏙</div>
<div class="box box5">five 💪</div>
<div class="box box6">six 😂</div>
<!-- <div class="box box7">7</div> -->
<!-- <div class="box box8">8</div> -->
<!-- <div class="box box9">9</div> -->
<!-- <div class="box box10">10</div> -->
</div>
</body>
Related
I can't touch the HTML file and the non-grey items should not change it's position
I'm trying to have the .grey item be at the bottom of the other 4 items. I know there is another question very similar to this one but they are working with columns and I'm not so none of the answers there helped me.
.red {
background-color: #900;
}
.green {
background-color: #090;
}
.blue {
background-color: #00F;
}
.purple {
background-color: #63C;
}
.grey {
background-color: #666;
}
.container {
background-color: #FFF;
width: 50%;
height: 70%;
min-height: 400px;
margin: auto;
border: 2px solid black;
}
.container {
display: flex;
flex-wrap: wrap-reverse;
justify-content: space-between;
}
.item {
width: 45%;
margin-bottom: 5%;
margin-left: 2%;
margin-right: 2%;
margin-top: 0;
}
.item:last-child {
width: 100%;
}
<div class="container">
<div class="item red"></div>
<div class="item green"></div>
<div class="item blue"></div>
<div class="item purple"></div>
<div class="item grey"></div>
</div>
I need the grey rectangle to be on the bottom
You can add order to the item. It will align wherever you want.
<div class="container">
<div class="item red"></div>
<div class="item green"></div>
<div class="item blue"></div>
<div class="item purple"></div>
<div class="item grey"></div>
</div>
.red { background-color: #900; }
.green { background-color: #090; }
.blue { background-color: #00F; }
.purple { background-color: #63C; }
.grey { background-color: #666; }
.container {
background-color: #FFF;
width: 50%;
height: 70%;
min-height: 400px;
margin: auto;
border: 2px solid black;
}
.container {
display: flex;
flex-wrap: wrap-reverse;
justify-content: space-between;
}
.item {
width: 45%;
margin-bottom: 5%;
margin-left: 2%;
margin-right: 2%;
margin-top: 0;
}
.item:last-child{
width: 100%;
order: -1; // It will make this item as first. Since it is reversed, this will be the last.
}
you can easily do it with add an order to .grey class
.grey{
order: -1;
width: 100%;
}
because it's justify-content is wrap-reverse ,
in the case you use wrap , you can add order: 1; or higher.
If You want to have div class .item grey on the bottom, In this specific case, You have to change flex-wrap: wrap-reverse to flex-wrap: wrap that's it ;-) Best regards !
.red { background-color: #900; }
.green { background-color: #090; }
.blue { background-color: #00F; }
.purple { background-color: #63C; }
.grey { background-color: #666; }
.container {
background-color: #FFF;
width: 50%;
height: 70%;
min-height: 400px;
margin: auto;
border: 2px solid black;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item {
width: 45%;
margin-bottom: 5%;
margin-left: 2%;
margin-right: 2%;
margin-top: 0;
}
.item:last-child{
width: 100%;
}
<div class="container">
<div class="item red"></div>
<div class="item green"></div>
<div class="item blue"></div>
<div class="item purple"></div>
<div class="item grey"></div>
</div>
I'm trying to learn CSS Flexbox and found an impediment.
I have content that displays right and left on desktop screen sizes and for mobile, I have flex-direction: column
See the visual bellow:
Desktop:
Mobile:
This is the code to accomplish such:
<div class="container">
<div class="box box1">
<div class="a">a</div>
<div class="b">b</div>
</div>
<div class="box box2">
<div class="c">c</div>
<div class="d">d</div>
</div>
</div>
These are the flexbox styles:
.box {
color: white;
font-size: 100px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
width: 100vw;
}
.container {
display: flex;
height: 100vh;
}
.a, .b, .c, .d {
height: 50%;
}
#media all and (max-width: 500px) {
.container {
flex-direction: column;
}
.box {
height: 50vh;
}
}
When in mobile, how can I order the following divs to be displayed in columns (as is) however on the following order:
a
c
d
b
I can't seem to find a solution for that unfortunately.
I have a CodePen here the CSS lines that matter are from line 162 onward.
You can consider display:contents (https://caniuse.com/#feat=css-display-contents) on the .box element then you will be able to use order on the inner elements:
.box {
color: white;
font-size: 80px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
width: 100vw;
}
body {
margin:0;
}
.container {
display: flex;
height: 100vh;
background:blue;
}
.a,.b,.c,.d {
height: 50%;
border:2px solid;
}
#media all and (max-width: 500px) {
.container {
flex-direction: column;
}
.box {
display:contents;
}
.b {
order:2;
}
}
<div class="container">
<div class="box box1">
<div class="a">a</div>
<div class="b">b</div>
</div>
<div class="box box2">
<div class="c">c</div>
<div class="d">d</div>
</div>
</div>
display: contents causes an element's children to appear as if they were direct children of the element's parent, ignoring the element itself. This can be useful when a wrapper element should be ignored when using CSS grid or similar layout techniques.
If you are open to change the html you can do it like below:
.container > * {
color: white;
font-size: 80px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
border:2px solid;
box-sizing:border-box;
}
body {
margin:0;
}
.container {
display: flex;
flex-direction:column;
flex-wrap:wrap;
height: 100vh;
background:blue;
padding:10px;
box-sizing:border-box;
}
.a,.b,.c,.d {
height: 50%;
width:50%;
}
#media all and (max-width: 500px) {
.a,.b,.c,.d {
width:100%;
height:25%;
}
.b {
order:2;
}
}
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
<div class="d">d</div>
</div>
And with CSS grid:
.container > * {
color: white;
font-size: 80px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
box-sizing:border-box;
border:2px solid;
}
body {
margin:0;
}
.container {
display: grid;
grid-template-areas:
'a b'
'c d';
grid-template-columns:1fr 1fr;
grid-template-rows:1fr 1fr;
grid-gap:10px;
min-height: 100vh;
background:blue;
padding:10px;
box-sizing:border-box;
}
.a {
grid-area:a;
}
.b {
grid-area:b;
}
.c {
grid-area:c;
}
.d {
grid-area:d;
}
#media all and (max-width: 500px) {
.container {
grid-template-areas:
'a'
'c'
'd'
'b';
grid-template-columns:1fr;
grid-template-rows:1fr 1fr 1fr 1fr;
}
}
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
<div class="d">d</div>
</div>
If you order your divs as .a & .c in .box1 and .c & .d in .box 2, you can use column in .container for desktop, and column in .box in mobile + order within .box2:
.box {
color: white;
font-size: 100px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
width: 100vw;
display: flex; /* <-- */
}
.container {
display: flex;
height: 100vh;
flex-direction: column; /* <-- */
}
.a, .b, .c, .d {
height: 50%;
}
#media all and (max-width: 500px) {
.box {
height: 50vh;
flex-direction: column; /* <-- */
}
.box2 .d {
order: 0; /* <-- */
}
}
<div class="container">
<div class="box box1">
<div class="a">a</div>
<div class="c">c</div>
</div>
<div class="box box2">
<div class="b">b</div>
<div class="d">d</div>
</div>
</div>
Nuri Katsuki's comment is right. If the "abcd" divs are on the same level, you can use CSS order property to achieve the order you want on mobile.
Also, the flex-wrap: wrap makes the children flow into columns on desktop query
I've edited your sample to illustrate it:
.container {
color: white;
font-size: 100px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
width: 100vw;
display: flex;
height: 100vh;
flex-direction: column;
flex-wrap: wrap;
}
.a { background:#e67e22;}
.b { background:#e74c3c;}
.c { background:#9b59b6;}
.d { background:#34495e;}
.a, .b, .c, .d {
height: 50%;
width: 50%;
}
#media all and (max-width: 500px) {
.container {
height: auto;
}
.a, .b, .c, .d { width: 100%; }
.b {
order: 3;
}
}
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
<div class="d">d</div>
</div>
/* Some default styles to make each box visible */
html,body {
padding: 0;
margin: 0;
}
.container {
color: white;
font-size: 100px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
width: 100vw;
display: flex;
height: 100vh;
align-items: stretch;
flex-direction: column;
flex-wrap: wrap;
}
.a { background:#e67e22;}
.b { background:#e74c3c;}
.c { background:#9b59b6;}
.d { background:#34495e;}
.a, .b, .c, .d {
height: 50%;
width: 50%;
}
#media all and (max-width: 500px) {
.container {
height: auto;
}
.a, .b, .c, .d { width: 100%; }
.b {
order: 3;
}
}
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
<div class="d">d</div>
</div>
I'm trying to learn CSS Flexbox and found an impediment.
I have content that displays right and left on desktop screen sizes and for mobile, I have flex-direction: column
See the visual bellow:
Desktop:
Mobile:
This is the code to accomplish such:
<div class="container">
<div class="box box1">
<div class="a">a</div>
<div class="b">b</div>
</div>
<div class="box box2">
<div class="c">c</div>
<div class="d">d</div>
</div>
</div>
These are the flexbox styles:
.box {
color: white;
font-size: 100px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
width: 100vw;
}
.container {
display: flex;
height: 100vh;
}
.a, .b, .c, .d {
height: 50%;
}
#media all and (max-width: 500px) {
.container {
flex-direction: column;
}
.box {
height: 50vh;
}
}
When in mobile, how can I order the following divs to be displayed in columns (as is) however on the following order:
a
c
d
b
I can't seem to find a solution for that unfortunately.
I have a CodePen here the CSS lines that matter are from line 162 onward.
You can consider display:contents (https://caniuse.com/#feat=css-display-contents) on the .box element then you will be able to use order on the inner elements:
.box {
color: white;
font-size: 80px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
width: 100vw;
}
body {
margin:0;
}
.container {
display: flex;
height: 100vh;
background:blue;
}
.a,.b,.c,.d {
height: 50%;
border:2px solid;
}
#media all and (max-width: 500px) {
.container {
flex-direction: column;
}
.box {
display:contents;
}
.b {
order:2;
}
}
<div class="container">
<div class="box box1">
<div class="a">a</div>
<div class="b">b</div>
</div>
<div class="box box2">
<div class="c">c</div>
<div class="d">d</div>
</div>
</div>
display: contents causes an element's children to appear as if they were direct children of the element's parent, ignoring the element itself. This can be useful when a wrapper element should be ignored when using CSS grid or similar layout techniques.
If you are open to change the html you can do it like below:
.container > * {
color: white;
font-size: 80px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
border:2px solid;
box-sizing:border-box;
}
body {
margin:0;
}
.container {
display: flex;
flex-direction:column;
flex-wrap:wrap;
height: 100vh;
background:blue;
padding:10px;
box-sizing:border-box;
}
.a,.b,.c,.d {
height: 50%;
width:50%;
}
#media all and (max-width: 500px) {
.a,.b,.c,.d {
width:100%;
height:25%;
}
.b {
order:2;
}
}
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
<div class="d">d</div>
</div>
And with CSS grid:
.container > * {
color: white;
font-size: 80px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
box-sizing:border-box;
border:2px solid;
}
body {
margin:0;
}
.container {
display: grid;
grid-template-areas:
'a b'
'c d';
grid-template-columns:1fr 1fr;
grid-template-rows:1fr 1fr;
grid-gap:10px;
min-height: 100vh;
background:blue;
padding:10px;
box-sizing:border-box;
}
.a {
grid-area:a;
}
.b {
grid-area:b;
}
.c {
grid-area:c;
}
.d {
grid-area:d;
}
#media all and (max-width: 500px) {
.container {
grid-template-areas:
'a'
'c'
'd'
'b';
grid-template-columns:1fr;
grid-template-rows:1fr 1fr 1fr 1fr;
}
}
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
<div class="d">d</div>
</div>
If you order your divs as .a & .c in .box1 and .c & .d in .box 2, you can use column in .container for desktop, and column in .box in mobile + order within .box2:
.box {
color: white;
font-size: 100px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
width: 100vw;
display: flex; /* <-- */
}
.container {
display: flex;
height: 100vh;
flex-direction: column; /* <-- */
}
.a, .b, .c, .d {
height: 50%;
}
#media all and (max-width: 500px) {
.box {
height: 50vh;
flex-direction: column; /* <-- */
}
.box2 .d {
order: 0; /* <-- */
}
}
<div class="container">
<div class="box box1">
<div class="a">a</div>
<div class="c">c</div>
</div>
<div class="box box2">
<div class="b">b</div>
<div class="d">d</div>
</div>
</div>
Nuri Katsuki's comment is right. If the "abcd" divs are on the same level, you can use CSS order property to achieve the order you want on mobile.
Also, the flex-wrap: wrap makes the children flow into columns on desktop query
I've edited your sample to illustrate it:
.container {
color: white;
font-size: 100px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
width: 100vw;
display: flex;
height: 100vh;
flex-direction: column;
flex-wrap: wrap;
}
.a { background:#e67e22;}
.b { background:#e74c3c;}
.c { background:#9b59b6;}
.d { background:#34495e;}
.a, .b, .c, .d {
height: 50%;
width: 50%;
}
#media all and (max-width: 500px) {
.container {
height: auto;
}
.a, .b, .c, .d { width: 100%; }
.b {
order: 3;
}
}
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
<div class="d">d</div>
</div>
/* Some default styles to make each box visible */
html,body {
padding: 0;
margin: 0;
}
.container {
color: white;
font-size: 100px;
text-align: center;
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);
width: 100vw;
display: flex;
height: 100vh;
align-items: stretch;
flex-direction: column;
flex-wrap: wrap;
}
.a { background:#e67e22;}
.b { background:#e74c3c;}
.c { background:#9b59b6;}
.d { background:#34495e;}
.a, .b, .c, .d {
height: 50%;
width: 50%;
}
#media all and (max-width: 500px) {
.container {
height: auto;
}
.a, .b, .c, .d { width: 100%; }
.b {
order: 3;
}
}
<div class="container">
<div class="a">a</div>
<div class="b">b</div>
<div class="c">c</div>
<div class="d">d</div>
</div>
I have a simple nav type layout using flex to space items with different widths horizontally. The items have lines between but as they different heights because the content had different heights
How can I make the items the height of the parent so all dividing lines go to the top of the parent.
https://codepen.io/anon/pen/zbEMVd
* {
font-family: sans-serif;
}
.wrap {
border: 1px solid grey;
display: flex;
padding: 5px;
justify-content: space-between;
max-width: 1200px;
}
.item:not(:last-of-type) {
border-right: 2px solid red;
}
.item-1 {
width: 150px;
}
.item-2 {
width: 50px;
}
.item-3 {
width: 50px;
}
.item-4 {
width: 50px;
}
.item-5 {
flex: 1;
}
.item-6 {
width: 50px;
}
<div class="wrap">
<div class="item item-1">One</div>
<div class="item item-2">Two Two Two Two Two </div>
<div class="item item-3">Three Three Three</div>
<div class="item item-4">Four</div>
<div class="item item-5">Five</div>
<div class="item item-6">Six</div>
</div>
Remove align-self from .item, and add display:flex; align-items: flex-end; instead.
.item{
display: flex;
align-items: flex-end;
/* ... */
}
https://codepen.io/anon/pen/ZPXVra
Make the item element a reverse-column flexbox (and remove align-self: flex-end from it) to get the effect - see demo below:
* {
font-family: sans-serif;
}
.wrap {
border: 1px solid grey;
display: flex;
padding: 5px;
justify-content: space-between;
max-width: 1200px;
}
.item {
/* align-self: flex-end; */
display: flex; /* ADDED */
flex-direction: column-reverse; /* ADDED */
background: #ddd;
}
.item:not(:last-of-type) {
border-right: 2px solid red;
}
.item-1 {
width: 150px;
}
.item-2 {
width: 50px;
}
.item-3 {
width: 50px;
}
.item-4 {
width: 50px;
}
.item-5 {
flex: 1;
}
.item-6 {
width: 50px;
}
<div class="wrap">
<div class="item item-1">One</div>
<div class="item item-2">Two Two Two Two Two </div>
<div class="item item-3">Three Three Three</div>
<div class="item item-4">Four</div>
<div class="item item-5">Five</div>
<div class="item item-6">Six</div>
</div>
I'm new to flexbox and I created the following in order to have a top-navigation, with three columns below the top-navigation. When I open my HTML file the top-navigation is 80px tall but the three columns are only 50%, less the 80px for the header. I don't understand what is going on? Should the three columns not just fill in the difference?
body {
font: 24px Helvetica;
background: #999999;
}
.layout {
min-height: 100vh;
display: flex;
flex-flow: row;
flex-wrap: wrap;
}
.top-navigation {
width: 100vw;
height: 80px;
background: #cc2936;
}
.left-sidebar {
width: 25%;
background: #dcdcdc;
flexgrow: 1;
}
.main-outlet {
width: 50%;
background: #ffffff;
flexgrow: 1;
}
.right-sidebar {
width: 25%;
background: #dcdcdc;
flexgrow: 1;
}
<div class="layout">
<div class="box top-navigation"></div>
<div class="box left-sidebar"></div>
<div class="box main-outlet"></div>
<div class="box right-sidebar"></div>
</div>
I think you need to change your layout a little bit. You can then set the wrapping div to have flex-direction: column and align-content: stretchto the three columns like this:
body {
font: 24px Helvetica;
background: #999999;
margin: 0;
}
.layout {
min-height: 100vh;
display: flex;
flex-direction: column;
flex-flow: row;
flex-wrap: wrap;
align-content: stretch;
}
.top-navigation {
width: 100vw;
height: 80px;
background: #cc2936;
}
.left-sidebar {
width: 25%;
background: #dcdcdc;
}
.main-outlet {
width: 50%;
background: #ffffff;
}
.right-sidebar {
width: 25%;
background: #dcdcdc;
}
<div class="box top-navigation"></div>
<div class="layout">
<div class="box left-sidebar"></div>
<div class="box main-outlet"></div>
<div class="box right-sidebar"></div>
</div>