Background grids, from paper to display

Taras Brizitsky
UX Collective
Published in
11 min readMay 28, 2022

--

So we are building a CAD or a drawing app. It has lots of handy tools and an infinitely large space. There’s enough room for drawings, notes, and anything else.

We start with a blank page, literally. Sketch welcomes its users with a sterile empty space implying that they already know how to start and what they are going to create.

New document in Sketch

It’s like a blank sheet of paper, except that it’s an infinite one.

Scholars start their study with a graph paper. It provides basic scale and structure, making drawing more accurate. As students progress, they use paper with smaller grid cells and learn about different kinds of graphing paper types and patterns. Even after college, we use notebooks with grid patterns as they help us organize our tasks, notes and sketches better even while being on the go.

Photo by Kelly Sikkema on Unsplash

In modern design tools background grids are clear equivalents of graph paper and are often used for the following purposes:

  • Create a sense of scale
  • Serve as visual anchors for aligning objects
  • Provide visual feedback on panning and zooming

The first two work for regular paper, and the last point is most useful for large virtual canvases.

A word on games…

We’ll explicitly exclude games from this story as otherwise, it would turn into a never-ending one. Game designers usually have much more creative freedom and don’t stop on regular conventions.

Pre-3D era games heavily relied on isometric grids to add a sense of depth

UFO: Enemy Unknown, screenshot from Wikipedia

while some go as far as making a radial grid a core part of the gameplay.

In Frostpunk you are building a radial settlement around a generator.

At the same time, game-making tools are not too much different from more generic design apps in the way they use grids.

Lines and dots

When talking about background grids in software, we usually imply line or dot visuals on a regular grid.

Grid cells could be subdivided into smaller ones for better accuracy and dots may be replaced with small crosses or rectangles.

Different approaches to visualizing a grid

Let’s try drawing two simple grids: one made of lines and another one made of small circular dots.

Linear and dot grids

At this point, details don’t matter much. Grid cell size (module) may be anything, the background is pure white, and grid elements are black. The only thing worth changing is the radius of the dots for optical compensation.

Increasing dot size

Now dim the color, tweak the module size, add optional subdivisions and that’s the end of the story, right? Wrong. We are just getting started.

First of all, we need a basic content example, so let’s draw a rectangle.

Grid with an object below

Unlike graph paper, we are not forced to draw the grid on the background. If we are using the grid as a ruler, we may easily place it above the object so that it helps us align content despite its layering. Think about it as a tracing paper placed on top of the content.

In Figma, a design tool where content alignment is a critical part of the work, layout grids are always placed above the content so that you always have a visual reference.

Figma’s Layout grid

The downside of this approach is rather obvious: for more casual products such grids are overkill and mostly add visual noise, so let’s return to our paper reference and treat the grid as a background rather than an overlay.

Grid with an object above

Now if we move around the canvas, we do understand the panning direction with the help of visual feedback from the grid.

Moving around the canvas

Here the rectangle’s opacity is reduced to 50% so that it does not hide the background. While panning the grid provides clear visual feedback about the direction and speed of movement even without any content on the canvas. Both grid visuals work equally good here, nothing magical.

Zoom in, zoom out

No zoom — no cry

Everything looked so tidy and elegant when we just moved around, but see what happens if we try zooming!

Grid scales with the canvas

If we treat our canvas as an infinite sheet of paper and zoom as a distance to the sheet, then everything is ok. But notice two things:

  • Line grid looks too heavy when zoomed in
  • On zooming out both grids quickly lose contrast against a background becoming merely visible

In practice, the last point could become rather annoying if we don’t take it into account.

Zooming in Lucidspark

In Lucidspark dot grid looks like specks of dust on the screen.

The actual size of grid elements does matter, we cannot easily ignore it.

Let’s start with the linear grid as it does seem to scale equally bad in both directions.

What if we stop treating the lines as a part of a canvas and retain stroke size at any zoom level?

Layout grid zoom in Figma

Looks better, but there is another problem, moire. When you zoom out too much, the grid is turned into a flickering mess of pixels. Not cool, right?

So before we proceed, we may need to accept the need of designing grid behavior for at least two different zoom ranges: above 100% and below 100%.

Below and beyond 100%

When zoomed in, line grids look perfectly fine if we don’t scale up the stroke.

Figma Layout grid zoom in

In the same scenario, unscaled dots are nearly invisible, but if we scale them up proportionally, they become a natural indicator of the zoom level.

Zoom in on Whimsical

Now let’s try zooming out.

At some point, we’ll have to deal with moire or “dust”. We may use the following approaches for fighting visual artifacts:

  • Hide/disable the grid below a certain zoom level (say, 75%, 50%, or 25% depending on the cell module size)
  • Decrease grid density each time we hit a certain zoom level. Say, double the grid module at 50% (1/2), 25% (1/4), 13% (1/8), 6% (1/16) etc.
  • Ignore them and pretend everything is ok. Just kidding 😆

Switching the grid off is rather straightforward, but looks quite weird leaving us with no benefits of the grid at a significant range of zoom levels.

Zoom in and out in Whimsical

Replacing the grid with a lower density one has a clear advantage: it provides most of the benefits of the grid at all available zoom levels.

Zoom out in Figjam

See how the density of the grid changes while the dot size remains the same? Disabling element scaling for both dot and line grids below 100% works fine except for a few details we’ll talk about soon.

Fine-tuning

One of the trickiest parts of designing a grid is that it should be prototyped, tuned, and tested inside the actual product rather than in an artificial environment or, worse, as a set of static images. There are quite many details that are very easy to miss if you are not paying enough attention.

50 shades of grey

Background color. Should it be pure white, black, or anything in between?

White would likely conflict with white content on the board, and dark grey may appear “dirty” or have a very low contrast to the grid and other canvas elements…

Even adjusting lightness by just one step leads to drastic changes in the way the canvas background and the grid are perceived.

Changing background lightness one step at a time

The same is true for the grid color: high contrast is accessible but annoying and low contrast grids may be merely visible even on quality displays.

Here are some example background and dot grid colors for a few popular whiteboarding apps:

Even for an ideal static picture, a choice of colors and balancing between accessibility and looks could be trickier than it looked at the very beginning.

Grey uniformity

As if that’s not enough, keeping dot size intact while zooming out could lead to changes in the perceived lightness of the canvas due to an increased dot density.

A simulated example below demonstrates the result.

White to grey

We could reduce the effect by making the lightness of the dots a function of the zoom ratio.

Parametric dot color in Miro

Miro uses this trick for lowering color flickering on zooming out.

Pixel perfection

It’s easy to optimize the visuals for the ideal case of 100% with static images, everything looks crisp and perfect. Problems start when you actually try to interact with the canvas.

At this point, we’ll need a bit of patience and a screen loupe as we’ll literally be talking about matters as large as a single pixel.

Whimsical dot grid at 100% close-up

Whimsical draws crossed lines rather than true circles in order to optimize performance. Looks nice and sharp.

Figjam renders antialiased circles which also seem identical.

Figjam dot grid at 100% close-up

But if we try to zoom out a bit the beauty fades away…

Figjam dot grid at 86% close-up

We may still see individual dots, but they are somewhat blurry and don’t seem to fit the pixel grid any longer.

Now let’s take a look at Miro at 100% and 86%.

Miro grid at 100% and 86% side by side

Notice anything interesting? Both grids are formed of perfectly aligned crisp dots.

But hey, how can it be?

In order to understand the trick, we’ll need a loupe and a ruler.

Let’s make a screenshot of the Miro canvas at the same 86%, and start measuring. The dots are still perfectly crisp, but what appeared to be a perfect order is in fact an optical illusion.

Miro grid with visual references

On this image, I painted a green square between perfectly aligned dots and a magenta one where dots are offset for a pixel. We can’t trick physics and always accurately display objects below 1 px, but we can trick the eye.

The difference between these two approaches (true rendering vs sharp image) is merely distinguishable on retina displays, but at 1x a pixel-perfect grid looks noticeably better.

Snapping in

Just works, huh

We almost forgot one of the key reasons grids are used, object snapping.

Objects are being snapped to the grid edges on creation, resizing, and moving.

Let’s see how it works…

Whimsical grid snapping on resizing

A little bit jittery, but not bad. Especially as we get perfect dimensions as the end result. Now let’s move our object.

Whimsical grid snapping on moving

The product is the same, but this behavior makes it feel less responsive and more annoying. Yet at every certain moment, the rectangle is perfectly placed on the grid.

This effect becomes even more obvious if the grid’s module is large or you zoom in too much. It’s just impossible to ignore.

Figjam grid snapping at 400%

How do we get a perfect grid snapping without making our product feel weird?

Ghosts and grids

One possible solution is to create a “ghost” version of the object that perfectly snaps to the grid while the original can be moved freely.

Object ghost in UI Bakery

The main downside of this approach is that now the ghost could be rather annoying as it adds a significant amount of flickering on small movements and adjustments.

We may try fine-tuning the ghost’s visuals, swapping the object with the ghost, introducing small animations, and conducting voodoo rituals, but the effect would not go away.

Any other options?

Divide and conquer

What if we discard the ghost entirely and instead optimize movement and resizing separately?

Grid snapping in Miro

The object’s movement is perfectly fluid and snapping only occurs once you release it. On resizing, snapping works normally and is not perceived as slow.

The difference in grid look and feel is even more significant on high zoom levels.

Grid snapping in Miro at 400%

Notice that at high zoom levels during the resize our grid works as a guideline rather than a forced structure?

People naturally zoom the canvas in when they want to fine-tune something, so why not build a small improvement on this habit?

It’s way faster than turning the grid snap feature on and off.

Oh snap

And what happens if we try snapping a moving object that does not perfectly with the grid?

We may:

  • snap to the center or a single predefined corner
  • snap to the center or the closest corner
  • adjust the dimensions of the object so that it fits the grid

Adjusting the dimensions sounds like a plan only until our users really care about precise sizing. And as our grid module may change on zooming out, this “smart” behavior may become an unpleasant surprise.

Snapping to the closest corner sounds cool only until you test this behavior on a prototype only to reveal that it’s incredibly annoying.

The only option remaining is snapping to a predefined corner that, just like in all drawing apps, is the top-left one. Wanna align your stuff to a bottom-left corner? You can’t. The world is cruel… 🥹

Snapping to top-left corner in Figjam

Wrapping up

Now that you’ve learned a few tricks you may better understand the underlying complexity of a seemingly basic component of design tools you may never even thought about.

And if by this time you got questions about irregular grids, zoom level limits, or finding ways of improving snapping algorithms based on velocity, you are already on the right track and don’t need any assistance.

Thanks for reading and keep being curious.

--

--