This question already has answers here:
Targeting flex items on the last or specific row
(10 answers)
Wrapping flex items in the last row [duplicate]
(1 answer)
Closed 3 years ago.
I have a list of items I want to display with CSS. Originally, it was only two items side-by-side on one line but now I want to make it responsive for larger screens so I want to make it display 3 items on one line instead. My old code looks like this with justify-content:space-between. It looks good with an odd number of items to display.
.flex-container-old{
margin-top: 50px;
background: magenta;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.box-old{
width: 40%;
border: 1px solid black;
margin-bottom: 20px;
height: 300px;
background: orange;
}
.wrapper{
margin: 0 auto;
width: 80%;
}
body{
background:#D3D3D3;
}
<div class="wrapper">
<div class="flex-container-old">
<div class="box-old">
</div>
<div class="box-old">
</div>
<div class="box-old">
</div>
<div class="box-old">
</div>
<div class="box-old">
</div>
</div>
</div>
So naturally I extended it to three items in one row by modifying the width property only to end up with the below.
.flex-container-new{
background: lightblue;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.box {
width: 30%;
border: 1px solid black;
margin-bottom: 20px;
height: 300px;
background: orange;
}
.wrapper{
margin: 0 auto;
width: 80%;
}
<div class="wrapper">
<div class="flex-container-new">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
</div>
My problem in the case of the above code with three items on one line is I want the last item in last row to be pushed to the left, aligned with the middle item in the row above it. Sadly bootstrap is not an option. This is for learning purposes. It there a way I can achieve the above with just CSS? Many thanks in advance.
This is easier to control using CSS Grid because we can dictate both the x and y axis. With Flexbox, you can only reliably control the x axis. If you haven't heard about the fr unit, it's defined by Mozilla as follows:
The fr, which is short for “fraction”, is a unit which represents a fraction of the available space in the grid container.
Another nice thing about using Grid is that we can drop the height and margin-bottom set in .box and also the flex-wrap rule. Everything about the layout of this grid, from the height of the cells to the grid-gap spacing between them, is all defined in the parent.
.grid-container-new {
background: lightblue;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 300px);
grid-gap: 20px;
}
.box {
border: 1px solid black;
background: orange;
}
<div class="grid-container-new">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
jsFiddle
Related
This question already has answers here:
Better way to set distance between flexbox items
(40 answers)
Closed 9 months ago.
I'm trying to manipulate divs without using float, using display: inline-block; in my css allows me to get the siblings next to each other within a container div, but with inline-block, I can't space them apart using margin-left: 20px;, margin-right :20px; ... and so on.
I'm sure there's a really simple solution, even if it doesn't involve using display: inline-block;, I just want to avoid floats and preferably avoid padding too.
you can try flex-box method to create space between two div which is inside a div (I conclude that from your question )
.parent{
border:2px solid red;
display:flex;
justify-content:space-around;
}
.parent div{
border:3px solid black;
}
<div class="parent">
<div class="child1">
child1
</div>
<div class="child2">
child2
</div>
</div>
you can also add many child div as you want , they will automatically make place in the parent container.
Here you can see below how i managed to do so without display:inline-block; and this will not break on any device unlike inline-block.
.box {
width: 200px;
height: 200px;
background: #F3F3F3;
color: #000;
display: flex;
align-items: center;
justify-content: center;
margin-left: 20px;
}
.container {
display: flex;
margin-bottom: 40px;
}
.container.two {
justify-content: space-between;
}
.container.three {
justify-content: space-evenly;
}
Margin 20px in between
<div class="container">
<div class="box">
BOX 1
</div>
<div class="box">
BOX 1
</div>
</div>
Align boxes on left and right according to width
<div class="container two">
<div class="box">
BOX 1
</div>
<div class="box">
BOX 1
</div>
</div>
Align even spacing on left and right
<div class="container three">
<div class="box">
BOX 1
</div>
<div class="box">
BOX 1
</div>
</div>
This question already has answers here:
Expand a div to fill the remaining width
(21 answers)
Closed 1 year ago.
I'm trying to make the last grid item fill all empty columns in a css grid that has auto-fit for wrapping items.
I've read Expand a div to fill the remaining width and Make last element take remaining width with wrapping (and with IE9 support), but they don't answer the case of the dynamically wrapping grid that is here the important part since they are made for float and display: block.
So for example if the grid-item is wrapped in a new line i want it to stretch for taking all the empty space.
If you look at the code then the div number 7 should always take all the empty space in the row. I've managed to hack something which dosen't seem robust enough, using 100vw is there a better way?
For the following example: resize the window to see the items wrap into the next lines:
* {
box-sizing: border-box;
}
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
.grid-element {
background-color: deepPink;
padding: 20px;
color: #fff;
border: 1px solid #fff;
}
.grid-element:last-of-type {
/*width: 100vw;*/ /* Is there a better way? */
}
body {
padding: 2em;
}
hr {
margin: 80px;
}
<div class="grid-container">
<div class="grid-element">
1
</div>
<div class="grid-element">
2
</div>
<div class="grid-element">
3
</div>
<div class="grid-element">
4
</div>
<div class="grid-element">
5
</div>
<div class="grid-element">
6
</div>
<div class="grid-element">
7
</div>
</div>
It can be achieved with display: flex. In addition, it is necessary to use flex-grow property.
As mdn says about flex-grow:
The flex-grow CSS property sets the flex grow factor of a flex item's
main size
* {
box-sizing: border-box;
}
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-element {
width: 10%;
border: 1px solid #000;
flex-grow: 1;
min-height: 120px;
box-sizing: border-box;
margin: 0 5px 10px;
justify-content: space-between;
text-align: center;
}
<div class="flex-container">
<div class="flex-element">
1
</div>
<div class="flex-element">
2
</div>
<div class="flex-element">
3
</div>
<div class="flex-element">
4
</div>
<div class="flex-element">
5
</div>
<div class="flex-element">
6
</div>
<div class="flex-element">
7
</div>
</div>
I am using grid. I centered my items but i want left position to be same on cross axis.
.box {
display: grid;
grid-template-columns: 1fr;
padding: 10px;
border: 1px solid blue;
gap: 1rem;
justify-items: center;
}
img {
width: 200px;
}
<div class="box">
<img src="img/featured.jpg">
<div class="item2">Item 2 Lorem</div>
</div>
Note : i want solution in only grid. There is many temporary fixes for that but i don't want that because i am looking for a perfect standard grid alignment solution for it.
You can do it a few ways:
1. Fixed Width Text (Not Responsive)
Based on the information you gave in your question. you can simply set the width of the item2 div to be the same as the image, e.g.:
.box {
display: grid;
grid-template-columns: 1fr;
padding: 10px;
border: 1px solid blue;
gap: 1rem;
justify-items: center;
}
.item2,
img {
width: 200px;
}
<div class="box">
<img src="https://via.placeholder.com/200x150">
<div class="item2">Item 2 Lorem</div>
</div>
2. The Responsive Way
This will allow us to responsively set up the 2 separate alignments you require: centre the container element, and left-align its contents, e.g.
<div class="box">
<div class="boxcontent">
Content here...
</div>
</div>
CSS: .boxcontent { text-align: left; }
Why this works:
You must have a defined relationship between the image and text, otherwise there is no way to tell the grid that these 2 individual elements must be positioned in relation to each other. You can do this by putting them in a container.
If you think about it, you are trying to do 2 separate alignments here:
make the image and text be centred in relation to the grid but also
make them be in alignment with each other so they are left aligned.
Putting them in a container achieves both of these objectives by creating a relationship between the image and text so that:
they act as a single unit in relation to the grid and also
allow them to be positioned in relation to each other regardless of the grid
Working Example:
.box {
display: grid;
grid-template-columns: 1fr;
padding: 10px;
border: 1px solid blue;
gap: 1rem;
justify-items: center;
}
.boxcontent {
text-align: left;
}
img {
width: 200px;
}
<div class="box">
<div class="boxcontent">
<img src="https://via.placeholder.com/200x150">
<div class="item2">Item 2 Lorem</div>
</div>
</div>
.box {
display: block;
margin: 0 auto;
width: max-content;
padding: 10px;
border: 1px solid blue;
}
img {
width: 200px;
}
.item2 {
margin-top: 1rem;
}
<div class="box">
<img src="pic_trulli.jpg" alt="Hi dear">
<div class="item2">Item 2 Lorem</div>
</div>
This question already has answers here:
Is it possible for flex items to align tightly to the items above them?
(5 answers)
Closed 3 years ago.
As the picture describes, I want to wrap items as such.
This is my current HTML and CSS.
<div class="column-container">
<div class="col item">1 <- More text and thus taller than the other ones</div>
<div class="col item">2</div>
<div class="col item">3</div>
<div class="col item">4</div>
<div class="col item">5</div>
</div>
.column-container {
display: flex;
justify-content: center;
flex-flow: row wrap;
height: 100%;
}
.item {
height: fit-content;
min-width: 300px;
max-width: 300px;
margin: 10px;
}
Here's a fiddle as well..
https://jsfiddle.net/3Ly5zh4n/1
Flexbox is probably not the best choice for this since flexbox is used to display content next to each other either vertical or horizontal. I'd suggest using CSS Grid instead. It might be a new area for some, but it's a quite good choice for handling columns in CSS.
The following is an example of how it can be used. The method repeat(auto-fill, ...) fills the whole container with either a full fraction for each element, or the minimum width of 150px, which should be 300px in your case.
.column-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-template-rows: 1fr 1fr;
grid-gap: 10px;
height: 300px;
}
.item {
display: flex;
justify-content: center;
align-items: center;
font-size: 36px;
color: white;
background-color: red;
}
.item--first {
grid-row: 1 / span 2;
}
<div class="column-container">
<div class="item item--first">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
I'd suggest reading css tricks A Complete Guide to Grid for further information. Hope this helps a bit.
.column-container {
display: flex;
flex-flow: row wrap;
height: 100%;
}
.item {
height: fit-content;
min-width: 150px;
max-width: 150px;
margin: 10px;
border: 1px solid black;
}
<div style="display: flex;justify-content: center">
<div class="column-container">
<div class="col item" style="height: 100px;">1 <- More text and thus taller than the other ones</div>
</div>
<div class="column-container">
<div class="col item">2</div>
<div class="col item">3</div>
<div class="col item">4</div>
<div class="col item">5</div>
</div>
</div>
I think this this will do what you want. Its a simpler approach but it behaves the way you explain in your requested image.
HTML:
<div>
<ul>
<!-- I have set the height of this li to 300px to demo the concept. -->
<li class="col item" style="height: 300px">
1 More text and thus taller than the other ones.
</li>
<li class="col item">2</li>
<li class="col item">3</li>
<li class="col item">4</li>
<li class="col item">5</li>
</ul>
</div>
CSS:
ul {
padding: 0;
}
ul .item {
list-style: none;
float: left;
height: 100px;
width: 300px;
margin: 10px;
border: 1px solid red;
}
This should give you a result of:
Result layout
Hope this helps...
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>