CSS Text Outline: How to Make Creative Typography Stroke

In the intricate world of web design today, typography serves as a powerful means of expression, improving site usability and it goes beyond the realms of font choice and sizes. In this article weāll explore a sub-section of Web Typography, that is, dealing with CSS text outline, also known as typography stroke, along with the various methods we can follow to achieve stroke effect in CSS.
Web typography, often referred to as web text, constitutes a form of vector-based graphics within the digital landscape. This characteristic enables web typography to scale seamlessly, mirroring the behaviour of standard Scalable Vector Graphics (SVGs). The scalability of web typography is a key feature that ensures optimal visual experiences across a diverse range of devices and screen sizes.
In essence, the vector-based nature of web typography means that the characters are defined by mathematical equations rather than fixed pixels. This inherent flexibility allows text elements to adapt gracefully, maintaining clarity and legibility whether viewed on a small smartphone screen or a large desktop monitor.
Since weāve established that Web typography is essentially vector-based graphics, then Web typography should also be able to do things just like design software that deals with vector-based graphics would, e.g. Adobe Illustrator.
What is Text Outline or Typography Stroke?
In the context of design, a āstrokeā typically refers to the outline of a shape or text element. It is a visual attribute that adds a defined boundary to a shape or text, helping it stand out and providing emphasis. Meanwhile, a āfillā refers to the interior area of a shape or object that is enclosed by its outline or border. It is the part of the element that is solid or filled with colour, pattern, or texture.
In the realm of typography, a ātext strokeā or ātypography strokeā or ātext outlineā specifically refers to the outlined border around the characters of a text.
Hereās an image that illustrate where the stroke and fill are located:

With CSS (Cascading Style Sheets), strokes can be applied to text using properties such as text-stroke, enhancing the visual appeal of typography on the web. These strokes can be customised to achieve different effects, contributing to the overall aesthetic and readability of the text. Whether itās a subtle accent or a bold statement, understanding and utilising strokes play a crucial role in graphic design and digital communication.
Stroked Typography in CSS
In CSS, stroked typography can be created in three methods:
Using the non-standard webkit-text-stroke property
Using text-shadow property
Using pseudo-element hack
Using the non-standard webkit-text-stroke property
The webkit-text-stroke property is a non-standard CSS property that is used to apply width and color of strokes or outlines to text characters. Itās a shorthand property for the longhand properties -webkit-text-stroke-width and -webkit-text-stroke-color.
The example below is equivalent:
-webkit-text-stroke: 4px navy;
OR
-webkit-text-stroke-width: 4px;
-webkit-text-stroke-color: navy;
Hereās an example of how you can use -webkit-text-stroke property:
/* CSS file */
h1 {
/* Apply a black stroke with a width of 2 pixels */
-webkit-text-stroke: 2px black;
/* Set the text fill color to white */
color: white;
/* Optional: Adjust other styling properties */
font-size: 180px;
font-family: 'Arial', sans-serif;
text-align: center;
}
<!-- HTML file -->
<h1>Hello World</h1>
Preview

In this example, the -webkit-text-stroke property is applied to an h1 element, creating a black stroke around the text. The color property is set to white to ensure that the text inside the stroke is filled with a contrasting color.
From the example above, everything seems to work fine, but letās say we increase the -webkit-text-stroke-width property value to 20px and change the color to red to see the effect properly.
/* CSS file */
h1 {
-webkit-text-stroke-width: 20px;
-webkit-text-stroke-color: black;
color: red;
font-size: 180px;
font-family: 'Arial', sans-serif;
text-align: center;
}
Preview

Wow, now the text starts looking really ugly and misshapen. This is because the stroke is positioned above the fill and resides within the confines of the text. In simpler terms, the stroke is above the fill or color of the text, placed in the center of the text. So how do we fix this?
The sad reality is that thereās no proper fix for this issue yet, as of 2023, and even design software like Adobe Illustrator has this same problem, where with texts, you canāt change the alignment of the stroke from being centered.
Hereās a GIF to illustrate the same issue with Adobe Illustrator 2022.

However, thereās a property that kinda fixes this issue, but as of 2023, it only works on Firefox browser. The CSS property is called paint-order, which helps to control the order in which the fill and stroke text content are drawn. With the paint-order CSS property, the stroke will be placed outside the text color or fill.
Hereās how it looks on Firefox browser (Windows)

Hereās what changed in the CSS file, and all we introduced was paint-order: stroke which does the magic.
/* CSS file */
h1 {
-webkit-text-stroke: 20px black;
color: red;
/* Set Paint-Order property */
paint-order: stroke;
font-size: 180px;
font-family: 'Aria', sans-serif;
text-align: center;
}
Notice on Firefox browser, the stroke corners are curved by default.
On Google Chrome browser, the result remains the same, the paint-order property has no effect at all, sadly š.
Hereās the CodePen link if youād like to preview it for yourself.
The -webkit-text-stoke, -webkit-text-stroke-width, and -webkit-text-stroke-color CSS properties all have good support in major browsers, and according to caniuse.com it has 96.89% support across all major browsers as of November 2023.
Pros
Easy to use, as it requires a single property
Cons
Achieving a satisfactory result can be challenging when combining a colour and a stroke.Though the paint-order property helps, but itās only supported in one browser.
Being a non-standard property, thereās a possibility that it might be removed and substituted in future updates. Additionally, there could be variations or inconsistencies across different browsers.
Using text-shadow property
The text-shadow method is more of a hacky solution, where multiple shadows with different offsets can be used to simulate the text stoke. With the approach, we are guaranteed that the simulated stroke with shadows would also be beneath the text content at every point.
If you think about it, weāll need the shadows to cover every direction of each character in the text, i.e. top, right, bottom, and left. Letās see an example:
/* CSS File */
h1 {
/* Simulate text-stroke with multiple shadows */
text-shadow:
1px 1px 0px #000, /* Bottom right */
-1px -1px 0px #000, /* Top left */
1px -1px 0px #000, /* Top right */
-1px 1px 0px #000; /* Bottom left */
/* Optional: Additional styling */
color: #fff; /* Text color */
font-size: 180px;
font-family: 'Arial', sans-serif;
text-align: center;
}
Preview

See the preview on CodePen
In this example, the text-shadow property is used to create a simulated text-stroke effect by applying shadows in each direction. Additionally, the shadows have a 0px blur radius (0px), ensuring a crisp outline.
Also, looking at the preview, it looks pretty close to what we had first with the -webkit-text-stroke property, but thereās a challenge, how do we tell what the offset X and Y length values should be? Letās say we increased the offset X and Y length values to 3px. So, letās see what happens:
/* CSS File */
h1 {
/* Simulate text-stroke with multiple shadows */
text-shadow:
3px 3px 0px #000, /* Bottom right */
-3px -3px 0px #000, /* Top left */
3px -3px 0px #000, /* Top right */
-3px 3px 0px #000; /* Bottom left */
/* Optional: Additional styling */
color: #fff; /* Text color */
font-size: 180px;
font-family: 'Arial', sans-serif;
text-align: center;
}

Hereās the CodePen link to preview
With keen eyes, youād notice that there are gaps in some characters of the text, like the āeā and ārā. To help show the gap, here is the same image but zoomed in.


To fix the gaps, weāll need to add more shadows, but then this method isnāt sufficient cause youād likely be guessing the shadow offset would be tedious, except youāre a maths wizard š . Hereās an article that shows how using 8 multiple shadows solved the gap problem.
Pros
It works properly when the offset X and Y length values are just 1px.
It is widely supported across all major browsers
Cons
Introduces gaps in the simulated stroke effect if the shadow X and Y offset is greater than 1px
Itās too hacky cause youād have to guess the shadow offsets.
Strokes arenāt shape as it should, they may appear blurry.
Using pseudo-element hack
With the help of pseudo-elements, we can simulate the text stroke effect by creating a copy of the text content and then apply the -webket-text-stroke property to the pseudo-element. With the attr() CSS function and data-* attribute, we can achieve the text stroke effect.
Enough explanation; letās see an example to understand how to utilise the pseudo-element hack.
<h1 data-text="Hello World">Hello World</h1>
The data-* attribute is used on the HTML element in order for the attribute value āHello Worldā to be gotten from CSS with the help of the attr(). Hereās how we get the data-text attribute value in CSS.
h1 {
color: red;
font-size: 180px;
font-family: 'Aria', sans-serif;
position: relative;
}
h1::after {
/* data-text atrribute value gotten as the content value in CSS */
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
/* Place the pseudo-element below the actual text */
z-index: -1;
/* Relative to h1 */
font-size: 1em;
-webkit-text-stroke: 20px black;
}
Preview

Hereās the CodePen link
In the example above, we had a lot of properties flying around, like the position relative and absolute values. On the h1 CSS type selector, notice the position: relative CSS declarion, itās very important, cause the h1 pseudo element selector would be positioned absolute to the h1 element. Also, the top, and left property has the value 0.
The issue with the pseudo-element hack, is that if the h1 selector changes its position, letās say the text is aligned to the center, the text stroke effect breaks. Hereās an example to see how it breaks:
h1 {
color: red;
font-size: 180px;
font-family: 'Aria', sans-serif;
position: relative;
/* New CSS declaration added */
text-align: center;
}
h1::after {
/* data-text atrribute value gotten as the content value in CSS */
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
/* Place the pseudo-element below the actual text */
z-index: -1;
/* Relative to h1 */
font-size: 1em;
-webkit-text-stroke: 20px black;
}
Preview

Pros:
Effectively generates a stroke around the text.
The stroke adjusts proportionally when the font-size of the element (e.g., an h1 tag) changes.
Cons:
Requires duplicating text content in a custom attribute.
Shares similar drawbacks with -webkit-text-stroke-width when used for stroke creation, potentially requiring mathematical adjustments to avoid using this property.
Issues may arise when the element alignment is changed.
Combining text-stroke and text-shadow Properties
Combining the text-stroke and text-shadow properties in CSS opens up a realm of possibilities for creating visually compelling and dynamic text effects. These properties, when used in conjunction, allow for intricate and layered styling, enhancing the overall aesthetic impact of your typography.
Here are some examples showcasing how you can combine text-stroke and text-shadow.
Example 1
h4 {
/* Apply a text-stroke with a white color and a width of 2 pixels */
-webkit-text-stroke: 2px white;
color: black; /* Set the text color */
/* Add a subtle text-shadow for depth and dimension */
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
/* Optional: Additional styling */
font-size: 180px;
font-family: 'Arial', sans-serif;
text-align: center;
}
In this example, the -webkit-text-stroke property is used for the text-stroke effect, creating a white outline around the text characters. The text-shadow property is then applied to add a subtle shadow, providing depth and dimension to the text.

Example 2
To peek at the code used to achieve this example, hereās the CodePen link:

Example 3
Hereās the CodePen link, for the Neon effect:

Creative Typography Stroke Examples
Letās look at more examples that are creative:
Example 1

<h1>Stroke</h1>
body {
background: black;
}
h1 {
background-image: linear-gradient(90deg, #ff00d2, #fed90f, #00a2ff);
background-clip: text;
-webkit-text-stroke-color: transparent;
-webkit-text-stroke-width: calc(1em / 16) ;
-webkit-background-clip: text;
color: #000119;
font-size: 22vmin;
font-weight: 700;
text-align: center;
}
This stroke effect is referenced from the video by SoftCode
Example 2

<h1>Lemon</h1>
@import url('https://fonts.cdnfonts.com/css/spicy-rice');
body {
background-image: url(https://st3.depositphotos.com/5489530/13659/i/600/depositphotos_136593476-stock-photo-lime-and-mint-detox-water.jpg);
background-color: #5DB318;
background-size: cover;
background-repeat: no-repeat;
background-position: bottom bottom;
}
h1 {
color: rgba(154, 41, 162, 0);
font-family: "Spicy Rice", Sans-serif;
font-size: 165px;
font-weight: normal;
text-shadow: -6px 10px 0px #5DB318;
mix-blend-mode: darken;
-webkit-text-stroke: 2px #FFFFFF;
text-stroke: 2px #FFFFFF;
text-align: right;
}
The stroke effect was reference in happyaddons website
Browser Support For text-stroke Property
According to caniuse.com, 96.89% of all browsers support the -webkit-text-stroke property except for all versions of Internet Explorer browser and Opera mini browser. However, the other browsers support the text-stroke property by making use of the webkit prefix to ensure compatibility.

Wrapping Up
In wrapping up our look at text-stroke in CSS, weāve covered a few cool ways to make your text stand out. Whether youāre using the -webkit-text-stroke property for a basic outline, getting creative with pseudo-elements, or adding depth with text-shadow, these methods give you options to make your typography pop. In addition, each approach has its strengths, offering flexibility for different design needs. So, play around, try them out, and let your text be a canvas for your creativity!
Here are also some helpful resources about the text-stroke:



