CSS Typography

CSS text-rendering dan Font Smoothing Dijelaskan

Updated Februari 24, 2026
Haruskah Anda menggunakan -webkit-font-smoothing: antialiased? Apa sebenarnya yang dilakukan text-rendering: optimizeLegibility? Jawaban definitifnya.

CSS text-rendering and Font Smoothing Explained

Two CSS properties affect how glyphs are rendered at the pixel level: text-rendering and -webkit-font-smoothing. Neither is part of the CSS specification proper — text-rendering is an SVG property adopted by browsers, and -webkit-font-smoothing is a WebKit-specific extension that was never standardized. Yet both are widely used in production, often cargo-culted from CSS resets without developers understanding what they actually do.

This guide explains what each property does, what the trade-offs are, and what settings make sense for different contexts in 2026.


text-rendering: auto vs. optimizeLegibility

The text-rendering property gives the browser hints about how to prioritize rendering quality. It's a hint, not an absolute instruction — browsers may interpret it differently.

The Four Values

/* Let the browser decide (default) */
.default {
  text-rendering: auto;
}

/* Prioritize legibility over speed */
.legible {
  text-rendering: optimizeLegibility;
}

/* Prioritize speed over legibility */
.fast {
  text-rendering: optimizeSpeed;
}

/* Geometric precision — useful for SVG text */
.precise {
  text-rendering: geometricPrecision;
}

auto

The default. The browser balances speed and legibility based on its internal heuristics. In practice, modern browsers are very good at this. For most text at typical sizes (12px–30px), the difference between auto and optimizeLegibility is imperceptible.

optimizeLegibility

When set to optimizeLegibility, the browser enables two features that can improve visual quality:

  1. Kerning — Adjusts spacing between specific letter pairs (e.g., "AV" gets tightened, "rn" gets separated). Modern browsers enable CSS kerning (font-kerning: normal) by default at all sizes, so this is less impactful than it used to be.

  2. Ligatures — Enables contextual ligatures like fi, fl, ffi, ffl, where the font has designed combined glyphs for better appearance.

/* Previously common pattern */
body {
  text-rendering: optimizeLegibility;
}

The Performance Cost — A Historical Note

In older browsers (particularly Chrome prior to 2013), text-rendering: optimizeLegibility triggered slow text rendering paths that could noticeably degrade scroll performance, especially on mobile. This led to the common advice to avoid it.

In 2026, modern browser rendering engines have largely closed this gap. The performance penalty is minimal on modern hardware and browsers. That said, on very large text blocks or older/low-power devices, the overhead can still be measurable. Test with real devices.

/* Safe pattern: enable for headings (where kerning matters),
   leave auto for body text (where speed matters more) */
h1, h2, h3, h4 {
  text-rendering: optimizeLegibility;
}

body {
  text-rendering: auto; /* or omit entirely */
}

optimizeSpeed

Disables kerning and ligatures entirely for fastest rendering. Almost never appropriate for body text.

/* Appropriate: very large lists, data tables, chat messages */
.message-list {
  text-rendering: optimizeSpeed;
}

geometricPrecision

Renders text with mathematical precision rather than optimizing for display. Intended for SVG text where coordinates need to be exact.

svg text {
  text-rendering: geometricPrecision;
}

-webkit-font-smoothing: The macOS Story

-webkit-font-smoothing is a WebKit/Blink property that controls antialiasing on macOS (and to some extent, iOS). It does not affect rendering on Windows, Android, or Linux.

/* Three values */

/* Auto: browser decides */
.auto { -webkit-font-smoothing: auto; }

/* Subpixel antialiasing (classic macOS behavior) */
.subpixel { -webkit-font-smoothing: subpixel-antialiased; }

/* Grayscale antialiasing (thinner, lighter strokes) */
.grayscale { -webkit-font-smoothing: antialiased; }

The History of Subpixel Rendering on macOS

For many years, macOS used subpixel antialiasing by default — a technique that uses the RGB components of each screen pixel as sub-pixels to achieve finer horizontal resolution. This made text on non-Retina displays look sharper and slightly heavier/darker.

Starting with macOS Mojave (10.14) in 2018, Apple disabled subpixel antialiasing system-wide. The primary reason: Retina displays (2x and above) have pixels small enough that subpixel rendering is unnecessary. On Retina, grayscale antialiasing produces equally sharp text without the color fringing associated with subpixel rendering.

The consequence for web developers: on modern Macs with Retina displays, the difference between antialiased and subpixel-antialiased is negligible — the OS no longer does subpixel rendering regardless of what you set.

On older Macs without Retina displays (still in use), the difference can be visible: - subpixel-antialiased: heavier strokes, more contrast - antialiased: thinner strokes, lighter appearance

What -webkit-font-smoothing: antialiased Actually Does

On macOS, antialiased switches to grayscale antialiasing, which tends to make text look slightly thinner and lighter than the default. This was widely adopted because it made many typefaces look closer to how they're designed — particularly for light-on-dark text where the standard rendering made text look bloated.

/* Common pattern in many CSS resets */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale; /* Firefox on macOS */
}

-moz-osx-font-smoothing: grayscale is the Firefox-macOS equivalent, which achieves the same effect. Like -webkit-font-smoothing, it has no effect on Windows or Linux.


Performance Impact and When to Use Each

text-rendering Performance

The real-world impact today:

Context Recommendation
Headings (small quantity) optimizeLegibility is fine
Large amounts of body text auto to avoid any overhead
Animations / scroll-heavy lists optimizeSpeed or auto
SVG text geometricPrecision
/* Production-safe pattern */
html {
  text-rendering: auto; /* Safe default */
}

h1, h2, h3 {
  text-rendering: optimizeLegibility; /* Where kerning visibility matters */
}

/* During animation — temporarily disable for performance */
.animating {
  text-rendering: optimizeSpeed;
}

font-smoothing and GPU Layers

One side effect of -webkit-font-smoothing: antialiased worth knowing: in some browsers, it can force an element onto its own compositing layer. This can improve scroll performance in some cases but increases memory usage. It's generally not a concern for typical use.


Font Smoothing in Dark Mode

Dark mode is where font smoothing matters most visibly. On dark backgrounds, text rendered with the default (subpixel/heavier) rendering can appear bolder and harder to read than intended. Switching to antialiased rendering in dark mode produces lighter strokes that match the designer's intent.

/* Light mode: default rendering */
body {
  -webkit-font-smoothing: auto;
  -moz-osx-font-smoothing: auto;
  background-color: #ffffff;
  color: #1a1a1a;
}

/* Dark mode: antialiased rendering for lighter strokes */
@media (prefers-color-scheme: dark) {
  body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    background-color: #0f0f0f;
    color: #e8e8e8;
  }
}

This pairing also works well with weight adjustments for variable fonts — slightly reducing weight in dark mode in combination with antialiased rendering produces text that reads at the intended visual weight:

@media (prefers-color-scheme: dark) {
  body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;

    /* If using a variable font — reduce weight slightly */
    font-weight: 375; /* Instead of 400 */
  }

  strong, b {
    font-weight: 600; /* Instead of 700 */
  }
}

This technique is used by several major design systems, including GitHub's Primer, because it compensates for the optical illusion where white text on a dark background appears heavier than the same weight of dark text on white.


Here is a production-ready set of font rendering settings based on current browser behavior:

/* === Font Rendering Baseline === */

html {
  /* Let the browser handle text rendering for body text.
     Modern browsers do a good job without hints. */
  text-rendering: auto;

  /* Grayscale antialiasing on macOS/iOS — thinner strokes,
     closer to design intent, better on Retina displays.
     No effect on Windows/Android/Linux. */
  -webkit-font-smoothing: antialiased;

  /* Firefox on macOS equivalent */
  -moz-osx-font-smoothing: grayscale;
}

/* Headings: enable kerning and ligatures via optimizeLegibility.
   Only a small number of elements — performance impact is negligible. */
h1, h2, h3, h4, h5, h6 {
  text-rendering: optimizeLegibility;
}

/* Dark mode: smoothing is especially important */
@media (prefers-color-scheme: dark) {
  html {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
}

/* High-contrast preference: let the browser handle it */
@media (prefers-contrast: high) {
  html {
    -webkit-font-smoothing: auto;
    -moz-osx-font-smoothing: auto;
  }
}

Why Not Apply optimizeLegibility Everywhere?

The short answer: it's unnecessary for body text and the risk of performance overhead on lower-end devices is real, even if minor on modern hardware. Browsers already apply kerning by default at most sizes (controllable via font-kerning). And ligatures are already active for common-ligatures on most modern browsers by default.

If you want kerning and ligatures explicitly, the right tool is CSS font properties:

body {
  font-kerning: normal;                             /* Kerning on */
  font-variant-ligatures: common-ligatures;         /* Standard ligatures */
}

code, pre {
  font-kerning: none;                               /* No kerning in code */
  font-variant-ligatures: no-common-ligatures;      /* No ligatures in code */
}

This is more semantically correct than relying on text-rendering: optimizeLegibility as a side-effect machine.

Summary Table

Property Value Effect Platform
text-rendering auto Browser defaults All
text-rendering optimizeLegibility Kerning + ligatures All
text-rendering optimizeSpeed Disables kerning/ligatures All
-webkit-font-smoothing antialiased Grayscale AA, thinner strokes macOS/iOS
-webkit-font-smoothing subpixel-antialiased Subpixel AA (legacy) macOS
-moz-osx-font-smoothing grayscale Grayscale AA macOS (Firefox)

The bottom line: apply -webkit-font-smoothing: antialiased globally (it's essentially universally recommended now), use text-rendering: optimizeLegibility for headings only, and use the prefers-color-scheme: dark media query to explicitly set smoothing for dark mode. That covers 95% of projects without performance concerns.

Typography Terms

Try These Tools

Fonts Mentioned

Related Articles