In this series we've looked at some simple ways theme developers can help make their theme accessible. If you follow all the recommendations in this series, you will more than exceed the minimum requirements for the accessibility-ready tag in the WordPress theme repository.
However, the tag is accessibility-ready rather than accessible, as no theme can ensure a website is accessible—too much relies on how the theme is used, and the nature of the content added to the site.
In this final tutorial we look at some simple techniques that we as theme developers could employ, to help the end users of our product use it in an accessible-friendly manner. There is also a lot scope for plugin developers to do likewise (an obvious example being a plugin which allows an audio file to be uploaded and attached to a custom post type could also allow a transcript to be uploaded and linked to that file).
Encouraging a Valid Header Structure
Earlier in this series we discussed ensuring the theme has a reasonable header structure, namely appropriate headings for the site title and post title(s). As mentioned, this structure should meaningfully reflect the page structure, and the <h1>
tags should be nested in <h2>
tags, <h2>
tags in <h3>
and so on.
But, on any given page, if we have used the <h1>
(and maybe <h2>
) tag outside the page or post's content, it would be a good idea to discourage their use inside the content, so as to prevent breaking that page structure. TinyMCE has a 'blockformat' dropdown which allows users to quickly add paragraphs and headings and so forth. We can remove the header tags which we don't want used in the post content:
function mytheme_tinymce_init( $init ) { // Set the block format elements you want to show in dropdown. Default is p,h1,h2,h3,h4,h5,h6 $init['theme_advanced_blockformats'] = 'p,h2,h3,h4,h5,h6'; return $init; } add_filter('tiny_mce_before_init', 'mytheme_tinymce_init' );
Of course, this isn't foolproof, and will be ineffective against users who don't use the TinyMCE editor. Additionally, it does not (and we cannot) ensure that the headers used in the content meaningfully reflect the structure of that content. It does, however, discourage the misuse of the reserved <h1>
(and <h2>
) tags.
Encouraging Good Colour Contrast
A slightly more involved idea, if allowing users to select their own colours in the theme, is to alert them when they are selecting colours with a low contrast rating (e.g. background and text colours). Exactly which colours you should be comparing will depend on the choices you've made available to the user. Below I've simplified this idea by assuming a fixed font-colour of #444444
, and comparing this with the user-provided background colour.
I'll leave the details of how to set up fields in the customiser, and to enable live previews to the codex. Here I just provide an example JavaScript file which alerts the user when their chosen background colour is too low.
First create a file called customizer-a11y.js
in your theme, with the following code:
( function( $ ) { //Update site background color... wp.customize( 'background_color', function( value ) { value.bind( function( newval ) { //Get value to compare the background colour with. var textcolor = '#444444'; //Calculate the contrast ratio - we provide this later var ratio = mytheme.checkContrast( textcolor, newval ); //Depending on the font-size you may wish to adjust the ratio breakpoints. if( ratio >= 5 ){ //Very good contrast ratio, hide the ratio warning $('#contrast-warning-bgcolor').hide(); }else if( ratio >= 4.5 ){ //Contrast is good, but getting close, display the ratio $('#contrast-warning-bgcolor').css( 'background', '#3AC469' ).show(); }else if( ratio >= 3 ){ //Contrast is poor $('#contrast-warning-bgcolor').css( 'background', '#FFA634' ).show(); }else{ //Contrast is very poor $('#contrast-warning-bgcolor').css( 'background', '#E31837' ).show(); } //The warning message is stored in mytheme.warningMsg - we'll add this later var text = mytheme.warningMsg.replace( '%f', ratio ); $('#contrast-warning-bgcolor').text( text ); } ); } ); } )( jQuery );
Next we need to create a function which, given any two colours (in hex) format, returns the contrast ratio between them. Details of calculating this ratio can be found on the W3C website, but it is done by first calculating the "relative luminance" (roughly speaking a measure of "brightness". The contrast ratio is then the ratio of those "relative luminance" values, with an added 'penalty' for bright colours.
The following should live at the bottom of the JavaScript file just created.
mytheme = { /** * Calculate the relative luminance of two colours * @param string color the foreground (text) colour * @param string bgcolor the background colour * @returns float The relative luminance of the colours */ checkContrast = function( color, bgcolor ) { var L1 = this._getLuminance( color ); var L2 = this._getLuminance( bgcolor ); return ratio Math.round((Math.max(L1, L2) + 0.05)/(Math.min(L1, L2) + 0.05)*10)/10; } /** * Calculate luminance of a colour * @param string color in Hex format * @returns float luminance of the colour */ _getLuminance = function( color ) { var R,G,B; //Remove hash tag if present color = color.replace(new RegExp("^[#]+"), ""); if( color.length == 3 ) { R = this._getRGBScore( color.substring(0,1) + color.substring(0,1) ); G = this._getRGBScore( color.substring(1,2) + color.substring(1,2) ); B = this._getRGBScore( color.substring(2,3) + color.substring(2,3) ); }else { R = this._getRGBScore( color.substring(0,2) ); G = this._getRGBScore( color.substring(2,4) ); B = this._getRGBScore( color.substring(4,6) ); } return (0.2126 * R + 0.7152 * G + 0.0722 * B); } /** * Calculate the RGB score according to http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G18 * @param color * @returns float */ _getRGBScore = function( color ) { try { color = parseInt( color, 16 ); //Hex to decimal }catch (err) { color = false; } if( color !== false ) { color = color/255; color = (color <= 0.03928) ? color/12.92 : Math.pow(((color + 0.055)/1.055), 2.4); } return color; } }
Lastly we load the JavaScript and print the mark-up for the contrast warning notice.
function mytheme_customizer_live_preview(){ echo '<div id="contrast-warning-bgcolor" role="alert" ></div>'; echo '<style> #contrast-warning-bgcolor{ position: fixed; right: 30px; top: 31px; background: #fff; border: 2px solid #000; color:#000; display:none; } </style>'; wp_enqueue_script( 'customizer-a11y', get_template_directory_uri().'/customizer-a11y.js', array( 'jquery','customize-preview' ), '1.0', true ); //Make the warning message available in our JavaScript file. wp_localize_script( 'customizer-a11y', 'mytheme', array( 'warningMsg' => esc_html__( 'Colour contrast warning. Ratio: %f', 'mytheme' ), )); } add_action( 'customize_preview_init', 'mytheme_customizer_live_preview' );
Summary
We have covered only a couple of suggestions in detail here, but the list could go on. There is also a lot of scope for plugin developers to do likewise:
- Form plugins could discourage the use of empty labels.
- Slider plugins could discourage the use of the auto-play option.
- Whenever an audio/video file is to be uploaded and attached to a custom post type, a plugin could prompt for a transcript to also be uploaded and linked to that file.
"Discourage" here doesn't mean removing the option entirely. However, alerting the user of the ramifications to the accessibility of the website can go a long way to educating the user, and ultimately improving web accessibility.
Resources
We finish this series with an overview of useful resources and tools to help you learn more about web content accessibility, and more importantly to help you ensure that your next plugin or theme is available to all users.
Websites
WordCamp Talks
- Practical WordPress Accessibility by Bram Duvigneau
- Good Habits: Coding for Accessibility by Joe Dolson
(Other talks can be found at http://wordpress.tv/tag/accessibility/)
Tools / Plugins
- Access Monitor: WordPress plugin which tests your site for accessibility compliance via Tenon.io.
- WP Accessibility: WordPress plugin which addresses some common accessibility issues with WordPress.
-
Accessible Dropdown Menus: WordPress plugin to ensure drop-down menus are keyboard accessible.
-
Contrast ratio: A site to calculate the contrast ratio of two colours.
-
Bootstrap Accessibility: Addresses some accessibility issues with Bootstrap.
Comments