Background textures guide

Line work

Grid & Ruling CSS Background Patterns

Rulings give a working surface structure the way an engineering pad does: they promise alignment before anything is placed on them. Every pattern here is a repeating CSS gradient mixed from the foreground token, so one declaration re-tints itself in light and dark mode.

Two weights at most
A fine rule plus a heavier major line is a hierarchy; a third weight is a moiré.
Snap to the layout grid
Match the cell to your spacing scale so content actually lands on the lines.
Keep rules under 10%
Above ~10% of the foreground color, line work starts underlining text at random.

Texture examples

5 surfaces built from CSS alone

Every swatch below is painted by the declaration beside it — no image files. The tints come from color-mix over your theme tokens, so switch modes and watch each sample follow.

01

Graph paper

Rule a fine square grid with a heavier line every fifth cell — the engineering-pad structure canvas tools are drawn on.

Derive the major line from the same cell (5 × 24px, not a second arbitrary number) or the two grids drift apart.

background-image:
  linear-gradient(color-mix(in oklab, var(--foreground) 5%, transparent) 1px, transparent 1px),
  linear-gradient(90deg, color-mix(in oklab, var(--foreground) 5%, transparent) 1px, transparent 1px),
  linear-gradient(color-mix(in oklab, var(--foreground) 9%, transparent) 1px, transparent 1px),
  linear-gradient(90deg, color-mix(in oklab, var(--foreground) 9%, transparent) 1px, transparent 1px);
background-size: 24px 24px, 24px 24px, 120px 120px, 120px 120px;
02

Dot grid

Mark only the intersections of the grid — the bullet-journal surface most drawing canvases print behind their nodes.

Dots need more alpha than lines: a single pixel of ink reads fainter than a full rule at the same opacity.

background-image:
  radial-gradient(color-mix(in oklab, var(--foreground) 16%, transparent) 1px, transparent 1px);
background-size: 20px 20px;
03

Notebook ruling

Run horizontal rules alone for a lined-paper surface that suits editorial layouts and note-taking UIs.

Set the ruling to your body line-height so real text sits on the lines instead of fighting them.

background-image:
  linear-gradient(color-mix(in oklab, var(--foreground) 6%, transparent) 1px, transparent 1px);
background-size: 100% 28px; /* = body line-height */
04

Blueprint

Tint the surface toward the brand color and rule it in the same hue for a drafting-blueprint panel.

Mix the tint from --primary rather than hard-coding a blue, so the panel follows a rebrand and both modes.

background-color: color-mix(in oklab, var(--primary) 8%, var(--background));
background-image:
  linear-gradient(color-mix(in oklab, var(--primary) 22%, transparent) 1px, transparent 1px),
  linear-gradient(90deg, color-mix(in oklab, var(--primary) 22%, transparent) 1px, transparent 1px);
background-size: 24px 24px;
05

Drafting crosshatch

Cross two faint diagonal rulings for the hand-hatched shading of a technical sketch.

Halve the per-layer alpha — where the two diagonals cross, their opacity stacks.

background-image:
  repeating-linear-gradient(45deg, color-mix(in oklab, var(--foreground) 4%, transparent) 0 1px, transparent 1px 10px),
  repeating-linear-gradient(-45deg, color-mix(in oklab, var(--foreground) 4%, transparent) 0 1px, transparent 1px 10px);

Implementation check

Ship the quiet version everywhere else.

Judge the texture at arm's length with real content on top, in both modes. Then remove it for print and forced-color modes, and confirm text contrast is measured against the texture's darkest fleck — not the base surface alone.

@media print {
  .texture { background-image: none; }
}

@media (forced-colors: active) {
  .texture { background-image: none; }
}

Carry the material into a complete theme.

Nodlume ships textures as .texture-* utility classes beside your palette, fonts, and shadows, generated into the React project with everything else.

Start planning free

We'd like to use Google cookies to understand how Nodlume is used and to measure our advertising. Nothing loads until you choose, and declining does not affect anything in the app.