title | description | category | author | date | further_reading | tags | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Text Contrast on Dynamic Backgrounds |
Use text shadows to guarantee color contrast |
How-to |
Conor Kelly |
2023-05-02 |
|
|
Short answer: Use text-shadows or additional background colors on text elements which overlay non-static backgrounds or which may potentially overlay a background color of insufficient contrast.
When designing and styling text elements, it is important to maintain a color contrast ratios to ensure its visibility, as per Web Content Accessibility Guidelines (WCAG) 2.1.
Small Text | Large Text | |
---|---|---|
AA | 4.5:1 | 3:1 |
AAA | 7:1 | 4.5:1 |
Using Adobe's (free) Color Contrast Analyzer we can quickly check if our colors are sufficiently contrasting.
Designers and developers are not always in control of what renders beneath text elements, often thwarting our well planned color pallet. Such cases include but are not limited to:
- Text overlaying static images
- Text overlaying parallaxing images
- Text overlaying video
- Fixed or absolute text scrolling over different background colors
- Responsive layouts shifting text over different background colors
Typography in film / TV / video provide us with a few techniques to ensure our text is always legible:
- Include a background element behind the text element
- Outline the text with a border
- Apply text-shadow(s)
Setting up text elements with a fixed background is a relatively simple approach, wherein the background may be translucent to avoid occluding other content. These background elements can either be styled as standard rectangles or as decorative overlay graphics.
Using a background element is a simple approach, but it does require some additional markup and styling.
<!-- index.html -->
<div class="container">
<video ...></video>
<div class="text-container">
<h1>hello world</h1>
</div>
</div>
Be sure to set the background color and padding on the text container, not the text element itself, to ensure the text does not touch the edges of the background element.
/* styles.css */
.container {
position: relative;
}
.text-container {
position: absolute;
padding: 1rem; /* optional but suggested */
top: 1rem;
left: 1rem;
background-color: rgba(0, 0, 0, 0.5);
}
Less obtrusive than backgrounds, developers can apply text shadows to ensure legibility. Text shadows can be applied to any text element, including those with transparent backgrounds.
Even adding a single text shadow can help ensure legibility.
<!-- index.html -->
<div class="container">
<video ...></video>
<h1>hello world</h1>
</div>
<!-- style.css -->
<style>
.container {
position: relative;
}
h1 {
position: absolute;
top: 1rem;
left: 1rem;
text-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.5);
}
</style>
When using multiple, comma-separated text shadows, the shadows are rendered in the order they are declared. This allows us to create a border-like effect around the text by applying a shadow with a blur-radius of 0.
Be sure to offset your shadows by at least 1px to avoid the shadow being clipped by the text element, and to offset the shadows in different directions to create a border-like effect.
/* styles.css */
.container {
position: relative;
}
h1 {
position: absolute;
top: 1rem;
left: 1rem;
text-shadow:
1px 1px 0 rgba(0, 0, 0, 0.5),
-1px -1px 0 rgba(0, 0, 0, 0.5),
1px -1px 0 rgba(0, 0, 0, 0.5),
-1px 1px 0 rgba(0, 0, 0, 0.5);
}
(Warning: the following recommendation is a bit of typography crime!)
Designers can create highly contrasting display text by giving the characters a stroke. If possible, an added stroke should always be applied to the outside of the characters (vs centered or inside) to preserve the shape, integrity, and legibility of the typeface. Additionally, such strokes should have rounded corners to avoid strange stroke rendering around the corners of the text.
This effect cannot be reproduced by CSS styling, so designers and developers will have to export the display text and bring it in as an image.