How to Make a CSS Grid with Dynamic Number of Rows or Columns

Can I make a CSS grid with dynamic number of rows or columns?

Okay, after reading the MDN reference, I found the answer! The key to dynamic rows (or columns) is the repeat property.

const COLORS = [  '#FE9',  '#9AF',  '#F9A',  "#AFA",  "#FA7"];
function addItem(container, template) { let color = COLORS[_.random(COLORS.length - 1)]; let num = _.random(10000); container.append(Mustache.render(template, { color, num }));}
$(() => { const tmpl = $('#item_template').html() const container = $('#app'); for(let i=0; i<5; i++) { addItem(container, tmpl); } $('#add_el').click(() => { addItem(container, tmpl); }) container.on('click', '.del_el', (e) => { $(e.target).closest('.item').remove(); });});
.container {  width: 100%;  display: grid;  grid-template-columns: repeat(4, 1fr);  grid-template-rows: repeat(auto-fill, 120px);  grid-row-gap: .5em;  grid-column-gap: 1em;}
.container .item {}
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div id="app" class="container"></div>
<button id="add_el">Add element</button>
<template id="item_template"> <div class="item" style="background: {{color}}"> <p>{{ num }}</p> <p> <button class="del_el">Delete</button> </p> </div></template>

CSS grid with dynamic number of rows and adjustable width

Make only the red container resizable with an initial width equal to 50% and use flex-grow:1 on the green container

function addCell(color) {
let container = document.getElementById(color + "-container");

let cell = document.createElement("div");
cell.innerText = color;
container.appendChild(cell).className = "container-item";
}
#container {
border: 1px solid #ddd;
display: flex;
gap: 10px;
padding: 10px;
height: 50vh;
resize: vertical;
overflow: auto;
}

#green-container,
#red-container {
display: grid;
overflow: auto;
}
#red-container {
border: 1px solid red;
width: 50%;
resize: horizontal;
}
#green-container {
border: 1px solid green;
flex-grow: 1;
}


.container-item {
padding: 10px;
border: 1px solid black;
}
<button onclick="addCell('red')">add red cell</button>
<button onclick="addCell('green')">add green cell</button>

<div id="container">
<div id="red-container"></div>
<div id="green-container"></div>
</div>

Set CSS Grid number of columns dynamically on the basis of list items

You can use grid-template-rows: repeat to do that like this:

.list {
list-style: none;
display: grid;
grid-template-rows: repeat(15, 45px);
gap: 10px;
grid-auto-flow: column;
}

.list-item {
background: black;
width: 40px;
height: 40px;
margin: 10px;
color: white;
font-size: 12px;
}
<ul class='list'>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
<li class="list-item">
<a>item</a>
</li>
</ul>

Dynamic CSS grid with template-columns: auto and full-width row

Your header rule sets row to 1, and this limits your grid layout. You need at least 3 rows in order to have one for the header, and two for the full-width element.

  1. Start by removing the header rule completely.

  2. Then add grid-template-rows to the wrapper.

  3. Change your wrapper to use repeat(), this makes the horizontal span work as expected:

.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(4, minmax(0, 1fr));
background-color: #fff;
color: #444;
}

  1. In order to make full-width span 2 rows you need at least 3 rows in total. Plus you need to declare your grid-row span like this:
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(4, minmax(0, 1fr));
background-color: #fff;
color: #444;
grid-template-rows: repeat(3, minmax(0, 1fr));
}

.full-width {
grid-column: 1 / -1;
grid-row: span 2 / span 2;
}

  1. If you want an empty node at the top left corner of the grid, we need to increase the amount of columns to 5. We also need an extra class that pushes the first grid child one column towards the right (the other children will be pushed along):
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(5, minmax(0, 1fr));
background-color: #fff;
color: #444;
grid-template-rows: repeat(3, minmax(0, 1fr));
}

.wrapper:first-child {
grid-column-start: 2;
}

CSS grid - dynamic column at the start of the grid

Yes, you can.

The grid layout allows you to set multiple elements in the very same defined cell.

You could set .select and .title inside the first column and first-row. (similar effect to absolute positionning somehow)

If the .select (is here) stands ahead the .title, give the .title a margin or a padding to leave space for the checkbox.


Live example below with and without the .select box

body {
background: #131418;
margin: 1em;
}

:root {
--extra-section: 70px;
}

.container {
padding: 0.5em;
border: 1px solid silver;
color: silver;
/* grid */
display: grid;
grid-template-columns: 1fr auto repeat(3, minmax(var(--extra-section), auto));
grid-auto-columns: var(--extra-section);
grid-auto-flow: column;
grid-column-gap: 0.5em;
align-items: center;
}

body {
background: #131418;
margin: 1em;
}

:root {
--extra-section: 70px;
}

.container {
padding: 0.5em;
border: 1px solid silver;
color: silver;
/* grid */
display: grid;
grid-template-columns: 1fr auto repeat(3, minmax(var(--extra-section), auto));
grid-auto-columns: var(--extra-section);
grid-auto-flow: column;
grid-column-gap: 0.5em;
align-items: center;
}
.container .select,
.container .title {
grid-column:1;
grid-row:1;
}
.select {position:relative;/* bring it up front to be clickable */}
.container .select + .title {
padding-inline-start:1.5rem;/* or padding-left for ltr direction */
}
<div class="container">
<div class="select">
<label>
<input type="checkbox">
</label>
</div>
<div class="title">
Lorem ipsum dolor sit amet, consectetur
</div>
<div class="people">
<img src="https://i.pravatar.cc/25" />
<img src="https://i.pravatar.cc/25" />
<img src="https://i.pravatar.cc/25" />
</div>
<div class="likes">9</div>
<div class="bookmarks">4</div>
<div class="shares">2</div>
</div>
<hr>
<div class="container">
<div class="title">
Lorem ipsum dolor sit amet, consectetur
</div>
<div class="people">
<img src="https://i.pravatar.cc/25" />
<img src="https://i.pravatar.cc/25" />
<img src="https://i.pravatar.cc/25" />
</div>
<div class="likes">9</div>
<div class="bookmarks">4</div>
<div class="shares">2</div>
</div>


Related Topics



Leave a reply



Submit