Reorder columns in reverse order - css

I have a list of flex items within a flexbox. The order of the items matter, and for accessibility purposes, the items need to show up in the correct order in the dom.
[[itema][itemb][itemc]]
When the flexbox shrinks I would like to have the items wrap in reverse order, e.g. itema wraps first, etc. Is there any way to have the itema wrap first? Thanks!
Edit:
Here is the code
<div class="flex">
<div class="container">
<div class="item">item1</div>
<div class="item orange">item2</div>
<div class="item blue">item3</div>
</div>
<div class="last-item green">menu</div>
</div>
.flex {
display: flex;
background-color: yellow;
height: 80px;
overflow: hidden;
color: #fff;
}
.container {
display: flex;
flex: 1 1 auto;
flex-wrap: wrap;
}
.item {
flex: 0 0 auto;
background-color: red;
height: 80px;
padding: 0 40px;
}
.last-item {
width: 40px;
flex: 0 0 auto;
height: 80px;
}
JSFiddle
All the behavior is as desired except I want the first item to wrap first. Any ideas? Thanks!

You can use the flex-direction: column-reverse to get your solution.
#media (max-width: 768px) {
.flex-box {
display: flex;
flex-direction: column-reverse;
}
}
.first,
.second,
.third {
display: inline-block;
}
<div class="flex-box">
<div class="first">
<p>First Box</p>
<img src="http://placehold.it/300x300" />
</div>
<div class="second">
<p>Second Box</p>
<img src="http://placehold.it/300x300" />
</div>
<div class="third">
<p>Third Box</p>
<img src="http://placehold.it/300x300" />
</div>
</div>
JSfiddle Demo

To make item1 wrap first, you can use flex-wrap: wrap-reverse on your flex container.
Try this simplified version of you code:
<div class="container">
<div class="item">item1</div>
<div class="item orange">item2</div>
<div class="item blue">item3</div>
</div>
.container {
display: flex;
flex: 0 1 auto;
flex-wrap: wrap-reverse;
}
.item {
background-color: red;
height: 80px;
padding: 0 40px;
}
.orange {
background-color: orange;
}
.blue {
background-color: blue
}
See the MDN reference for browser support.

Related

Positioning of elements in a flex layout [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I need help laying out my html with css flexbox (I hope this is doable with flexbox).
I have a Container with a variable amount of images. Image can be either landscape or portrait orientation. If image is landscape (Image 1) - it will occupy one 'row'. If image is portrait - there are two cases:
If there is one portrait image in a 'row' (either it's the last image, or the next one is landscape) - then Image 2 should be centered on the 'row'.
If there are two successive portrait images - I'd like them to both fit into one 'row'
Pls note, that the 'rows' are an abstract notion here. I don't want to use css grid (unless there are absolutely no other options).
Using a flexbox in combination with the justify-content: center; and flex-wrap: wrap; should achieve the exact effect you are looking for.
Please see the two code snippets below for the two examples. I have used multiple coloured div with a width and height to simulate the horizontal and vertical image types you referred to.
.flex {
display: flex;
flex-wrap: wrap;
width: 100px;
border: 2px black solid;
padding: 1em;
justify-content: center;
}
.horizontal {
background: yellow;
width: 100px;
height: 50px;
margin-bottom: 1em;
}
.vertical {
background: green;
width: 50px;
height: 100px;
}
<div class="flex">
<div class="horizontal">Image 1</div>
<div class="vertical">Image 2</div>
</div>
.flex {
display: flex;
flex-wrap: wrap;
width: 100px;
border: 2px black solid;
padding: 1em;
justify-content: center;
}
.horizontal {
background: yellow;
width: 100px;
height: 50px;
margin-bottom: 1em;
}
.vertical {
background: green;
width: 50px;
height: 100px;
}
#blue {
background: blue;
}
<div class="flex">
<div class="horizontal">Image 1</div>
<div class="vertical">Image 2</div>
<div class="vertical" id="blue">Image 3</div>
</div>
This can be done with align-items: center and flex-wrap:wrap:
.flex{
width: 220px;
display:flex;
align-items: center;
flex-wrap:wrap;
}
.flex img{
border: solid 4px #efefef;
box-sizing:border-box;
margin: 0 auto;
}
<h3>Example 1</h3>
<div class="flex">
<img src="https://placekitten.com/220/60">
<img src="https://placekitten.com/110/120">
</div>
<h3>Example 2</h3>
<div class="flex">
<img src="https://placekitten.com/220/60">
<img src="https://placekitten.com/100/120">
<img src="https://placekitten.com/100/120">
</div>
You can easily achieve this using the same grid system as Bootstrap using class like container, row, col:
.container {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.align-center {
align-items: center;
justify-content: center;
}
.image1 {
width: 500px;
height: 300px;
background-color: red;
}
.image2,
.image3 {
width: 250px;
height: 500px;
}
.image2 {
background-color: yellow;
}
.image3 {
background-color: blue;
}
.image1,
.image2,
.image3 {
border: solid #000 2px;
}
<div class="container align-center">
<div class="row">
<div class="col image1">
<h1>image1</h1>
</div>
</div>
<div class="row align-center">
<div class="col image2">
<h1>image2</h1>
</div>
</div>
</div>
<div class="container align-center">
<div class="row">
<div class="col image1">
<h1>image1</h1>
</div>
</div>
<div class="row align-center">
<div class="col image2">
<h1>image2</h1>
</div>
<div class="col image3">
<h1>image3</h1>
</div>
</div>
</div>

how to correctly make flex-box children to scroll

I'm stuck and can't make content to correctly scroll while facing a few of nested flex-boxes. Here is my css:
html,body,#root{
width:100%;
height:100%;
padding:0;
margin:0;
}
.flex-fill{
height:100%;
width:100%;
display:flex;
align-items:stretch;
}
.flex-fill>div:last-child{
flex-grow:1;
}
.flex-col{
flex-direction:column;
}
<div id='root'>
<div class='flex-fill flex-col'><!--actually scrolling div-->
<div style="flex:0 0 35px"><h1>main title</h1></div>
<div>
<div class='flex-fill flex-col'>
<div style="flex:0 0 30px"><h2>subtitle</h2></div>
<div class='flex-fill'>
<div style="flex:0 0 30%">...left side nav list...</div>
<div class='flex-fill flex-col'>
<div style="flex:0 0 25px">...data header...</div>
<!--I hope the content of this div is scroll-able-->
<div style="overflow-y:scroll">...data list...</div>
</div>
</div>
</div>
</div>
</div>
</div>
The data list contained in the inner most div is very long and I want to make it scrollable. But in the fact the above codes make whole content of the root div scrolling. Have I misunderstanding about flex or overflow? How can I fix the other parts and just scroll the data list?
Answer updated to keep your HTML structure the same. Inline styles removed and added as classes:
html,body{
height:100%;
padding:0;
margin:0;
}
#root {
height: 100%;
display: flex;
}
.flex-fill{
height:100%;
display:flex;
align-items:stretch;
}
.flex-col{
flex-direction:column;
display: flex;
flex: 1 0 0;
height: 100%;
}
.flex-row{
flex-direction:row;
display: flex;
height: 100%;
}
.scrolling-div {
height: 100%;
overflow-y: scroll;
}
<div id='root'>
<div class='flex-fill flex-col'>
<div><h1>main title</h1></div>
<div class="flex-col">
<div class='flex-col'>
<div><h2>subtitle</h2></div>
<div class="flex-row">
<div>...left side nav list...</div>
<div class='flex-col'>
<div>...data header...</div>
<!--Now Scrolls-->
<div class="scrolling-div">
...scrolling data list...<br />
...scrolling data list...<br />
...scrolling data list...<br />
...scrolling data list...<br />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
#Welson Zhong, please have a look at the below working snippet, please look it in Full page view, hope it helps now :)
note: too much flex kills flex ;) that was the issue with your code.
html, body {
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
font-family: sans-serif;
font-size: 18px;
}
.main {
display: flex;
flex-direction: row;
flex: 1 0 auto;
}
.sidebar {
flex: 1 auto;
}
.content {
display: flex;
flex-flow: column nowrap;
flex: 3 0px;
}
h1,h2,.data-header {
flex: none;
}
/* below css is for visual purpose only */
.main *:not(.content) {
box-shadow: inset 0 0 0 1px #ccc;
padding: 10px;
}
<h1>main title</h1>
<h2>sub title</h2>
<div class="main">
<div class="sidebar">
...left side nav list...
</div>
<div class="content">
<div class="data-header">...data header...</div>
<div style="overflow-y:scroll; flex: auto">...data list...</div>
</div>
</div>

Flexbox not working properly on chrome

I'm using the following code to display 5 images (without the use of background) distributed evenly across a container and with an equal height equivalent to the tallest image (although I wonder if it would be possible to do this with the shortest one). Applying flex: 1; on the image-container gives me the desired effect under firefox, but under chrome the 5 images appear vertically stretched and oversized. The desired effect is to keep every container filled under a given width while minimizing loss of aspect ratio.
Edit: I've loaded this page under both browsers and I do get the effect I wanted although they are rendered differently. Now I need to find what's wrong with my version compared to the one I posted here.
body {
width: 300px;
}
.container {
display: flex;
flex-wrap: wrap;
height: 100%;
width: 100%;
background-color: black;
}
.row1 {
display: flex;
width: 100%;
background-color: blue;
}
.column {
height: 100%;
width: 20%;
display: flex;
flex-flow: column;
position: relative;
background-color: red;
}
.image-container {
overflow: hidden;
display: flex;
flex: 1;
background-color: yellow;
}
img {
width: 100%;
height: auto;
}
.image-label {
width: 100%;
height: 35px;
display: flex;
background-color: green;
justify-content: center;
}
.row2 {
display: flex;
width: 100%;
flex-flow: row wrap;
background-color: cyan;
height: 20px;
}
<div class="container">
<div class="row1">
<div class="column">
<div class="image-container">
<img src="http://www.koka.ac.jp/admission/wp-content/themes/admission/assets/img/common/floating-btn-internet.gif">
</div>
<div class="image-label">img1</div>
</div>
<div class="column">
<div class="image-container">
<img src="http://www.moglix.com/themes/et_poostyle/img/offer.jpg">
</div>
<div class="image-label">img2</div>
</div>
<div class="column">
<div class="image-container">
<img src="http://i.imgur.com/slhFy4T.png">
</div>
<div class="image-label">img3</div>
</div>
<div class="column">
<div class="image-container">
<img src="http://alma-sys.com/images/SLIDE%20MENU%20IMG/WEB%20D%20-%20Copy.jpg">
</div>
<div class="image-label">img4</div>
</div>
<div class="column">
<div class="image-container">
<img src="http://amerpages.com/app/webroot/img/items/121/16716/pds/19682_s.jpg">
</div>
<div class="image-label">img5</div>
</div>
</div>
<div class="row2"></div>
</div>

How can I make flexbox wrap only an even number of items? [duplicate]

Is there a way to make a line break in multiple line flexbox?
For example to break after each 3rd item in this CodePen.
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
height: 100px;
background: gold;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px;
}
.item:nth-child(3n) {
background: silver;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
Like
.item:nth-child(3n){
/* line-break: after; */
}
The simplest and most reliable solution is inserting flex items at the right places. If they are wide enough (width: 100%), they will force a line break.
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px
}
.item:nth-child(4n - 1) {
background: silver;
}
.line-break {
width: 100%;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="line-break"></div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="line-break"></div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="line-break"></div>
<div class="item">10</div>
</div>
But that's ugly and not semantic. Instead, we could generate pseudo-elements inside the flex container, and use order to move them to the right places.
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px
}
.item:nth-child(3n) {
background: silver;
}
.container::before, .container::after {
content: '';
width: 100%;
order: 1;
}
.item:nth-child(n + 4) {
order: 1;
}
.item:nth-child(n + 7) {
order: 2;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
But there is a limitation: the flex container can only have a ::before and a ::after pseudo-element. That means you can only force 2 line breaks.
To solve that, you can generate the pseudo-elements inside the flex items instead of in the flex container. This way you won't be limited to 2. But those pseudo-elements won't be flex items, so they won't be able to force line breaks.
But luckily, CSS Display L3 has introduced display: contents (currently only supported by Firefox 37):
The element itself does not generate any boxes, but its children and
pseudo-elements still generate boxes as normal. For the purposes of
box generation and layout, the element must be treated as if it had
been replaced with its children and pseudo-elements in the document
tree.
So you can apply display: contents to the children of the flex container, and wrap the contents of each one inside an additional wrapper. Then, the flex items will be those additional wrappers and the pseudo-elements of the children.
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
display: contents;
}
.item > div {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px;
}
.item:nth-child(3n) > div {
background: silver;
}
.item:nth-child(3n)::after {
content: '';
width: 100%;
}
<div class="container">
<div class="item"><div>1</div></div>
<div class="item"><div>2</div></div>
<div class="item"><div>3</div></div>
<div class="item"><div>4</div></div>
<div class="item"><div>5</div></div>
<div class="item"><div>6</div></div>
<div class="item"><div>7</div></div>
<div class="item"><div>8</div></div>
<div class="item"><div>9</div></div>
<div class="item"><div>10</div></div>
</div>
Alternatively, according to an old version of the spec, Flexbox allowed forced breaks by using break-before, break-after or their old CSS 2.1 aliases:
.item:nth-child(3n) {
page-break-after: always; /* CSS 2.1 syntax */
break-after: always; /* CSS 3 syntax */
}
But these forced line breaks only work on Firefox, and I don't think they are supposed to work according to the current spec. The new proposed way (not implemented anywhere) is with wrap-before or wrap-after:
.item:nth-child(3n) {
wrap-after: flex; /* New proposed syntax */
}
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px
}
.item:nth-child(3n) {
page-break-after: always;
break-after: always;
wrap-after: flex;
background: silver;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
From my perspective it is more semantic to use <hr> elements as line breaks between flex items.
.container {
display: flex;
flex-flow: wrap;
}
.container hr {
width: 100%;
}
<div class="container">
<div>1</div>
<div>2</div>
<hr>
<div>3</div>
<div>2</div>
...
</div>
Tested in Chrome 66, Firefox 60 and Safari 11.
#Oriol has an excellent answer, sadly as of October 2017, neither display:contents, neither page-break-after is widely supported, better said it's about Firefox which supports this but not the other players, I have come up with the following "hack" which I consider better than hard coding in a break after every 3rd element, because that will make it very difficult to make the page mobile friendly.
As said it's a hack and the drawback is that you need to add quite a lot of extra elements for nothing, but it does the trick and works cross browser even on the dated IE11.
The "hack" is to simply add an additional element after each div, which is set to display:none and then used the css nth-child to decide which one of this should be actually made visible forcing a line brake like this:
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.item {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px
}
.item:nth-child(3n-1) {
background: silver;
}
.breaker {
display: none;
}
.breaker:nth-child(3n) {
display: block;
width: 100%;
height: 0;
}
<div class="container">
<div class="item">1</div>
<p class="breaker"></p>
<div class="item">2</div>
<p class="breaker"></p>
<div class="item">3</div>
<p class="breaker"></p>
<div class="item">4</div>
<p class="breaker"></p>
<div class="item">5</div>
<p class="breaker"></p>
<div class="item">6</div>
<p class="breaker"></p>
<div class="item">7</div>
<p class="breaker"></p>
<div class="item">8</div>
<p class="breaker"></p>
<div class="item">9</div>
<p class="breaker"></p>
<div class="item">10</div>
<p class="breaker"></p>
</div>
You want a semantic linebreak?
Then consider using <br>. W3Schools may suggest you that BR is just for writing poems (mine is coming soon) but you can change the style so it behaves as a 100% width block element that will push your content to the next line. If 'br' suggests a break then it seems more appropriate to me than using hr or a 100% div and makes the html more readable.
Insert the <br> where you need linebreaks and style it like this.
// Use `>` to avoid styling `<br>` inside your boxes
.container > br
{
width: 100%;
content: '';
}
You can disable <br> with media queries, by setting display: to block or none as appropriate (I've included an example of this but left it commented out).
You can use order: to set the order if needed too.
And you can put as many as you want, with different classes or names :-)
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.item {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px
}
.container > br
{
width: 100%;
content: '';
}
// .linebreak1
// {
// display: none;
// }
// #media (min-width: 768px)
// {
// .linebreak1
// {
// display: block;
// }
// }
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<br class="linebreak1"/>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
No need to limit yourself to what W3Schools says:
I think the traditional way is flexible and fairly easy to understand:
Markup
<div class="flex-grid">
<div class="col-4">.col-4</div>
<div class="col-4">.col-4</div>
<div class="col-4">.col-4</div>
<div class="col-4">.col-4</div>
<div class="col-4">.col-4</div>
<div class="col-4">.col-4</div>
<div class="col-3">.col-3</div>
<div class="col-9">.col-9</div>
<div class="col-6">.col-6</div>
<div class="col-6">.col-6</div>
</div>
Create grid.css file:
.flex-grid {
display: flex;
flex-flow: wrap;
}
.col-1 {flex: 0 0 8.3333%}
.col-2 {flex: 0 0 16.6666%}
.col-3 {flex: 0 0 25%}
.col-4 {flex: 0 0 33.3333%}
.col-5 {flex: 0 0 41.6666%}
.col-6 {flex: 0 0 50%}
.col-7 {flex: 0 0 58.3333%}
.col-8 {flex: 0 0 66.6666%}
.col-9 {flex: 0 0 75%}
.col-10 {flex: 0 0 83.3333%}
.col-11 {flex: 0 0 91.6666%}
.col-12 {flex: 0 0 100%}
[class*="col-"] {
margin: 0 0 10px 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#media (max-width: 400px) {
.flex-grid {
display: block;
}
}
I've created an example (jsfiddle)
Try to resize the window under 400px, it's responsive!!
I just want to throw this answer in the mix, intended as a reminder that – given the right conditions – you sometimes don't need to overthink the issue at hand. What you want might be achievable with flex: wrap and max-width instead of :nth-child.
ul {
display: flex;
flex-wrap: wrap;
justify-content: center;
max-width: 420px;
list-style-type: none;
background-color: tomato;
margin: 0 auto;
padding: 0;
}
li {
display: inline-block;
background-color: #ccc;
border: 1px solid #333;
width: 23px;
height: 23px;
text-align: center;
font-size: 1rem;
line-height: 1.5;
margin: 0.2rem;
flex-shrink: 0;
}
<div class="root">
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
<li>F</li>
<li>G</li>
<li>H</li>
<li>I</li>
<li>J</li>
<li>K</li>
<li>L</li>
<li>M</li>
<li>N</li>
<li>O</li>
<li>P</li>
<li>Q</li>
<li>R</li>
<li>S</li>
<li>T</li>
<li>U</li>
<li>V</li>
<li>W</li>
<li>X</li>
<li>Y</li>
<li>Z</li>
</ul>
</div>
https://jsfiddle.net/age3qp4d/
Another possible solution that doesn't require to add any extra markup is to add some dynamic margin to separate the elements.
In the case of the example, this can be done with the help of calc(), just adding margin-left and margin-right to the 3n+2 element (2, 5, 8)
.item:nth-child(3n+2) {
background: silver;
margin: 10px calc(50% - 175px);
}
Snippet Example
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
height: 100px;
background: gold;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px;
}
.item:nth-child(3n+2) {
background: silver;
margin: 10px calc(50% - 175px);
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
For future questions, It's also possible to do it by using float property and clearing it in each 3 elements.
Here's an example I've made.
.grid {
display: inline-block;
}
.cell {
display: inline-block;
position: relative;
float: left;
margin: 8px;
width: 48px;
height: 48px;
background-color: #bdbdbd;
font-family: 'Helvetica', 'Arial', sans-serif;
font-size: 14px;
font-weight: 400;
line-height: 20px;
text-indent: 4px;
color: #fff;
}
.cell:nth-child(3n) + .cell {
clear: both;
}
<div class="grid">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell">6</div>
<div class="cell">7</div>
<div class="cell">8</div>
<div class="cell">9</div>
<div class="cell">10</div>
</div>
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
height: 100px;
background: gold;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px;
}
<div class="container">
<div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
<div class="item">10</div>
</div>
you could try wrapping the items in a dom element like here. with this you dont have to know a lot of css just having a good structure will solve the problem.

flexbox vertical align child top, center another

I've got the following markup:
.row {
display: flex;
align-items: stretch;
margin: -16px;
background: #ddd;
}
.row .col {
display: flex;
flex-direction: column;
justify-content: center;
flex: 1;
margin: 16px;
background: #fff;
}
.header, .content, .footer {
padding: 16px;
background: red;
}
<div class="row">
<div class="col">
<div class="header">Header #1</div>
<div class="content">Lorem Ipsum<br />Dolor<br />Sit Amet</div>
<div class="footer">Footer</div>
</div>
<div class="col">
<div class="header">Header #2</div>
<div class="content">Lorem Ipsum<br />Dolor</div>
</div>
</div>
Unfortunatly the second header isn't align vertically to the top. Is there a way to archive this with flexbox? I need the ".header" to be aligned the the top and the ".content" to be centered within the rest of the box.
Greetings!
No, not really, not without another wrapper which is a flex-container.
As flexbox is, to a certain extent based on manipulting margins, there is no method (AFAIK, although I'd be interested to find out if there is) to justify-content: center and then align-self a child element to somewhere else other than center.
I'd go with something like this: Add a wrapper to the "content" div, give it flex:1 to fill the remaining space below the header, then make that wrapper display:flex with justify-content:center.
This seems to be the most logical method
.col {
height: 150px;
width: 80%;
margin: 1em auto;
border: 1px solid grey;
display: flex;
flex-direction: column;
}
.header {
background: lightblue;
}
.content {
background: orange;
}
.flexy {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
background: plum;
}
<div class="col">
<div class="header">Header #2</div>
<div class="flexy">
<div class="content">Lorem Ipsum
<br />Dolor</div>
</div>
</div>
Codepen Demo
Flexbox opens up all sorts of opportunities with margin: auto; this is one of them. Setting margin to auto along the flex axis (vertical in this case) will absorb any extra space before dividing it up between the flex items. Finally it's possible to vertically center stuff without creating a div soup.
.row {
display: flex;
align-items: stretch;
margin: -16px;
background: #ddd;
}
.row .col {
display: flex;
flex-direction: column;
flex: 1;
margin: 16px;
background: #fff;
}
.header, .content, .footer {
padding: 16px;
background: red;
}
.content {
margin-top: auto;
margin-bottom: auto;
}
<div class="row">
<div class="col">
<div class="header">Header #1</div>
<div class="content">Lorem Ipsum<br />Dolor<br />Sit Amet</div>
<div class="footer">Footer</div>
</div>
<div class="col">
<div class="header">Header #2</div>
<div class="content">Lorem Ipsum<br />Dolor</div>
</div>
</div>

Resources