Text✨ Premium

Outline to Fill

Outline text that fills with color on hover — pure CSS, zero JavaScript.

CSSHoverStroke

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Text has 56 effects, including 4 free. Explore the category →

3 usage examples

Oversized keyword on a creative studio homepage — Outline to Fill example 1

① Oversized keyword on a creative studio homepage

WhenA studio or agency homepage features its name or a brand keyword in very large type (8–12 vw) as the centrepiece of the hero section.
WhyAt large sizes, the contrast between the hollow silhouette and the background is immediately striking. The fill-on-hover turns a decorative headline into an invitation to engage with the brand.
SettingsStroke 3–4 px for legibility at large sizes, font-size 8–12 vw, transition 0.5 s for a more cinematic fade, letter-spacing -0.04em.
Outline CTA button — hover state without an opaque background — Outline to Fill example 2

② Outline CTA button — hover state without an opaque background

WhenA primary action button ("Join", "Get started", "Try it") needs to stand out on a dark or colored section without an opaque background fill — a solid button would weigh down the layout.
WhyThe resting state (outline only) is elegant and unobtrusive; the fill on hover signals intent with strong visual personality. The effect replaces the classic hover state (background color change) with a typographic mechanism that is directly reusable as a component.
Settingsfont-size 1.4–2 rem, stroke 2 px (matching the button border), transition 0.3 s ease-out, padding 12–16 px 32–40 px on the button container.
Main menu or title screen for a gaming interface — Outline to Fill example 3

③ Main menu or title screen for a gaming interface

WhenMenu options (Play, Settings, Scores) or the game title are displayed against a dark background with a neon aesthetic.
WhyThe outline style is iconic in gaming aesthetics — it evokes retro and neon interfaces. The fill-on-hover confirms selection in a visually satisfying way, without requiring any JS.
SettingsStroke 2–3 px, neon color (cyan #06b6d4, magenta #ec4899, green #22c55e), transition 0.2 s for snappier feedback, letter-spacing 0.1 em, neon text-shadow on the hover state.

How it works

The resting state relies on two combined properties: -webkit-text-stroke draws the glyph outline with a chosen width and color, and color: transparent hides the inner fill. The text is only visible as a hollow silhouette.

On hover (:hover), color switches to the fill color (#6366f1) and -webkit-text-stroke is reset to zero. The transition: .4s applied at rest animates both properties simultaneously: the outline fades out as the fill appears.

-webkit-text-stroke is prefixed but natively supported across all modern rendering engines — Chrome, Firefox, Safari, Edge — without polyfills. Unlike text-shadow, it operates on the vector path of the glyph, preserving sharp edges at any size and font-weight.

The effect is entirely stateless: no JS, no extra DOM. Apply the text-outline-fill class to any text element and add the CSS — done.

Accessibility

  • No prefers-reduced-motion: the transition (.4s) runs regardless of the system setting. Add @media (prefers-reduced-motion: reduce) { .text-outline-fill { transition: none } } for motion-sensitive users.
  • The effect is triggered by :hover only — not keyboard-accessible. Add .text-outline-fill:focus-visible { -webkit-text-stroke: 0 transparent; color: #6366f1 } to fire on focus as well.
  • Text content is native HTML (<span>): screen readers read it normally, independently of the visual style — no aria attributes are required on the element.
  • Resting state: only the outline (#6366f1, 2 px) is visible. At 2 px on a dark background, the stroke alone may fall below WCAG AA contrast — increase width or color if legibility demands it.
  • Filled state: #6366f1 on #0a0a0f yields a contrast ratio of approximately 4.6:1 — WCAG AA compliant (≥ 4.5:1). On a light background, re-check with your palette.

Browser compatibility

Relies exclusively on -webkit-text-stroke and color — no JavaScript, no external dependencies.

Chrome 4+✓ Full
Firefox 49+✓ Full
Safari 3+✓ Full
Edge 79+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

If <code>-webkit-text-stroke</code> is not supported (very old browsers), text displays with its normal <code>color</code> fill — no errors, content remains readable.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<span class="text-outline-fill">YOUR TEXT</span>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
-webkit-text-stroke (width) 2px Outline stroke thickness. 1 px = delicate, 3–5 px = bold and readable at a distance. Beyond 5 px, glyphs may close up at small font sizes.
-webkit-text-stroke (color) #6366f1 Outline color at rest. May differ from the fill color for a two-tone effect (stroke and fill chromatically distinct).
color (hover state) #6366f1 Fill color on hover. Same value as the outline for monochrome consistency; a different value for a dual-color effect.
transition .4s Animation duration. 0.2 s = snappy response (gaming, UI), 0.6–0.8 s = slow cinematic fade. Add ease-in-out to smooth both ends.
font-size 2.5rem Text size. The effect is most impactful above 3 rem — below that, a 2 px stroke takes up a disproportionate share of the glyph surface.
font-weight 800 Font weight. Heavy weights (700–900) produce a bolder stroke and a more substantial fill. Light weights (300–400) give a more airy result.

FAQ

It is prefixed (-webkit-) but natively supported across all modern engines — including Firefox since v49 and Edge since v79 — without polyfills. The unprefixed property (text-stroke) is not yet a CSS standard. For a prefix-free alternative, use an <svg> with stroke and fill, at the cost of a more complex structure.
The effect only fires on :hover, making it invisible to keyboard users. Add .text-outline-fill:focus-visible { -webkit-text-stroke: 0 transparent; color: #6366f1 } so keyboard focus produces the same visual result. Make sure the element is focusable (tabindex="0" if it is not a link or button).
Yes: in the :hover selector, keep -webkit-text-stroke at its resting value instead of resetting it to zero. Only color will change — you get outlined text that colors its interior on hover, stroke remaining. The effect is more subtle but readable at smaller sizes.