Advanced Text Resizing
For text inside hero images to be considered accessible, they must conform to the following guidelines:
- They must not be "hard-coded" into the image in order to conform to WCAG 1.4.5 - Images of Text.
- They must adhere to the contrast requirements of WCAG 1.4.3 - Contrast (Minimum)
- They must accommodate the adjustable text-spacing guidelines of WCAG 1.4.12 - Text Spacing.
- They must be resizable via a browser's text zooming feature to conform to WCAG 1.4.4 - Text Resize.
The first item is easily resolved: just use "live" HTML text. Checking contrast is covered in the Text Contrast Strategies section of Enable. The final two requirements, though, can bring up some hard, mind-numbing issues that I have seen over and over again, so I thought I'd show how I've fixed these.
Text Zooming Issues
Consider this screenshot of a typical desktop-sized hero image:
is a Turkish film actor, director, producer and martial artist. He is widely considered one of the most prominent Turkish actors of all time. Arkın's films have ranged from well-received dramas to mockbusters throughout his career spanning four decades.
Learn moreIt is easy to render this text via HTML. The design even accommodates text spacing requirements: when I apply Steve Faulkner's text spacing bookmarklet, the text fills the hero image.
However, things break down when I try to resize the text. Here is what the hero image looked like when I applied 150% text zoom on the page:
This is typical of a lot of hero images on the web. It's so common that I created a JavaScript library to work around this issue. When the text is resized using the browser's text-zooming feature, the layout changes to accommodate the larger text:
How does this work? When the user resizes text on the screen using the browser's text zooming functionality,
the JavaScript library adds the text-zoom
class on the body
tag. Additional styles
were created to adjust the layout of the hero.
Code Walkthrough of the Above Example
Below is the HTML of the above example. Use the dropdown to highlight each of the individual steps that make the example accessible.
Installation Instructions
You can load this JavaScript library into your application in several ways:
- as an ES6 module using Webpack.
- as a CommonJS module using
require()
and Webpack. - as a native ES6 module within the browser.
- as an old-school ES4/JavaScript library.
If you haven't done so already, choosing which you should use is a major architectural decision. Here are a few articles that will help you decide:
- Jan Olaf Krems gives a great overview of the JavaScript file format differences.
- Joe Honton discusses that with ES modules and HTTP/2, you may not need Webpack anymore
- Stack Overflow has a really good thread about Webpack vs. ES6 modules as well.
Using NPM/Webpack to load ES6 Modules:
-
Install the
enable-a11y
NPM project. -
Edit your webpack.config.json file to resolve the
~
modifier by adding the following:module.exports = { ... resolve: { extensions: ['.js', '.jsx', '.scss', '.css', '*.html'], modules: [ path.resolve('./src/js'), path.resolve('./node_modules') ], alias: { '~enable-a11y': path.resolve(__dirname, 'node_modules/enable-a11y') }, ... }, ... }
-
You can use the module like this:
// import the JS module import textZoomEvent from '~enable-a11y/js/modules/textZoomEvent'; // import the CSS for the module import '~enable-a11y/css/textZoomEvent'; // How to initialize the textZoomEvent library textZoomEvent.init();
-
Alternatively, if you are using LESS you can include the styles in your project's CSS using:
@import '~enable-a11y/css/textZoomEvent';
.css
suffix)
Using NPM/Webpack to Load Modules Using CommonJS Syntax
-
Install the
enable-a11y
NPM project. -
You can import the module using
require
like this:var textZoomEvent = require('enable-a11y/textZoomEvent').default; ... textZoomEvent.init();
- You will have to include the CSS as well in your project's CSS using:
@import '~enable-a11y/css/textZoomEvent';
Using ES6 modules natively.
This is the method by which the page you are reading now loads the scripts.
- Grab the source by either using NPM, grabbing a ZIP file, or cloning the enable source code from GitHub.
-
If you want to load the module as a native ES6 module, copy
js/modules/textZoomEvent.js
, andcss/textZoomEvent.css
from the repo and put them in the appropriate directories in your project (all JS files must be in the same directory). -
Load the CSS in the head of your document:
<html> <head> ... <link rel="stylesheet" href="path-to/css/textZoomEvent.css" > ... </head> <body> ... </body> </html>
-
Load your scripts using the following code (NOTE: you must use
<script type="module">
):<script type="module"> import textZoomEvent from "path-to/textZoomEvent.js" textZoomEvent.init(); </script>
Using ES4
Just do the same as the ES6 method, except you should get the JavaScript files from thejs/modules/es4
directory instead of the js/modules/
:
<script src="path-to/es4/textZoomEvent.js"></script>