DEV Community

Cover image for Creating a Grid Visualizer
Mads Stoumann
Mads Stoumann

Posted on • Edited on

Creating a Grid Visualizer

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>
Enter fullscreen mode Exit fullscreen mode

In CSS, we need two custom properties to control the amount of columns and the column-gap:

:where(html) {
  --columns: 6;
  --column-gap: 20px;
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

And now for a bit of math! The width of a column is:

100% / number of columns
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Simplified, this is:

(100% - (number of columns - 1) * gap-width)) / number of columns
Enter fullscreen mode Exit fullscreen mode

In CSS, we add this logic to a custom property:

--_w: calc( (100% - (((var(--columns) - 1) * var(--column-gap)))) / var(--columns) );
Enter fullscreen mode Exit fullscreen mode

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) ) );
Enter fullscreen mode Exit fullscreen mode

With our default settings, this renders a nice 6-column grid with gaps:

6-col-grid


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);
}
Enter fullscreen mode Exit fullscreen mode

With the default --column-span: 3, this gives us:

Content with colspan

Let's compare this with Dev Tools' grid visualizer, which we add by clicking the small grid-button next to the markup:

Enable Dev Tools Grid

This renders:

Grid with Visualizer

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>
Enter fullscreen mode Exit fullscreen mode

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 || ''));
}
Enter fullscreen mode Exit fullscreen mode

Codepen demo


Happy coding!

Top comments (0)