If you're working with a grid-system, chances are, you're using some kind of grid visualizer – maybe in Figma, or in Dev Tools.
I'm currently working on a project where I need a customizable grid-visualizer. Thankfully it's pretty simple – using a bit of math and CSS!
The markup for this demo is very basic. We have a grid, and a single piece of content:
<div class="grid">
<div class="content"></div>
</div>
In CSS, we need two custom properties to control the amount of columns and the column-gap:
:where(html) {
--columns: 6;
--column-gap: 20px;
}
For the .grid
-class, we need to set up a basic grid, using the two custom properties, we just configured:
.grid {
column-gap: var(--column-gap);
display: grid;
grid-template-columns: repeat(var(--columns, auto-fit), 1fr);
}
We'll add the colors for the columns and gaps as two new properties:
--_col-bgc: hsl(200, 50%, 75%, .5);
--_gap-bgc: hsl(200, 50%, 45%, .5);
And now for a bit of math! The width of a column is:
100% / number of columns
From that value, we need to deduct the gap-width. There will always be one gap less than the number of columns, so:
((number of columns - 1) * gap-width) / number of columns
Simplified, this is:
(100% - (number of columns - 1) * gap-width)) / number of columns
In CSS, we add this logic to a custom property:
--_w: calc( (100% - (((var(--columns) - 1) * var(--column-gap)))) / var(--columns) );
Finally, using our custom properties, we add a repeating-linear-gradient
:
background-image: repeating-linear-gradient(to right,
var(--_col-bgc), var(--_col-bgc) var(--_w),
var(--_gap-bgc) var(--_w), var(--_gap-bgc) calc(var(--_w) + var(--column-gap) ) );
With our default settings, this renders a nice 6-column grid with gaps:
For the .content
, we add a small chunk of css:
.content {
background-image: linear-gradient(45deg, black, transparent);
grid-column: span var(--column-span, 3);
}
With the default --column-span: 3
, this gives us:
Let's compare this with Dev Tools' grid visualizer, which we add by clicking the small grid
-button next to the markup:
This renders:
Cool – This seems to be working!
Adding an editor
Finally, let's add a small editor, so we can easily play around with the columns-, gap- and colspan-properties:
<form id="app">
<fieldset>
<legend>Grid Visualizer</legend>
<label>Columns
<input type="range" name="columns" value="6" min="1" max="12" />
</label>
<label>Gap
<input type="range" name="column-gap" value="20" min="0" max="100" data-unit="px" />
</label>
<label>Column-span
<input type="range" name="column-span" value="3" min="1" max="12" data-scope=".content" />
</label>
</fieldset>
</form>
To update the custom properties dynamically, we need a small JavaScript:
app.addEventListener('input', (event) => setCustomProperty(event.target));
function setCustomProperty(input) {
const scope = input.dataset.scope;
const node = !scope ? document.documentElement : scope === 'self' ? input : scope === 'parent' ? input.parentNode : document.querySelector(scope);
node.style.setProperty('--' + input.name, input.value + (input.dataset.unit || ''));
}
Codepen demo
Happy coding!
Top comments (0)