Reputation:
Given 9 div
s one after another, I want to create a grid 3X3 via CSS.
How do I do that?
.cell {
height: 50px;
width: 50px;
background-color: #999;
display: inline-block;
}
.cell:nth-child(3n) {
background-color: #F00;
/* what property should I use to get a line break after this element? */
}
/* this doesn't work; at least not in safari */
.cell:nth-child(3n)::after {
display: block;
}
<div class="grid">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
Note: I don't want float/clear
solution. Focus is on CSS and not HTML restructure.
If I add content: '\A'; white-space: pre;
to ::after
output comes out to be ugly.
.cell {
height: 50px;
width: 50px;
background-color: #999;
display: inline-block;
}
.cell:nth-child(3n) {
background-color: #F00;
/* what property should I use to get a line break after this element? */
}
.cell:nth-child(3n)::after {
display: inline;
content: '\A';
white-space: pre;
}
<div class="grid">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
How do I go about getting all div in a 3X3 row-column layout?
Upvotes: 31
Views: 79887
Reputation: 19109
02/2022 Update: As David mentioned in the comments, grid-gap
is now deprecated and was replaced with the tidier gap
. I've updated the code snippet below to reflect this.
Now that CSS Grid is fairly very well supported, I thought I'd supplement the other answers with a more modern solution.
.grid {
display: grid;
gap: 1px;
grid-template-columns: repeat(3, 1fr);
}
div > div {
padding: 10px;
background-color: #ccc;
}
<div class="grid">
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
</div>
Upvotes: 45
Reputation: 371221
This layout is simple with CSS flexbox. No changes to HTML.
.grid {
display: flex; /* establish flex container */
flex-wrap: wrap; /* enable flex items to wrap */
justify-content: space-around;
}
.cell {
flex: 0 0 32%; /* don't grow, don't shrink, width */
height: 50px;
margin-bottom: 5px;
background-color: #999;
}
.cell:nth-child(3n) {
background-color: #F00;
}
<div class="grid">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
Benefits of flexbox:
To learn more about flexbox visit:
Browser support:
Flexbox is supported by all major browsers, except IE < 10. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add prefixes use Autoprefixer. More details in this answer.
Upvotes: 27
Reputation: 1165
I know the question is asking for a non-float clear solution, but after trying the flexbox solution I found that it did not preserve the width of my elements (further reading suggests I may have needed to set the width on the container element). In the specific case of a 3x3 grid however (as opposed to a grid with n rows of three) that a float clear solution more concise and works nicely. Here it is in case others find this answer when looking for a solution as I did:
.cell {
float: left;
height: 100px;
width: 100px;
margin: 5px;
}
.cell:nth-child(4) {
clear: left;
}
.cell:nth-child(7) {
clear: left;
}
Upvotes: 0
Reputation: 60563
Besides Excellent answer from @Michael_B to use flexbox
, you can use
CSS tables
or
float:left
both to support old browsers such as IE 8/9 , which flexbox
won't support.
Note IE8 won't support nth-child
but supports first/last-child
.grid {
display: table;
border-spacing: 5px
}
.row {
display: table-row
}
.cell {
width: 50px;
height: 50px;
background: grey;
display: table-cell;
}
.row div:last-child {
background: red
}
<div class="grid">
<div class="row">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
<div class="row">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
<div class="row">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
</div>
float:left
): with NO changes to HTML, using clear:left
at each (4th)n item..cell {
width: 50px;
height: 50px;
background: grey;
float: left;
margin: 5px
}
.cell:first-child + div+ div,
.cell:first-child + div+ div + div + div + div,
.cell:first-child + div+ div + div + div + div + div + div + div {
background: red
}
.cell:first-child + div+ div + div,
.cell:first-child + div+ div + div + div + div + div,
.cell:first-child + div+ div + div + div + div + div + div + div + div {
clear: left
}
<div class="grid">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
Upvotes: 7
Reputation: 12548
Just to add another, you can also make a 3x3 grid using only a single <div>
. Plunker
HTML:
<div class="grid"></div>
CSS:
.grid {
width: 50px; height: 50px;
background-color: red;
border-top: 50px solid red;
border-bottom: 50px solid red;
margin: 0 50px;
position: relative;
box-shadow: inset 0 4px 0 -2px white,
inset 0 -4px 0 -2px white;
}
.grid::before {
content: '';
width: 50px; height: 50px;
background-color: red;
border-top: 50px solid red;
border-bottom: 50px solid red;
margin: 0;
position: absolute; left: -52px; top: -50px;
box-shadow: inset 0 4px 0 -2px white,
inset 0 -4px 0 -2px white;
}
.grid::after {
content: '';
width: 50px; height: 50px;
background-color: red;
border-top: 50px solid red;
border-bottom: 50px solid red;
margin: 0;
position: absolute; right: -52px; top: -50px;
box-shadow: inset 0 4px 0 -2px white,
inset 0 -4px 0 -2px white;
}
Upvotes: 3