Blog

Making Icons Accessible

I’ve been using the excellent Font Awesome for a few years and it’s become part of almost every new design that I do. For a long time I’ve just slapped my icon down on the page, styled it and added a click event where needed. Job done.

Having spent some time looking a bit more deeply into accessibility, I can now see that this is not a great approach. There’s more to consider. If you can’t see it what is it actually doing?

Here’s how I approach using icons now. It may not be the perfect solution but it’s certainly a lot closer than most use cases I see. The way I use HTML depends on the use case.

If the icon is purely decorative – there in addition to text, e.g. a floppy disk icon next to the word “Save” on a button, then I think we can reasonably just forget about it and hide it for non screen users. A simple aria-hidden=”true” attribute should do.

<button><i class="fa fa-save" aria-hidden="true"></i> Save</button>

If it is there as an indicator, in place of a label, like where a hotel might have icons for TV, bath, etc. then we can use an <span> to wrap it. Inside the span we add our icon and another span with a text alternative. We show the icon and hide the inner span for screens, show the text only for other media.

Finally, if the icon is interactive and acts like a link or button, let’s make it a link or button. Like the previous example, use the <button> or <a> tag to wrap the icon and a span text alternative and show/hide for the appropriate media. This has the added bonus of making it possible to tab to the icon and so use just the keyboard to navigate the page. It also handles the icon’s active state and visited in the case of a link.

Alternatively, if you didn’t want to add a span with text inside your button or link, you could use the aria-label attribute to provide a text alternative.

One little tip. If you use an icon inside a link or button, do not leave whitespace between the outer wrapper element and the inner icon as you may get unwanted effects in the styling, such as underlined spaces either side of your icon. Keep it tight.

A New Found Appreciation for Images on the Web

I’ve been putting images in web pages for years. Nearly 2 decades now. For most of that time it has been quite easy. Add your source and the dimensions and BOOM, there you go. There was always some work around optimising images outside of your page but once in there, easy.

Then, with higher pixel densities it started getting a bit harder and we had to work it out with media queries and srcset. Now SVG is widely supported, all this fussing around with different versions for different resolutions has gone away, at least for simple graphics.

I’ve recently been doing some design work on an Android app and it’s a very different way of doing things with images. For example, I’ve created a splash screen for while the app is loading. It’s a full page, wide logo in the centre, coloured background.

On the web, I’d just set the background colour and then centre the SVG logo, probably with flexbox, and use a flex-basis of 80% or some margin to give it a flexible width.

On Android, I’ve had to provide the splash screen image as a series of PNG files. 5 different resolutions, varying from 480×320 up to 1920×1280, and then in both orientations, 10 files in all. The clever part is that at the point of installing the app the Android device will only get the files appropriate for its size and pixel density but it means a lot of messing around with assets.

It’s been a similar story for icons too. Multiple resolutions. You want a different colour? That’s a separate PNG.

I’m making it sound worse than it actually is. Luckily there are great tools that let you import a single image and export all the variations you could need.

But it does make you think about the differences between platforms. To me, the web browser, with it’s ability to resize on the fly, use SVG, recolour, apply filters, transform and animate in CSS makes Android image support feel very primitive.

How to Be a Good Designer

I’ve been designing web sites and user interfaces for quite a long time now and thought I’d try to pass on what I think it takes to be a good designer. This isn’t about design techniques or theory, just how to interact with other people.

Rule 1. Don’t be a dick.
That’s really it. Don’t let your ego take over. You will inevitably have to present your work to others. Don’t presume that because you’re the designer that your opinion is worth more than anyone else’s. It’s a collaborative process and if you start feeling that you know best it will stop you listening to others. This leads neatly into…

Rule 2. Listen to others.
This isn’t because you have to or to be polite. If you actually listen and understand people’s views, opinions and concerns you can learn how to adapt your designs to meet their needs or explain how there might be a different solution to the problem.

Rule 3. Explain your thinking.
Don’t just present a design and let others judge it. Explain clearly all of the design decisions you have made. If you can justify these and articulate them clearly people will understand, you’ll have more of a conversation and, in turn, their feedback will be more constructive. It will also give them more faith in you – you don’t do things on a whim but your decisions are well thought out.

Rule 4. You don’t have to win.
It’s ok to not get your way. It’s important to show that you respect others’ opinions and concede to try their ideas. If their idea really was wrong it will come out over time and the next time they will be more inclined to trust your view.

FPL Player Value, Expected Returns and Targets

FPL players range in cost starting from 4 up to 13 so how do you compare them fairly across such a broad spectrum? What sort of returns should you expect from each price bracket? I’ve tried to apply some (very rough) maths to it to find out who’s justifying their price tag.

Season Target

Firstly, we need to set a points target for the season to get our weekly target. I’m going to base mine on equalling my best ever season, 2016/2017, where I scored 2281 points, with a rank of 16,876. So, for this, I’m using a season target of 2280 points, which as you’ll see further down makes the maths easier.

Scope and Disclaimers

The next thing is to set the scope of this exercise and get in my disclaimers. I’m assuming 38 “normal” game weeks with no hits and no chips. I’m also ignoring rises in team value. Finally, I’m giving all figures rounded to 2 decimal places.

Team Value

So, breaking things down, we all start with a team value of 100. This means each of our 15 squad players averages out at a cost of 6.67 (100/15).

Only 11 of our 15 score each week so we need to focus on the team rather than the squad. I’ve assumed that our first 11 have a cumulative cost of 82. That’s assuming a typical value of 18 on bench, something like 4.0, 4.5, 4.5, 5.0.

Using that total playing cost of 82, each player now has an average value of 7.45 (82/11).

Weekly Target

Going back to my season target of 2280 points. Over 38 game weeks this (conveniently) breaks down to 60 points per week. So, I have a weekly target of 60 points.

Player Target

The next thing to work out is the average return required from each player each week. Given that our captain scores double this is the game week requirement divided by 12, 60/12 = 5. So, I want each player to score 5.

Expected Returns

If I’m expecting an average of 5 points from an average player cost of 7.45 that means I’m expecting each player to return 0.67 of his cost in points. Roughly two thirds. So, a player worth 12 should return 8 points, a player worth 9 should return 6, you get it.

Value Index

We can then take this expected return number and divide by 0.67 to give a value index based on 1, where 1 is the expected value, above 1 is better, below 1 is poorer.

We can estimate the value over the season so far by looking at the Points per Match and comparing that with the cost. If PPM divided by cost is less than 0.67 the player’s returning lower than expected, if higher it’s better. This index makes it easy to see how much better or worse as a percentage. 1.14 = 14% better, 0.92 = 8% worse.

Real Examples

Here are some examples using stats from mid game week 28, 2017/2018 season.

Defenders

PlayerCostPPMValue Index
Alonso7.25.31.10
Davies5.75.21.36
Valencia6.95.11.10
Bellerin6.03.70.92
Bruno4.53.31.09

Midfielders

PlayerCostPPMValue Index
Salah10.58.41.19
De Bruyne10.46.40.92
Hazard10.76.00.84
Ramsey7.05.81.24
Doucoure5.54.21.14

Forwards

PlayerCostPPMValue Index
Kane12.96.40.74
Firmino9.35.50.88
Rooney7.24.40.91
Murray5.73.50.92
Wilson6.04.31.07

Observations

From these few selected players in the examples, we can see that the best performing for their cost is Ben Davies of Spurs with 1.36; the worst is surprisingly Harry Kane with 0.74.

Conclusion

There are obviously other factors like minutes played but maybe we can use this value index to see which players perform consistently when selected. Maybe using point per match based on recent form rather than the season average would yield more accurate results?

Lightning Fast Filtering in JavaScript

I thought I’d share a technique for filtering large sets of data quickly in a web page. The scenario is a biggish set of data, 100,000 records, with each record having 3 properties, and we want to filter them using text matching.

Here is the finished article with dummy generated data. Give it a try. Just type any 3 or 4 characters and watch it do its thing.

See the Pen Fast Filtering with JavaScript by Chris Smith (@chris22smith) on CodePen.dark

Fast, isn’t it? You can go into the JavaScript tab and see how it all works but I’ll explain some of the main parts.

When trying to make it fast the most important thing to be aware of is that changing JavaScript objects is fast, changing the DOM is slow. So, we do as much as we can in JavaScript and then just update the DOM at the end. If you try to create 100,000 <li> tags it will be very slow and will probably die on you.

The first step is to set up a function to convert the data array into a HTML list. We keep this fast by setting a limit on how many items we will show. In this demo I’ve set it to 10 but even increasing it to 100 makes little difference to the speed. They key thing is not to get into big numbers which put a strain on the DOM. So we don’t loop through all the items, only the first few. A nice small loop, which runs quickly.

The building is all done in JavaScript, with nothing touching the DOM until we have a complete Document Fragment with all the list items ready to append to our list. I’ve separated out the building of each list item into its own function to hopefully make this even faster. Whenever iterating through large numbers of records the more variables and functions we can take out of the loop and pre-define the better.

The next step is to get the data array with the full data and filter it down into a smaller array using the native JavaScript filter() method. This method is incredibly fast, much quicker than using a for loop to iterate through each item. You can read more about filter() on MDN. If you use a predefined function with it rather than an anonymous function it’s faster still.

Once we have the filtered down array we can call our function to rebuild the list in HTML. It all happens in the blink of an eye.

As a final touch I’ve added a count message function which gets called each time we filter. This just helps to see what’s going on – how many records are being shown and the size of the reduced data set.