WebCraft

text-underline-offset

An underline you actually drew

default — ink skipped
typography, judged partly
skip-ink: none — strikes the descenders
typography, judged partly
thickness, offset and colour tuned
typography, judged partly

CaveatTwo traps hide in plain sight. First, text-decoration does not inherit — it propagates: drawn on the parent, painted straight through every child, and no child can undo it, because text-decoration: none on the span removes decorations the span itself owns, not the line passing through from above. Second, the shorthand resets its own longhands: writing text-decoration: underline after the tuning quietly puts thickness back to auto — offset survives only because it lives outside the shorthand — so tune after the shorthand or skip it. Size the tuning in em so it scales with the type, and know that skip-ink defaults to skipping — right for Latin descenders, wrong for scripts like Chinese where the gaps read as damage, which is what none is for.

FallbackAn engine too old for the longhands drops each one alone and keeps the underline itself, so the reader gets the plain line the web has always drawn — no order games needed. The one property to keep an eye on is text-decoration-color against low-contrast palettes: the line carries meaning for colour-blind readers precisely because it is not colour, so never let the tint be the only thing separating a link from prose.

CSS
a {
  /* shorthand first: it resets
     the thickness set before it */
  text-decoration: underline;
  text-decoration-thickness: .09em;
  text-underline-offset: .24em;
  text-decoration-color:
    color-mix(in srgb,
      currentColor 45%, transparent);
}

Published