Skip to content

Comic dots ​

CMYK halftone dot backgrounds for any Tailwind color. Pure CSS, no images.

Comic mixes subtractively, the way ink lands on paper. Its sibling Pixel mixes additively, the way a display emits light. Left at their defaults both read back as the color you passed in; turn the knobs up and the channels come apart.

Browser support

Built on CSS relative color syntax with max() inside rgb(from ...), and registered custom properties. Live status for each is at the foot of this page.

Do not pair this with text-contrast-*

The dots sit on a white base, so the surface a reader sees is part ink and part white, in a proportion set by comic-gap, comic-dot and comic-bleed. text-contrast-* solves against one flat color and has no way to know any of that. Pick the text color by hand here. See Composition.

Quick reference ​

class styles
bg-comic-<color>Sets color and applies CMYK dot pattern with background-blend-mode: multiply
bg-comic-<color>/<opacity>Same with opacity modifier, 0-100
bg-comic-<color>/[<number>]Same with a 0-1 opacity
bg-comic-[<value>]Arbitrary color value
bg-comic-(--var)Color from a custom property
comic-dot-<number>--jib-comic-dot: --spacing(<number>). Dot radius.
comic-dot-[<value>]--jib-comic-dot: <value>
comic-bleed-<number>--jib-comic-bleed: --spacing(<number>) / 4. Dot edge softness.
comic-bleed-[<value>]--jib-comic-bleed: <value>
comic-gap-<number>--jib-comic-gap: --spacing(<number>) / 4. Space between dots.
comic-gap-[<value>]--jib-comic-gap: <value>

How it works ​

Each color decomposes into CMYK channels from the inverse of its RGB values:

DotColorOpacity formula
C (cyan)rgb(0 255 255)(max(R,G,B) - R) / max(R,G,B)
M (magenta)rgb(255 0 255)(max(R,G,B) - G) / max(R,G,B)
Y (yellow)rgb(255 255 0)(max(R,G,B) - B) / max(R,G,B)
K (black)rgb(0 0 0)1 - max(R,G,B) / 255

The four dot layers sit at different grid offsets and composite through background-blend-mode: multiply for subtractive color mixing, just like a printing press.

bg-blend-* overwrites that list

background-blend-mode repeats a single value across every layer, and Tailwind's bg-blend-* sets one. It sorts after the halftone, so bg-comic-* bg-blend-multiply blends nothing with the halftone — it replaces the per-layer list the CMYK mixing is built from, including the normal entries that keep a ripple, a border gradient and the colour underlay out of the mix.

Basic usage ​

Add bg-comic-<color> to any element:

Gap ​

Control the space between dots with comic-gap-<number>. The value scales at --spacing / 4, so comic-gap-1 is 1px and comic-gap-4 is 4px. The default is 2px.

gap-0

gap-1

gap-2

gap-4

gap-8

Gap adds to dot size, so the grid cell works out to dot * 2 + gap. Changing comic-dot-* scales the grid with it.

Dot size ​

Control the dot radius with comic-dot-<number> using the Tailwind spacing scale. The default is 1px.

dot-0.5

dot-1

dot-1.5

dot-2

dot-3

Bleed ​

Control the dot edge softness with comic-bleed-<number>. The transparent gradient stop sits at dot + bleed, so:

  • comic-bleed-0 gives crisp hard-edged circles
  • comic-bleed-1 gives slight softness, and is the default
  • Larger values blur the dot edges further

bleed-0

bleed-1

bleed-2

bleed-3

bleed-4

Opacity ​

Add an opacity modifier with the / syntax to fade the whole pattern: all four CMYK dot layers and the white background. The bare value is a percentage (0–100); a bracketed value is a 0–1 alpha, so /50 and /[0.5] are the same. The bracketed-percentage form /[50%] that the color utilities accept is not available here, because converting it would need calc(x / 100%), which Firefox rejects.

100%

/75

/50

/25

/10

It scales every CMYK channel opacity by the same factor and turns the white background semi-transparent, so you can layer the pattern over whatever is underneath.

over gradient

over gradient

CMYK channel behavior ​

Every Tailwind color at every shade, rendered as Ben Day dots. Grays produce only K (black) dots with no color cast, which is what proper CMYK conversion buys you over naive CMY.

Slate

Gray

Zinc

Neutral

Stone

Red

Orange

Amber

Yellow

Lime

Green

Emerald

Teal

Cyan

Sky

Blue

Indigo

Violet

Purple

Fuchsia

Pink

Rose

Using a custom value ​

Use the arbitrary value syntax for colors not in the Tailwind palette:

Applying conditionally ​

All bg-comic-* and comic-* utilities support Tailwind's variant syntax:

html
<!-- dots on hover -->
<div class="bg-blue-500 hover:bg-comic-blue-500"></div>

<!-- larger gaps from md up -->
<div class="bg-comic-red-500 md:comic-gap-8"></div>

In practice ​

Swatches show the pattern; a panel shows what it is for. Every color below comes from bg-comic-*, and the red is the point: on press it is yellow and magenta dots, and the dots do the mixing. The keyline, the caption box and the display type are plain Tailwind.

comic · press sheet

Four inks.
One press.
No images.
This red is yellow and magenta dots. Nothing here is a photograph.
Krakk!
Fig. 01 · bg-comic-[#c62828]
Fig. 02 · the issue goes to press in black and white. Same ink, no hue — dot coverage carries the tone.

Import ​

Included in @import 'tw-jib-css'. To import individually:

css
@import 'tw-jib-css/comic';

Baseline status

What these utilities are built on, live from the Web Platform Dashboard.