5 items per row, auto-resize items in flexbox
You are right in giving a flex-basis: 20%
but you have to adjust for the 4px margin on each flex item for it to wrap properly.
Equal Width Flex items in the last row
Use flex: 0 1 calc(20% - 8px)
- this means the item won't grow beyond 20% of width (adjusting for margin) and can shrink based on the container width. See demo below:
.container {
background: gray;
width: 600px;
height: 200px; /* height given for illustration */
display: flex;
flex-flow: row wrap;
position: relative;
}
.item {
background: blue;
margin: 4px;
flex: 0 1 calc(20% - 8px); /* <-- adjusting for margin */
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Flexbox: 4 items per row
You've got flex-wrap: wrap
on the container. That's good, because it overrides the default value, which is nowrap
(source). This is the reason items don't wrap to form a grid in some cases.
In this case, the main problem is flex-grow: 1
on the flex items.
The flex-grow
property doesn't actually size flex items. Its task is to distribute free space in the container (source). So no matter how small the screen size, each item will receive a proportional part of the free space on the line.
More specifically, there are eight flex items in your container. With flex-grow: 1
, each one receives 1/8 of the free space on the line. Since there's no content in your items, they can shrink to zero width and will never wrap.
The solution is to define a width on the items. Try this:
.parent { display: flex; flex-wrap: wrap;}
.child { flex: 1 0 21%; /* explanation below */ margin: 5px; height: 100px; background-color: blue;}
<div class="parent"> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div></div>
How to change the number of flex items per row with image links?
Added the following css
to your code:
.images-container img {
width: 100%;
}
.images-container>a {
flex: calc(100% / 3);
}
You can adjust the number of images per row by changing the flex
property in .images-container>a
.
Here is the working snippet with newly added css.
* { box-sizing: border-box;}
.container { display: flex; flex-direction: column; margin: 0 auto; padding: 10px;}
input[type="search"] { height: 40px; width: 80%; margin: 30px auto; border: 1px red solid;}
.images-container { display: flex; justify-content: space-evenly; flex-wrap: wrap; border: 1px red solid;}
a { flex: 25%; border: 1px red solid;}
.images-container img { width: 100%;}
.images-container>a { flex: calc(100% / 3);}
<div class=container>
<div class="images-container"> <a href="https://picsum.photos/id/1/150/150" data-lightbox="image-1"><img src="https://picsum.photos/id/1/150/150" alt="Image 1"></a> <a href="https://picsum.photos/id/2/150/150" data-lightbox="image-2"><img src="https://picsum.photos/id/2/150/150" alt="Image 2"></a> <a href="https://picsum.photos/id/3/150/150" data-lightbox="image-3"><img src="https://picsum.photos/id/3/150/150" alt="Image 3"></a> <a href="https://picsum.photos/id/4/150/150" data-lightbox="image-4"><img src="https://picsum.photos/id/4/150/150" alt="Image 4"></a> <a href="https://picsum.photos/id/5/150/150" data-lightbox="image-5"><img src="https://picsum.photos/id/5/150/150" alt="Image 5"></a> <a href="https://picsum.photos/id/6/150/150" data-lightbox="image-6"><img src="https://picsum.photos/id/6/150/150" alt="Image 6"></a> <a href="https://picsum.photos/id/7/150/150" data-lightbox="image-7"><img src="https://picsum.photos/id/7/150/150" alt="Image 7"></a> <a href="https://picsum.photos/id/8/150/150" data-lightbox="image-8"><img src="https://picsum.photos/id/8/150/150" alt="Image 8"></a> <a href="https://picsum.photos/id/9/150/150" data-lightbox="image-9"><img src="https://picsum.photos/id/9/150/150" alt="Image 9"></a> <a href="https://picsum.photos/id/10/150/150" data-lightbox="image-10"><img src="https://picsum.photos/id/10/150/150" alt="Image 10"></a> <a href="https://picsum.photos/id/11/150/150" data-lightbox="image-11"><img src="https://picsum.photos/id/12/150/150" alt="Image 11"></a> <a href="https://picsum.photos/id/12/150/150" data-lightbox="image-12"><img src="https://picsum.photos/id/12/150/150" alt="Image 12"></a> </div>
</div>
How to display 3 items per row in flexbox?
Flex container:
- You probably want to use
display: flex
notinline-flex
. - Add
flex-wrap: wrap
to allow wrapping onto multiple lines. - Remove
width: 33%
if you wish it to take entire space avaiable.
For 3 items per row, add on the flex items:
flex-basis: 33.333333%
- You can also use the
flex
's shorthand like the following:flex: 0 0 33.333333%
=> which also meansflex-basis: 33.333333%
.
.serv ul { display: flex; flex-wrap: wrap; padding-left: 0;}
.serv ul li { list-style: none; flex: 0 0 33.333333%;}
<div class="serv"> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul></div>
Control item count in a row with flexbox
You only need to consider one rule like below:
/*7 = 4 (1st row) + 3 (2nd row) and 5 = 1st element in 2nd row (4 + 1)*/
.grid-wrapper .grid-item:nth-child(7n + 5) {
width: calc(100%/3);
flex-grow:0;
}
The trick is to make one element bigger to trigger the wrap then rely on flex-grow
to fill the space.
Full code
* { box-sizing: border-box;}
.grid-wrapper { display: flex; flex-wrap: wrap; justify-content: center;}
.grid-wrapper .grid-item { width: 25%; text-align: center; padding: 5px; flex-grow: 1;}
.grid-wrapper .grid-item:nth-child(7n + 5) { width: calc(100%/3); flex-grow:0;}
p { background: #ddd; padding: 15px;}
<div class="grid-wrapper"> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div> <div class="grid-item"> <p>Grid Item</p> </div><div class="grid-item"> <p>Grid Item</p> </div></div>
Better way to set distance between flexbox items
- Flexbox doesn't have collapsing margins.
- Flexbox doesn't have anything akin to
border-spacing
for tables (edit: CSS propertygap
fulfills this role in newer browsers, Can I use)
Therefore achieving what you are asking for is a bit more difficult.
In my experience, the "cleanest" way that doesn't use :first-child
/:last-child
and works without any modification on flex-wrap:wrap
is to set padding:5px
on the container and margin:5px
on the children. That will produce a 10px
gap between each child and between each child and their parent.
Demo
.upper {
margin: 30px;
display: flex;
flex-direction: row;
width: 300px;
height: 80px;
border: 1px red solid;
padding: 5px; /* this */
}
.upper > div {
flex: 1 1 auto;
border: 1px red solid;
text-align: center;
margin: 5px; /* and that, will result in a 10px gap */
}
.upper.mc /* multicol test */ {
flex-direction: column;
flex-wrap: wrap;
width: 200px;
height: 200px;
}
<div class="upper">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
<div class="upper mc">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
Arrange 2 items per row using flexbox
You can give flex: 50%
to children div
s without touching .item
.item {
width: 100%
}
.container {
display: flex;
flex-wrap: wrap;
}
.container > div {
flex: 50%; /* or - flex: 0 50% - or - flex-basis: 50% - */
/*demo*/
box-shadow: 0 0 0 1px black;
margin-bottom: 10px;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
Related Topics
Convert a SQL Query Result Table to an HTML Table for Email
Why Does Inline-Block Cause This Div to Have Height
How to Disable the Resize Grabber of <Textarea>
Wait Until an HTML5 Video Loads
How to Change the Opacity (Alpha, Transparency) of an Element in a Canvas Element
How to Make in CSS an Overlay Over an Image
Adding Custom Attribute (Html5) Support to Jsf 2.0 Uiinput Component
What Do <Form Action="#"> and <Form Method="Post" Action="#"> Do
CSS Grid - Maximum Number of Columns Without Media Queries
Heading with Horizontal Line on Either Side
How to Give a CSS Class Priority Over an Id
How to Vertically Center a Bootstrap Carousel-Caption
Why Does My Transform Snap Back
Html5Shiv VS Dean Edwards IE7-Js VS Modernizr - Which to Choose