CSS Grid - Number of Columns Can Be Different in the First Row Than Second Row

Can I have a varying number of columns per row in a CSS grid?

If your rows have varying numbers of cells that aren't all laid out on a single two-dimensional (row and column) space, you don't have a grid. A grid by definition contains a fixed number of rows and columns, and cells that span one or more of each. Maybe you'd have multiple heterogeneous grids, one per row, but that just defeats the whole point of grids, really.

If your varying number of rows is symmetrical or follows some kind of pattern, you can follow Michael_B's suggestion of building a grid based on a common denominator and populating the grid areas mosaic-style. This is just about as non-trivial as a flexbox solution currently would be, but once more browsers implement flexbox fragmentation, flexbox should become the obvious choice over grid as it ought to be.

CSS Grid - Number of Columns can be different in the first row than second row

This is what I wanted actually.

section {  display: grid;  grid-template-columns: repeat(3, 1fr);  grid-gap: 5px;}
div { height: 50px; background: red;}div:first-child { grid-column: 1 / 3;}
<section>  <div>1</div>  <div>2</div>  <div>3</div>  <div>4</div>  <div>5</div>  <div>6</div>  <div>7</div>  <div>8</div></section>

Equal height rows in CSS Grid Layout

Short Answer

If the goal is to create a grid with equal height rows, where the tallest cell in the grid sets the height for all rows, here's a quick and simple solution:

  • Set the container to grid-auto-rows: 1fr

How it works

Grid Layout provides a unit for establishing flexible lengths in a grid container. This is the fr unit. It is designed to distribute free space in the container and is somewhat analogous to the flex-grow property in flexbox.

If you set all rows in a grid container to 1fr, let's say like this:

grid-auto-rows: 1fr;

... then all rows will be equal height.

It doesn't really make sense off-the-bat because fr is supposed to distribute free space. And if several rows have content with different heights, then when the space is distributed, some rows would be proportionally smaller and taller.

Except, buried deep in the grid spec is this little nugget:

7.2.3. Flexible Lengths: the fr
unit

...

When the available space is infinite (which happens when the grid
container’s width or height is indefinite), flex-sized (fr) grid tracks are
sized to their contents while retaining their respective proportions.

The used size of each flex-sized grid track is computed by determining
the max-content size of each flex-sized grid track and dividing that
size by the respective flex factor to determine a “hypothetical 1fr
size”.

The maximum of those is used as the resolved 1fr length (the
flex fraction), which is then multiplied by each grid track’s flex
factor to determine its final size.

So, if I'm reading this correctly, when dealing with a dynamically-sized grid (e.g., the height is indefinite), grid tracks (rows, in this case) are sized to their contents.

The height of each row is determined by the tallest (max-content) grid item.

The maximum height of those rows becomes the length of 1fr.

That's how 1fr creates equal height rows in a grid container.


Why flexbox isn't an option

As noted in the question, equal height rows are not possible with flexbox.

Flex items can be equal height on the same row, but not across multiple rows.

This behavior is defined in the flexbox spec:

6. Flex Lines

In a multi-line flex container, the cross size of each line is the minimum size necessary to contain the flex items on the line.

In other words, when there are multiple lines in a row-based flex container, the height of each line (the "cross size") is the minimum height necessary to contain the flex items on the line.

Different column size on each row (Grid)

This is not possible, the idea of css grid is to have a "grid", that is all the rows follow the same column configuration.

What you can do however is have an element span several column, and here you have several options:

This one stretches from the first column to the first from the end

div:nth-child(3) {
grid-column: 1 / -1;
}

This one spans 2 columns from the first one:

div:nth-child(3) {
grid-column: 1 / span 2;
}

Using CSS Grid, Can you have Row 1 Full and Row 2 Auto-Fit?

You might be able to make it easier to handle if you use grid-template-areas.

<!DOCTYPE html>
<html>
<head>
<style>

.property_field.woo_loop_listing {
grid-area: title;
background-color: #e9c8ec;
}
.item2 {
grid-area: left;
background-color: #8aff33 !important;
}
.item3 {
grid-area: middle;
background-color: #fff1ec !important;;
}
.item4 {
grid-area: right;
background-color: #1cecec !important;;
}

.grid-container {
display: grid;
grid-template-areas:
"title title title"
"left middle right";
padding: 10px;
}

.grid-container > div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
</style>
</head>
<body>
<div class="grid-container">
<div class="property_field woo_loop_listing">Street Address, Town, ZIP CODE</div>
<div class="item2">House</div>
<div class="item3">4 Bed</div>
<div class="item4">2 Bath</div>
</div>
</body>
</html>

CSS grid control items number on each row

If you want to use grid, you will need to start from a number of columns that can be divide into each of items per row requireement.

Here 3,4 and 5 can divide 60.

#container {
display: flex;
align-items: center;
justify-content: center;
border:solid;
}

#innerContainer {
display: grid;
grid-template-columns: repeat(60, 1fr);
margin:-30px;
}

.item {
min-width: 90px;
width: calc(100% - 60px);/* remove the gap */
background-color: blue;
margin: 30px;/* set the gutter here */
grid-column: auto / span 15;
display: flex;
}

.item:before {
content: '';
padding-top: 100%;
flex-basis: 0%;
}

.item:nth-child(4)~.item {
grid-column: auto / span 12
}

.item:nth-child(9)~.item {
grid-column: auto / span 20
}
<div id="container">
<div id="innerContainer">
<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 class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>

Take half width in 3 columns CSS grid layout

You can create a 6 columns grid, and set grid-column: auto / span 3; for the first two elements and auto / span 2 for the rest of them:

.grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-gap: 16px;
grid-auto-rows: 32px;
}

.grid span {
background-color: steelblue;
grid-column: auto / span 2;
}

.grid span:nth-child(1),
.grid span:nth-child(2) {
grid-column: auto / span 3;
}
<div class="grid">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</div>

How to change grid columns size on implicit row?

Essentially, once a row/column size has been set it cannot be changed.

What you can do is define the grid in such a way that items can span multiple columns.

So instead of a 5fr wide container, define one that is 10 columns of 1fr each and then specify how may columns an individual child will span.

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

::before,
::after {
box-sizing: inherit;
}

.container {
display: grid;
grid-template-columns: repeat(10, 1fr);
gap: 1em;
margin: 1em;
}

p {
border: 1px solid grey;
}

p {
grid-column: span 4
}

p:nth-child(2) {
grid-column: span 6;
}

p:nth-child(3) {
grid-column: span 6;
}
<div class='container'>
<p>item-1</p>
<p>item-2</p>
<p>item-3</p>
<p>item-4</p>
<p>item-5</p>
<p>item-6</p>
</div>

Is it possible to make every second row in a CSS Grid to have different number of columns?

You cannot have different number of columns on each row because it would be against the purpose of a grid. Instead you can define a grid of 12 columns and then make your child to either take 3 columns or 4 columns:

.container {  display: grid;  grid-template-columns: repeat(12, 1fr);  grid-column-gap:2px;  grid-row-gap: 5px;}.container > div {  grid-column:span 3;  height:40px;  background:red;}.container > div:nth-child(7n + 1),.container > div:nth-child(7n + 2),.container > div:nth-child(7n + 3) {  grid-column:span 4;  background:blue;}
<div class="container">  <div></div><div></div><div></div><div></div>  <div></div><div></div><div></div><div></div>  <div></div><div></div><div></div><div></div>  <div></div><div></div><div></div><div></div>  <div></div> </div>


Related Topics



Leave a reply



Submit