Accessible Textboxes
It may surprise a lot of people that you can make editable textboxes without JavaScript and without using
<input type="text">
or <textarea>
tags.
Why would you use the ARIA method? I can see two reasons:
- Maybe because you can't use
::before
or::after
pseudo-elements to style form elements, although there are other ways around this without using ARIA. - If you wanted to create a WYSIWYG editor then you would have to do this, since form elements don't allow the editing of formatted text.
This last use case we do not cover, since creating an accessible WYSIWYG editor would involve quite a bit of JavaScript (I will be adding a page in Enable about WYSIWYG editors in the future).
HTML example
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 makes the example accessible.
ARIA example
Keep in mind that if you use this in a form, none of the nice free form functionality (e.g.: HTML5 validation, inclusion of data when submitting a form in an HTTP request, etc), won't work. These example do, however, show up in Voiceover's Rotor and NVDA's Element Dialogue.
- No JavaScript was involved in making these (you would need to use JavaScript, though, to make a true WYSIWYG editor).
- The first example is simply a
div
with itscontenteditable
attribute set to"true"
. Textareas can be simulated usingaria-multiline="true"
and using CSSresize: both
to make them resizable. - The element will not submit its data to the server like a real form field.
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 makes the example accessible.
Textbox With Character Counter
The character counter is visible at all times. It is announced to screen reader users when:
- They use the keyboard to access the textbox (e.g. using the TAB key).
- When there are
n
characters left before the textbox is filled, wheren
is either 20 (the default value) or the value used in the textbox'sdata-warning-threshold
attribute.
The character counter uses a JavaScript library to implement it. Below is the HTML markup needed for it to work, as well as instructions on how to load the library in your own projects.
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 makes the example accessible.
Installation Instructions
You can load this JavaScript library into your application in serveral 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 obviously 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 enableCharacterCount from '~enable-a11y/js/modules/enable-character-count'; // How to initialize the enableCharacterCount library enableCharacterCount.init();
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 enableCharacterCount = require('enable-a11y/enable-character-count').default; ... enableCharacterCount.init();
- You will have to include the CSS as well in your project's CSS using:
@import '~enable-a11y/css/enable-character-count';
Using ES6 modules natively.
This is the method that this 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/enable-character-count.js
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 you document:
<html> <head> ... <link rel="stylesheet" href="path-to/css/enable-character-count.css" > ... </head> <body> ... </body> </html>
-
Load your scripts using:
<script type="module"> import enableCharacterCount from "path-to/enable-character-count.js" enableCharacterCount.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/enable-character-count.js"></script>