Author: Phil

Accessibility fundamentals. AKA building, designing and writing for real people.

How many sites do you visit that are full of indecipherable jargon? Littered with cringe worthy stock images, confusing layouts, and slow to load? Beautiful but functionally flawed. How many of the sites you’ve built are like that? Own up – we’ve all done it… (although hopefully not ticking all those boxes at once!)

We’re all part of the problem – we’ve lost sight of the purpose of the sites we build. It’s all about users, not us; we are definitely not “average users”.

The problem

Accessibility is often an afterthought, maybe a token aria-role and not much more. But accessibility effects us all and permeates every aspect of a website. Accessibility isn’t about disability. That’s not to say that you shouldn’t be making your site accessible to the disabled, but accessibility is about everyone.

Every decision we make about development, design and content effects whether people can understand and use your site. Unfortunately many common practices are hampering our users. It’s not hard. It’s just thoughtlessness, and it’s affecting your bottom line.

Here’s a few of the common problems:


Undeniably the low hanging fruit – we’ve all seen, or heard of, designs that are beautiful but frustrating, or even impossible, to use. Pick any trend in web design and there are myriad bad implementations that hinder users:

  • Big images (full screen background images, sliders, “hero” images etc) – without careful implementation these often cause bloated page sizes that drive away limited bandwidth users and can also create artificial “folds” that can confuse people into thinking there isn’t any other content on a page. Worse still, when these images aren’t appropriate and conveying meaning, they can stop users from even being able to tell what your site is about.
  • Undifferentiated links – there’s a reason browsers without exception all style links in blue and underlined, it’s the standard. Users are smart: change that shade of blue, fine; change the colour completely to one that stands out from normal text, normally OK; drop the underline, fine; but while changing the colour to be the same as normal text and omitting the underline looks much less “messy”, now no-one has any idea what to click on… The same goes for buttons – “ghost buttons” with no border or background to differentiate them are a bit of a fad lately. I’ve watched too many user-testing videos of people blindly clicking on any object and text as they have no indicator to tell them what is a link / button and what isn’t.

But more problematic are the widely accepted design patterns that fundamentally exclude users:

  • “Hamburger” menus (especially on desktop) – yes we all know what they are, but have you actually thought about the rest of your users? Older and less technologically inclined ones in particular are still completely stumped by sites with ‘missing’ menus. “Lots of sites use them” is not a valid response… Lots of sites are also driving away potential users.
  • No home button – like the hamburger menu, omitting a home link in the menu is normally justified because “everyone knows you just click on the logo”. But what is really being said is ‘we in the web industry all know to click on the logo and so do the web savvy users’, but what about the rest? Would you really build a hotel with no signs to reception because ‘everyone knows it’s near the dining room’?


Code has its biggest effect on accessibility by affecting the usability of assistive technologies.

You’re doing it wrong if:

  • You can’t understand your site when viewing it in outline mode (without styles and images). NB – unfortunately this got more complicated recently with the admission in the HTML5.1 spec that browser support for the document outline model in HTML5 hasn’t appeared.
  • You can’t perform basic navigation of your site using just the keyboard. This is critical for everyone from power-users to those with extreme physical disabilities whose assistive technologies normally mimic simple keyboard commands. Strongly tied to this is a design point – removing :focus and :active styling is a really bad idea and leads to keyboard users getting lost on the page.


This isn’t complex in theory, write clear and concise text and you’re done. If you’ve got images or other media then insert them at appropriate points in the flow of text to give them implicit meaning, and ensure that they are relevant and adding meaning / value themselves.

I’ll leave aside the strange desire some companies have for making their website a copy of corporate documents; even if your audience is one coming to view (for example) legal documents, they wouldn’t expect your ‘About’ page to read like one.

But in practice this is more complex than it at first seems. Users abilities fall into a range of categories (including but not limited to):

  • Specialists with knowledge of industry specific terminology (jargon to the rest of us).
  • Educated general public – this can be educated in the sense of general education / intelligence level, and / or those slightly informed about a specific topic.
  • Novices – those with no prior knowledge of a subject, yet who have a reason to access it (even if it is only curiosity).
  • Those in any other category where their ability to access the content is physically impaired, for example a level of visual impairment.
  • Those in any other category where their ability to access the content is mentally impaired, for example someone with dementia who has trouble holding large amounts of information in their working memory.
  • Those in any other category who have a primary language other than the one the content is written in.

Writing while meeting the needs of all these groups is no easy task. Even a sentence as simple as “watch out for trouble” hides problems. Metaphors, idioms, phrasal verbs (there’s a good article on the problems with these specifically on GOV.UK) and other literary devices can all cause problems for users. While they may sometimes be the most appropriate way to phrase something, you should be aware of them and the problems they can cause. Imagine someone reading that example sentence literally…

Personally I find this by far the hardest section. A near final draft of this post scored a distinctly average 10 on Hemingway and a 54.3 for Flesch-Kincaid Reading Ease on Readability-Score.

The beginning of a solution

Rant over. So how do we make our sites inclusive and accessible? There’s no magic bullet, and every site is different and will need tailoring to it’s own audience.


However this list is a good starting point. In fact if you can follow most of these, you will make a big difference and help keep the web accessible to everyone.

Make it Perceivable

  • Give links and buttons clear visual differentiation. Conforming to traditional patterns unless there is a strong reason not to.
  • All link states should have clear styling including :focus and :active.
  • Link and button text should always explain what it does when read out of context. Use screen-reader only content if absolutely necessary.
  • Buttons must be large enough for users on touch devices.
  • Colour should never be the only differentiator between two states / meanings.
  • Text contrast must conform to AA WCAG2.0 guidelines, always attempt to reach AAA level.
  • Avoid overlaying text on images or backgrounds that affect readability.
  • Provide text alternatives for non-text content.
  • Use semantic code to convey the structure and relationships of content sections. Structure must remain meaningful when viewed without stylesheets and javascript, and also when read by screen-readers.
  • Always give inputs labels even if using placeholder text. They can be visually hidden if desired.
  • Never disable browser zooming and use relative units for text sizing.

Make it Operable

  • You must be able to navigate the site with only a keyboard.
  • Focus should not move / be moved unexpectedly.
  • Provide ‘skip links’. At a minimum give a ‘skip to content’ link as the first item on the page.
  • Provide clear site navigation that is not hidden behind “hamburger” menus.
  • Include the homepage in the main navigation.
  • Use breadcrumbs to provide navigation at depth.

Make it Understandable

  • Always set the lang attribute on the page’s <html> element.
  • On your homepage <h1> should be the site title (it can be visually hidden). On all other pages it must be the page / content title.
  • Use regular semantic headings to keep content easily digestible and signposted.
  • Content and purpose should be clear and as concise.
  • Only use images and other media to add value and meaning to the text content. They must appear in an appropriate place so that it is clear what they relate to.
  • Keep content related to actions immediately next to each other, both visually and in the code.
  • Ensure there is a clear flow of content without unrelated
  • Avoid jargon where possible.
  • Use metaphors, idioms, phrasal verbs and sayings only when they are truly the most appropriate way to convey your meaning.
  • Abbreviations and acronyms should be avoided or have definitions available at every use.

I’ll leave you with this:

The goal, she stated, is a world where all apps are accessible, even in cases where it may seem unintuitive. As an example, she recited her experience in traveling to China and discovering an unknown object in her hotel room that appeared to be a fruit. Rather than sampling it, she took a photo of it and sent it to a friend, who identified the object as being a dragonfruit.

Girma noted she was only able to do that because the Camera app is accessible via Voice Over. Without considering such a scenario, one might imagine that a blind person wouldn’t need an accessible camera app because ‘why would a blind person take pictures?’

Haben Girma at WWDC16, via AppleInsider

Further reading:

New look – a focus on text and speed

Custom Creative has had a bit of a makeover. Now my time is largely spent on projects at Helpful Technology I have decided to move the focus of this site from marketing my services to the blog content. With this comes a renewed commitment to write more… good intentions at least.

While restructuring the site I decided it was time for a visual refresh too. Particularly due to the focus on reading a high performance theme was in order – I settled on Fastr (available on GitHub) and created my own fork. So far the changes are minor – styling tweaks for taste & accessibility, and support for some new WordPress features including title-tag & custom-logo.

Now Fastr lived up to is name anyway – with no JavaScript and minimal CSS it is already a high performance theme – but with a couple of plugins things really start to fly. This site has now hit the heady heights of 99% performance ratings on both Yslow and Pagespeed.

Page size for this sitePerformance scores for this site
The two main factors getting us here, after the theme, are Autoptimize and WP Super Cache.

Autoptimize concatenates and minifies HTML, CSS, and JavaScript; it can also inline and defer if chosen. This reduces file sizes and DNS lookups. Since this site is so lightweight I chose to inline all CSS as this can drastically reduce the time to first render and the apparent loading speed for users.

WP Super Cache creates static HTML versions of your site to save the latency and load of accessing the database to generate the site.

In front of the site there is also Varnish – this is hosted on Gandi’s PAAS which comes with Varnish pre-configured, I highly recommend them for anything not requiring a dedicated server – and then Cloudflare. As I have said however, most of the speed in this case actually comes from the plugins and theme itself.

I hope you like the new site – there’s bound to be some tweaks to appearance and configuration of the next few weeks, and hopefully more than a few posts.

Showing an Author only their comments in WordPress

Recently at Helpful Technology I was working on the new Foreign Office Blogs website – collapsing their massive WordPress multisite instance down into a standard single site install. When I say massive… it was 161 sites with 448 users spread across ~4500(!) database tables and nearly 5GB of files. Oh, and it’s multilingual too.

One of the big, and somewhat unexpected, challenges to workflow once it was merged was comments. As WordPress presents the number of comments in the admin bar as well as the admin menu, authors were getting confused about whether they had any comments to respond to / manage, or if they were for other authors. While on the Posts screen you do at least get a Mine filter so that you can view just your own posts (along with the standard All, Published, Draft and Bin/Trash), there is nothing similar for Comments.
Also, WordPress helpfully puts a big notification bubble next to Comments in the menu as well as in the admin bar that shows the total number of Pending comments – again, not Author specific.

Part 1 – the list of comments

This first issue is actually the easiest to deal with – there is a helpful hook pre_get_comments that allows you to modify the wp_query arguments used to generate the Comments list.
All that’s needed is a simple finction that does a couple of sanity checks to make sure you are on edit-comments.php and the user is an Author (Editors and above have the rights to view and manage others posts so affecting them doesn’t really make sense*) and then $query->query_vars['post_author'] = $user_ID; does the magic.

Part 2 – comment counts

Changing the comment counts is actually a lot harder as there is no hook you can use to manipulate it as simply. Internally WordPress uses wp_count_comments which takes a single (optional) argument, a Post ID. It’s all or nothing, so to speak – it either returns the comment counts for the whole blog, or for a single blog post. There is a filter which lets you inject replacement values into the function however, so we have a way in. We can create a duplicate of this function, and then use the duplicate as a filter for the core function to inject the comment counts for just the logged in user.
But how do you get the count for a single user? Comments are associated with posts not users… Here caching is going to be your friend. We first have to do a standard query for all posts by the user WP_Query( array('author' => $user_ID,'posts_per_page' => -1) );, and then loop over each post, get the comments, and add up the number. This is comparably intensive so we can store the results in a transient for a length of time that makes sense for your blog. One thing to watch out for is that wp_count_comments expects a stdClass Object so remember to cast the array just before returning it.

*You could take this further and read some custom meta from the current user that specifies which other users they manage to determine which to show, but that’s for another day…

Putting it all together

Either build this into a simple plugin or put it into your theme’s functions.php depending on your needs:

Bulk updating Cloudflare’s firewall rules

I’ve been using Cloudflare recently and overall it’s extremely straightforward, but there was one small fly in the ointment – the firewall settings.

Currently you can only enter single IPv4 addresses at once (ranges like x.x.x.x-x aren’t valid either). Luckily they have a very easy to use API so I put together a quick form that does a bulk update of your rules.

You can only do one “action” at once (whitelisting / blacklisting / removing), but if you need anything more complicated I’m surprised you’re here… The API is also smart enough that it doesn’t moan if you ask it to, e.g., whitelist an IP that is already whitelisted.

You can download it on GitHub, and as always pull requests are welcome.

RegEx to match / link Twitter usernames and hashtags

One of the things we do at Helpful Technology is provide digital skills training. As part of that we have a sandboxed Twitter style social network platform that allows users to get used to the medium and practice in a safe environment.

I’ve been re-building this system recently, and one feature we wanted to add was the automatic linking of usernames and hashtags. This is fairly simple to do with a bit of RegEx in PHP – and on WordPress you can just attach it to the filter called the_content to process all text before it is output and insert links as needed. The code could be put in a plugin, but here it’s written so you can just drop it in to your functions.php.

If you’re wondering about the ‘weird’ \p{X} statements – that’s using PHP’s unicode character properties to ensure all languages are matched.

Bash script to configure MySQL database and install WordPress

Updated 4/6/15 – now with added key/salt generation

When deploying a new WordPress site, there are two (potentially) needlessly time-consuming steps – logging in to MySQL to setup a new database and user, and then copying the WordPress files to the directory. The script below lets you do this in one step, pass in your database and basic WordPress settings, and it will configure MySQL and directly download WordPress to the server. A key benefit of this over a phpMyAdmin + FTP approach is that it will work over even ropey internet connections as the work is all done on the server itself.

A more advanced approach is to build a setup script based on WP-CLI, which allows the most customisation, but also needs more setup work and control over the server. If you always install the same plugins and themes – definitely look in to this.

How to use the script:

  1. SSH in to your server and navigate to the desired install directory (e.g. /var/www/domain/)
  2. Paste all of the following in to terminal and hit Return:
    curl -L -o '' && bash
  3. Enter your details when prompted
  4. (Exit / close the SSH connection, your done here)
  5. Navigate to your new site in a web browser to complete the normal WordPress installation steps

Here’s the raw script so you can see what it’s doing – feel free to Fork it or suggest improvements:

Colour schemes, plugins, expandrive

Very short post to share a few useful links from the weekend, all related to Sublime Text:

Panic apps “ssh key is not in a supported format” error

I recently started using Panic’s Coda as an alternative to Sublime Text, and it looks really slick – the inbuilt SFTP particularly could make a big difference to my workflow.

But I hit a snag pretty early – Coda wouldn’t accept my SSH key – neither would Transmit (a straight FTP app from Panic) – throwing a “ssh key is not in a supported format” error. Now they key definitely works – Terminal and Cyberduck were both fine with it.
There was nothing unusual about how the key was generated – it was under Yosemite in accordance with GitHub’s guidelines, and using a passphrase.

A quick search threw up quite a lot of similar problems, and plenty of different solutions – however none worked for me…

Luckily Panic give prompt support on Twitter and after a couple of suggestions found a solution that worked for me:

In fact I didn’t even need to use a ssh config file – but I have quite a simple setup at the moment. The important, and counterintuitive, part was to NOT select the key file, but enter the passphrase.
If that doesn’t work for you, and you’re getting SSH key errors in Coda or Transmit, there are a selection of other solutions in this thread.

UK GovCamp 2015

6am Saturday the 24th I headed down to London for UK GovCamp 2015 – an unconference centered on the public sector.

As usual the was a huge variety of topics pitched, and personally I really appreciated the lack of an “introductions” session – it got things moving much faster.

My day went sonething like this:

  • The other half of open source: wordpress, local GDS, github, APIs selfishness. Hosted by @simond and @danmaby
  • Content strategy at scale. Hosted by @tomhewitson
  • Stop me before I hack your website! and “How to do wordpress securely”. Hosted by @edent and @harrym
  • Security screw-ups. Hosted by @glynwintle
  • Corridor session catching up and drinking tea

Now this isn’t a full write up of the event, or even my day, but there’s a few things to highlight:

  • GDS hasn’t filtered down to Local level. One was to tackle this, since Local Gov. is focussed around transactions, is to build a new middleware framework to integrate font- and back-end systems. Another tack would be a build an extensible platform, along the lines of WordPress, that could deal with creating and managing the front-end and integrate with any necesary back-end system.
  • You must pentration test your site – reapeat 10 times. Particularly authoritative domains, which are high value for spammers in particular – watch for comment and hidden link spam. Think of it like an annual gas check – not a one off.
  • A domain is for life, not just for… Orphaned domains can be re-registered by people with nefarious intents. This is especially dangerous if your domain is widely linked to, made even worse if they are authoratative themselves – there were some really nasty examples like the re-purposing of the Bloody Sunday and Hutton Inquirey sites.
  • People are always a security weak spot – but that doesn’t mean you shouldn’t batten down the technical side. Don’t let the “script-kiddies” in.
  • Password complexity requirements tend to weaken security – most people put a capital as the first letter, and punctuation (!) / number (0 or 1) as the last.
  • Please(!) leave the water out all day. It’s not only at lunch time that people are thirsty – this is a speaking orientated event after all…

There’s a very interesting blogpost by @jonathanflowers that puts some thought’s I’ve had much more eloquently. I recommend you read the original but in essence – the session pitching format could do with some work. This would really increase the value of the conference to me, being able to ensure I’m in sessions that I really care about, or not – an informed decision at least.

There’s a Flickr pool of photos from the day, the tweets were all under #ukgc15, and all the liveblogs can be found by looking at the session list.