cssweb-designfront-end-developmentcss-trickstypography

CSS Text Outline: The Guide to text-stroke, WebKit & SVG

6.205 min read
Md Nasim SheikhMd Nasim Sheikh
Share:

Typography is the cornerstone of web design. One of the most impactful effects is the text stroke (or outline). In the past, this required Photoshop. Today, CSS gives us three ways to do it, but browser compatibility can still be confusing.

Table of Contents

⚡ TL;DR: Quick Copy Snippets

If you just want the code, here are the three best methods.

1. The Modern Standard (Works in Chrome, Firefox, Safari) Note: Yes, you must use the -webkit- prefix even for Firefox.

.stroke-text {
  color: white; /* Fill color */
  -webkit-text-stroke: 2px black; /* Width and Color */
}

2. The "Outline Only" (Transparent Fill)

.outline-text {
  color: transparent;
  -webkit-text-stroke: 2px red;
}

3. The "Perfect" Vector Stroke (SVG) Use this if the CSS stroke looks messy or "eats" the text.

svg text {
  fill: white;
  stroke: black;
  stroke-width: 4px;
  paint-order: stroke fill; /* Draws stroke BEHIND the text */
}


Advertisement

Method 1: The Quick Way (-webkit-text-stroke)

The most direct way to create a text stroke in CSS is using the text-stroke property. It's a shorthand for two properties: text-stroke-width and text-stroke-color.

The "moz-text-stroke" Myth

If you are searching for moz-text-stroke to make this work in Firefox, stop searching. It does not exist.

Firefox supports the standard non-prefixed property, but for maximum compatibility across all browsers (including legacy ones), the industry standard is to use the -webkit- prefix. This works in Firefox, Chrome, Edge, and Safari.

.simple-stroke {
  font-family: sans-serif;
  font-size: 6rem;
  font-weight: 900;
  
  color: white; 
  -webkit-text-stroke: 2px black;
}

The Problem: "Eating" the Text

The main downside of text-stroke is that the stroke is drawn centered on the edge of the letter. This means half the stroke is outside, and half is inside.

If you have a thin font and a thick stroke, the stroke will "eat" your letter, making it look thin and ugly.

❌ The limit: Generally, avoid strokes thicker than 2px when using this method.

Advertisement

Method 2: The "Old School" Shadow Hack

Before text-stroke was supported, developers used text-shadow to simulate an outline. This is still useful if you need to support ancient browsers (like Internet Explorer) or if you want a softer, glowing outline.

How it works: We create four (or more) shadows, each offset by 1 pixel in different directions.

.shadow-stroke {
  color: #f1c40f;
  text-shadow:
    -1px -1px 0 #000,  /* top left */
     1px -1px 0 #000,  /* top right */
    -1px  1px 0 #000,  /* bottom left */
     1px  1px 0 #000;  /* bottom right */
}

Pros:

  • The stroke sits behind the text, so it never "eats" the letters.
  • Works on 100% of browsers.

Cons:

  • It looks "pixelated" or fuzzy at corners.
  • It requires a lot of code for thicker strokes.

Method 3: The "Gold Standard" (SVG)

If you want a professional, crisp, pixel-perfect stroke that works at any size (even huge headlines), SVG is the only correct choice.

Unlike CSS borders, SVG gives us the magical paint-order property. This allows us to tell the browser: "Draw the stroke first, then paint the text on top of it."

This ensures the stroke is always strictly on the outside.

<svg width="100%" height="150">
  <text x="50%" y="50%" dy=".35em" text-anchor="middle" class="svg-text">
    SVG STROKE
  </text>
</svg>

.svg-text {
  font-family: 'Bangers', cursive;
  font-size: 7rem;
  
  fill: white;       /* Text Color */
  stroke: black;     /* Stroke Color */
  stroke-width: 6px; /* Thick Stroke! */
  
  /* The Secret Sauce */
  paint-order: stroke fill;
}

Why this wins:

  1. Scalable: You can have a 20px stroke and the text remains perfectly readable.
  2. Gradients: You can apply gradients to the stroke itself (using SVG defs).
  3. Animation: You can animate the stroke (the famous "self-drawing line" effect).

Advertisement

Advanced: The "Clone" Trick (::before)

If you can't use SVG but hate how text-stroke eats your letters, there is a CSS-only workaround using the data-text attribute.

We basically clone the text, put it behind the original, and add the stroke to the clone.

Step 1: HTML Add the text twice, once inside the tag and once in a data attribute.

<h1 class="clone-stroke" data-text="HELLO">HELLO</h1>

Step 2: CSS

.clone-stroke {
  position: relative;
  color: white; /* The clean fill on top */
  z-index: 1;
}

.clone-stroke::before {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: 0;
  z-index: -1; /* Sit behind */
  
  /* The thick stroke */
  -webkit-text-stroke: 8px red; 
}

Summary: Which one should I use?

  • For simple, thin outlines: Use Method 1 (-webkit-text-stroke). It works in Firefox/Chrome/Safari.
  • For thick, bold headlines: Use Method 3 (SVG). It is the cleanest and most professional look.
  • For ancient browser support: Use Method 2 (Shadows).

Stop searching for moz-text-stroke—it's a myth! Stick to -webkit- and you are good to go.

Test Your Skills
Beginner Level

CSS Flexbox & Grid Mastery

Test your knowledge and reinforce what you've learned in this article.

20/15
Questions
10 min
Duration
Start Quiz
Md Nasim Sheikh
Written by

Md Nasim Sheikh

Software Developer at softexForge

Verified Author150+ Projects
Published:

You May Also Like