I have a container with items inside it.
This container has a height set. I'd like to wrap the items inside this container to a new column by maintaining the order of them to the next column. How do I do this?
For example, if I have 5 items, I'd like to wrap them like this:
1 4
2 5
3
and not like
1 2
3 4
5
Here is a photo for a reference:
From this photo, I'd like to create a new column with the 11th and 12th item
You can use flexbox with flex-direction: column:
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
max-height: 20rem;
width: 20rem;
border: 1px solid black;
padding: 5px;
gap: 5px;
}
.item {
font-size: 5rem;
border: 1px solid black;
text-align: center;
}
<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>
Related
This question already has answers here:
How can I show three columns per row?
(4 answers)
Closed 1 year ago.
I am looking for a way (with Flexbox, not Grid) to create a layout, when I have a container with x cards inside, and each card inside should take 1/3 of the container width. So cards number 1,2,3 will be in the first row, cards number 4,5... in the second row etc.
I feel like it is impossible with flexbox, I don't wanna do some checks for number of items, I used map to map cards in containers of max 3 cards but I didn't like the solution. Before I move to using grid, I would love to get some insight if it is possible to acomplish with Flexbox.
The code is:
<div class="container">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
you should set box-sizing: border-box; on the cards so padding and borders are calculated in their width. and set their max-width: 33.33%.
body {
padding: 30px;
margin: 0;
}
.container {
display: flex;
flex-direction: row;
width: 100%;
flex-wrap: wrap;
background: orange;
}
.card {
box-sizing: border-box;
width: 100%;
text-align: center;
max-width: 33.33%;
padding: 50px 0;
background-color: aqua;
border: 1px solid #000;
}
<div class="container">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
</div>
The difference will be for the second row. There are two options for the last two element width.
Option 1 Last two nodes take 33% width only and leave the right side blank.
You have to use display: flex; flex-wrap: wrap; for .container and display: flex; flex: 0 1 33%; for the child element, which is .card.. Here flex-shrink is to be set for child
.container {
display: flex;
flex-wrap: wrap;
}
.card {
height: 100px;
display: flex;
flex: 0 1 33%;
justify-content: center;
align-items: center;
font-size: 50px;
}
<div class="container">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
</div>
Option 2 Last two element use 50% width each.
You have to use display: flex; flex-wrap: wrap; for container and display: flex; flex: 1 0 33%; to the child element, which is .card. Here flex-grow is to be set for child
.container {
display: flex;
flex-wrap: wrap;
}
.card {
height: 100px;
display: flex;
flex: 1 0 33%;
justify-content: center;
align-items: center;
font-size: 50px;
}
<div class="container">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
</div>
Flex-wrap can help you with that
.container{
display: flex;
flex-wrap: wrap;
}
.card{
min-width: 33.3333%;
}
Example here: https://codepen.io/jriches/pen/WNjVaav
Use 33.33333333% width in your card class.
My goal is to get the section looking like this:
(https://i.gyazo.com/7dd160aeadd2ed2c5f696e9cfd5158e3.png)
This is what my current code is giving me:
(https://i.gyazo.com/1fb61e98783f823f3bd003d1ffec3bf8.png)
I'm a beginner and struggle laying laying out sections. How would i get the my current code to give me what i want in the my goal image. Thanks.
My HTML for the image section
<div class="mid-section">
<div class="left-side">
<img src="340h.png" alt="">
</div>
<div class="right-side">
<img src="160hx140.png" alt="">
<img src="160hx140.png" alt="">
<img src="160hx140.png" alt="">
<img src="160hx140.png" alt="">
</div>
</div>
My CSS for the image section:
.mid-section{
width: 760px;
background-color: gray;
display: flex;
align-items: center;
justify-content: center;
margin: auto;
}
.right-side, .left-side{
justify-content: space-around;
}
.left-side img{
width:350px;
height:280px;
margin-top: 0;
}
.right-side img{
width:165px;
height:135px;
margin: 0px 20px 20px 0px;
}
.right-side{
width: 380px;
align-items: center;
justify-content: center;
}
.left-side{
width: 380px;
align-items: center;
justify-content: center;
}
CSS-grid is good for this. I simplified your HTML a bit for brevity...
HTML
<div class="mid-section">
<img src="340h.png" alt="">
<img src="160hx140.png" alt="">
<img src="160hx140.png" alt="">
<img src="160hx140.png" alt="">
<img src="160hx140.png" alt="">
</div>
CSS
.mid-section {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
grid-column-gap: 1em;
grid-row-gap: 1em;
}
.mid-section img:first-child {
grid-row-start: 1;
grid-row-end: span 2;
}
img {
border: red solid 1px;
min-height: 100px;
}
Everything you need to know about grid: https://css-tricks.com/snippets/css/complete-guide-grid/#prop-grid-column-row
Here's a basic example using CSS Grid which implements the layout you're after. I don't need to specify the grid placement for .item1 (the large image) because the placement is implicit. Also note that I use display: inline-grid, so that the width of the overall grid is as wide as the content that fills it, not 100% of the row.
.grid {
display: inline-grid;
grid-template-columns: 350px repeat(3, 1fr);
grid-template-rows: 135px 135px;
grid-gap: 10px;
}
.item2, .item4 {
grid-column: 2 / 3;
}
.item3, .item5 {
grid-column: 3 / 4;
}
<div class="grid">
<img class="item1" src="http://placekitten.com/350/280" alt="">
<img class="item2" src="http://placekitten.com/165/135" alt="">
<img class="item3" src="http://placekitten.com/165/135" alt="">
<img class="item4" src="http://placekitten.com/165/135" alt="">
<img class="item5" src="http://placekitten.com/165/135" alt="">
</div>
jsFiddle
First I'd recommend reading:
Introduction to the CSS basic box model
Next we need to break down what it is we are trying to achieve. It's typically easiest to break down a layout by rows and columns and do any spacing between elements last. Since there is an image that spans across two rows, to me, it would be easier to start with a columns. I'm starting with a border to help visually see if the layout is working as intended.
| Col 1 | Col 2 | Col 3 |
To Achieve this with flexbox:
div {
border: 2px solid blue;
}
div > div {
border: 2px solid red;
}
.d-flex {
display: flex;
}
.flex-row {
flex-direction: row;
}
<div class="d-flex flex-row">
<div> Col 1 </div>
<div> Col 2 </div>
<div> Col 3 </div>
</div>
Now we can break down columns into rows for the additional spaces required:
| Col 1 | Col 2 Row 1 | Col 3 Row 1 |
| Col 1 | Col 2 Row 2 | Col 3 Row 2 |
div {
border: 1px solid blue;
}
div > div {
border: 2px solid red;
}
div > div > div {
border: 3px solid green;
}
.d-flex {
display: flex;
}
.flex-row {
flex-direction: row;
}
.flex-column {
flex-direction: column;
}
<div class="d-flex flex-row">
<div> Col 1 </div>
<div class="d-flex flex-column">
<div> Col 2 Row 1</div>
<div> Col 2 Row 2</div>
</div>
<div class="d-flex flex-column">
<div> Col 3 Row 1</div>
<div> Col 3 Row 2</div>
</div>
</div>
Here are some assumptions Ill work against since they were not included at the time I wrote this answer; the spacing between these elements and the container elements is all the same, and we are not trying to dynamically change the images sizes to be scaled as the window grows or shrinks (we won't resize the images to fit in the space allocated, they are of a static size).
Basically My Opinion of Margins vs Padding:
Margins - When you want to separate elements from each other.
Padding - When you want the contents of your elements to be separated from the elements border.
There are many subtle differences between the two which I won't go over here. Another advantage of margins in this scenario is that we only need to apply them to the inner most containers. Since we are in a flexbox model we need to do some semi-tricky stuff to get the margins to all align correctly.
div {
border: 1px solid blue;
}
div > div {
border: 2px solid red;
}
div > div > div {
border: 3px solid green;
}
.d-flex {
display: flex;
}
.flex-row {
flex-direction: row;
}
.flex-column {
flex-direction: column;
}
.m-20 {
margin: 20px;
}
.mtr-20 {
margin: 20px 20px 0 0;
}
.mtrb-20 {
margin: 20px 20px 20px 0;
}
<div class="d-flex flex-row">
<div class="m-20"> Col 1 </div>
<div class="d-flex flex-column">
<div class="mtr-20"> Col 2 Row 1</div>
<div class="mtrb-20"> Col 2 Row 2</div>
</div>
<div class="d-flex flex-column">
<div class="mtr-20"> Col 3 Row 1</div>
<div class="mtrb-20"> Col 3 Row 2</div>
</div>
</div>
Now we can see that all the borders are lining up as needed. Now we can remove the border and insert any images and see if everything will work as intended.
.d-flex {
display: flex;
}
.flex-row {
flex-direction: row;
}
.flex-column {
flex-direction: column;
}
.m-20 {
margin: 20px;
}
.mtr-20 {
margin: 20px 20px 0 0;
}
.mtrb-20 {
margin: 20px 20px 20px 0;
}
<div class="d-flex flex-row">
<div class="m-20"><img src="https://via.placeholder.com/150x220.png"/></div>
<div class="d-flex flex-column">
<div class="mtr-20"><img src="https://via.placeholder.com/150x100.png"/></div>
<div class="mtrb-20"><img src="https://via.placeholder.com/150x100.png"/></div>
</div>
<div class="d-flex flex-column">
<div class="mtr-20"><img src="https://via.placeholder.com/150x100.png"/></div>
<div class="mtrb-20"><img src="https://via.placeholder.com/150x100.png"/></div>
</div>
</div>
Now we notice that the images aren't quite aligned even though we've been very careful to get it pixel perfect. This is because images are display: inline by default and you can read all about those affects on the question Image inside div has extra space below the image.
So instead of inline we'll set them to flex.
.d-flex {
display: flex;
}
.flex-row {
flex-direction: row;
}
.flex-column {
flex-direction: column;
}
.m-20 {
margin: 20px;
}
.mtr-20 {
margin: 20px 20px 0 0;
}
.mtrb-20 {
margin: 20px 20px 20px 0;
}
img {
display: flex;
}
<div class="d-flex flex-row">
<div class="m-20"><img src="https://via.placeholder.com/150x220.png"/></div>
<div class="d-flex flex-column">
<div class="mtr-20"><img src="https://via.placeholder.com/150x100.png"/></div>
<div class="mtrb-20"><img src="https://via.placeholder.com/150x100.png"/></div>
</div>
<div class="d-flex flex-column">
<div class="mtr-20"><img src="https://via.placeholder.com/150x100.png"/></div>
<div class="mtrb-20"><img src="https://via.placeholder.com/150x100.png"/></div>
</div>
</div>
I have a row and a grid inside a container:
CSS:
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.main-grid {
display: grid;
justify-content: center;
}
HTML:
<div class="container">
<div class="row">
// inputs here
</div>
<div class="main-grid">
<div class="grid-children animated fadeIn" *ngFor="let project of projects">
// grid children here
</div>
</div>
</div>
It currently looks like this(actual grid content blacked out):
So there is a row with a filter above and the grid below, both are centered as defined in the container.
But i would like only the grid to be centered and the row above start at the left side of the grid. So it should look like this:
Resized it would look like this:
I would like to know whether there is a way to center the grid below and tell the row above to start at the left side of the grid below, i was not able to do that by playing around with a container and as far as i know there is also no way to get the x-coordinate of an element which i could use to get the x-coordinate of the grid and apply it to the row.
From my testing i was only able to either center both or make both start at the left side. If i made the row start at the left side and center the grid, then the x-coordinate of the rowstart wouldnt align with the one form the grid(cause its centered).
Just define the row width as 100% and than align it to left
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.row{
width: 100%;
align-self: left;
}
<div class="container">
<div class="row"><!--form--></div>
<div class="center_content"><!--grid--></div>
</div>
I did a few changes, The .container needs to be a flex container and the .main-grid can also be made into a flex-based container.
This can be done as follows
The .container is a column direction flex-box.
The .main-grid is a row based flex-box.
snippets:
Html:
<div class="container">
<div class="row">
inputs
</div>
<div class="main-grid">
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
<div style="height:100px;min-width:80px;max-width:100px;background-color:black;border: 1px solid white; flex: 1 1 auto;"></div>
</div>
</div>
Css:
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
padding: 15px;
}
.main-grid {
justify-content: center;
display: flex;
flex-wrap: wrap;
}
Here is a working demo for the same.
This question already has answers here:
Equal height flex items in flex columns
(3 answers)
Closed 5 years ago.
I'm using flex to create even columns and vh to make them the same height. That's working fine but inside the columns I can have an x number of items in them. I'd like for elements in each column to be even height depending on how many items are present (using css).
1 = 100%
2 = 50%
3 = 33.33%
etc.
I know I can do this through JS but I'd like to automate this through css via flex, grid, or something elese.
I've tried replicating your problem. Use flex: 1 on .items so that each and every item take equal space (according to the problem statement).
Have a look at the snippet below:
body {
margin: 0;
}
.parent {
width: 80%;
padding: 20px;
display: flex;
border: 1px solid red;
}
.child {
flex: 1;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: flex-end;
padding: 20px;
border: 1px solid blue;
height: 60vh;
}
.item {
flex: 1;
background: lightGreen;
border: 1px solid green;
}
<div class="parent">
<div class="child">
<div class="item">33.33%</div>
<div class="item">33.33%</div>
<div class="item">33.33%</div>
</div>
<div class="child">
<div class="item">50%</div>
<div class="item">50%</div>
</div>
<div class="child">
<div class="item">100%</div>
</div>
</div>
Hope this is what you are trying to achieve.
This is all you need to make it work with the Flexbox:
.flex-container {
display: flex;
}
.flex-item {
display: flex;
flex-direction: column;
flex: 1;
}
.item {
flex: 1;
border: 1px solid;
}
<div class="flex-container">
<div class="flex-item">
<div class="item">1/1</div>
</div>
<div class="flex-item">
<div class="item">1/2</div>
<div class="item">1/2</div>
</div>
<div class="flex-item">
<div class="item">1/3</div>
<div class="item">1/3</div>
<div class="item">1/3</div>
</div>
<div class="flex-item">
<div class="item">1/4</div>
<div class="item">1/4</div>
<div class="item">1/4</div>
<div class="item">1/4</div>
</div>
</div>
I have a container of items with the following style:
.container-ok {
display: flex;
flex: 0 1 auto;
flex-direction: column;
align-items: flex-end;
}
.container-error {
display: flex;
flex: 0 1 auto;
flex-direction: column;
justify-content: flex-end;
}
.item {
width: 3rem;
border: 1px black solid;
}
<div class="container-ok">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="container-error">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
I'm expecting that all the items in the container are rendered in one column and are on the right side, but it's not working. When I remove flex-direction, it works but I have as example 3 items and they are in a row (3 columns) not one column. If I remove justify-content and replace it with align-items, it works. But align-items is for vertical alignment.
What am I doing wrong?
thank you
If I understood you right, you want to achieve this result
HTML
<div class="container-ok">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="container-error">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
CSS
.container-ok {
display: flex;
flex: 0 1 auto;
justify-content: flex-end;
}
.container-error {
display: flex;
flex: 0 1 auto;
justify-content: flex-end;
}
.item {
width: 3rem;
border: 1px black solid;
}
Also there is a nice guide to flexbox, maybe it will help you
Justify content declaration works because it defines the alignment along the main axis. Instead justify content not work because It defines the default behaviour for how flex items are laid out along the cross axis on the current line. You can think of it as the justify-content version for the cross-axis (perpendicular to the main-axis).