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)