Building for the device agnostic web
"Agnostic" is a big word - what does it mean? It's faux Greek for "not knowing".
So what is the "device agnostic web"? It means we don't know what device will be used to interact with our site.
But isn't that just "The Web", right? No. There are plenty of people out there who try to control which browsers interact with their sites:
This is a whole load of fails concentrated in one place. The Carphone Warehouse aren't a warehouse and they don't sell carphones. They sell mobile phones and this is the product page for pretty much any mobile phone when viewed on a mobile phone.
How bad is this problem?
"45% of the Fortune 100 target smartphone users with dedicated mobile sites today, yet none of the companies studied fully comply with Google's mobile site requirements."
Nearly half of the top 100 American companies are trying this and none of them are getting it right as judged by Google's mobile site requirements. These guidelines aren't exactly rocket surgery - they basically say "don't break the web" and yet people still can't manage it.
It's not just mobile phones
- Games consoles
- Screen readers
- Search engine spiders
- The future: ???
This problem is probably highest profile with mobile phones but there are an awful lot of things out there that are interacting with web sites.
We've got tablets, games consoles, smart televisions, screen readers, search engine spiders - and they vary greatly in capabilities.
We're in the present - we're trapped between the past and the future. We need to build sites that will work in browsers from the past and browsers from the future.
How do we deal with this?
Progressive enhancement. We start with a solid foundation and enhance from there.
Elements of a web page
- CSS (Presentation)
This separation of concerns should, of course, be the the foundation for any site but we can do more: We can also apply progressive enhancement within each of these elements.
The core attributes of our HTML are that it should be clean and semantic. Getting this right gives us the best chance of it working everywhere.
Let's look at these attributes in a bit more detail:
- Correctly nest tags
- Close all tags (e.g.
- Quote attributes
- Well formed XML
Previously I would have said 'valid' rather than 'clean' here, however, HTML 5's validation rules are lax enough that it's not much use as a guide for where we need to be.
What we're looking for is robust markup that's not going to cause problems for any browser's parser.
An advantage of HTML5 is that progressive enhancement is built it - browsers will ignore things they don't understand. This means that, providing we get the basics right, we can safely use more modern markup as long as we don't rely on it.
Correctly nesting tags should be something you are doing anyway - whilst you might be able to get away with overlapping tags in some browsers, you don't know how reliably an unknown browser will react.
Close all tags - even those you don't strictly have to like line breaks, meta tags and other singleton tags. Yes, you can get away with not doing it but if you do it you don't have to "get away with it" - it's just going to work.
The same goes for quoting attributes - if you quote them, it's going to work.
What we're building up to here is that your HTML should be well formed XML. Now that probably sounds like overkill especially as nobody really likes XML that much. The point here is that if it's well formed XML then the browser's parser doesn't have to guess about anything when it's building the DOM tree, you're not going to be caught out by how an unknown browser handles HTML it doesn't fully understand.
- New HTML5 elements
I'm not going to get into the details of exactly what element should be used to markup what content, that would take forever, everyone would disagree with me and we'd all be right.
However, headings, paragraphs, lists and anchors have been around since the start of HTML. If you make sure your content is correctly marked up using these then it really should work in any browser ever made.
The new HTML5 elements - and in particular the sectioning elements such as header, footer and the like - are fine to use but don't rely on them. The definitions aren't all stable and I'm not sure if there's really much out there that actually uses them.
The other thing to bear in mind is that older browsers - and not just IE - might not recognise them. My recommendation is to put them in to mark sections but then put
divs inside them to actually hang styles and functionality from. See: HTML5 Elements for Legacy Browsers
Try not to get analysis paralysis with figuring out the correct way to semantically markup content. Start with the basics to give you a good foundation and think about what the content is supposed to be rather than how it is supposed to look. Making a few dodgy decisions here and there is much better than not even attempting it.
If you can change the layout of your site purely by changing the CSS and not touching the markup then it's a good indication that it's semantic.
- Baseline presentation
- Media queries
- Interaction optimisations
Like HTML, CSS has progressive enhancement built in - browsers will ignore things they don't understand. Again, providing we get the basics right, we can use advanced features provided we don't rely on them.
- Colours, typography, backgrounds, borders, etc.
- Linear layout - no floats.
- Basic interactions - no hover.
Your baseline presentation is the core elements of the CSS. It should contain the basic style elements of your site such as the colours, typography, backgrounds, borders and the like.
The baseline layout should be completely linear with everything 100% width. Don't use any floats at this stage as some legacy browsers don't handle floats and other layout styles very reliably.
Don't add any interaction enhancements at this point - specifically no hovers.
The site's not going to look very inspiring at this point, it's just one long list of branded content - not much different to the unstyled HTML. However, this is exactly what we want - it's a baseline presentation that any browser with CSS support will be able to handle.
- Layout solution
- Media query support:
@media only all
- Not just width
It's important to remember that media queries and responsive design are not a silver bullet to cross device compatibility. They are a layout solution.
We can detect for media query support with
@media only all.
This is essentially our "cutting the mustard" test for good CSS support so, as we have a reliable baseline, we can start applying layout CSS and be fairly confident that it will be supported.
Don't forget that there are more media queries than just width. For example height can be very useful to compress vertical whitespace for small screens in landscape orientation - such as Google Glass.
- Sequential (keyboard)
- Direct (touch)
- Location aware (hover)
- Ambient / Passive (sensors)
There is a hierarchy of interactions. Sequential navigation where you move from one item to the next in sequence is the baseline, this is normally keyboard navigation but that also includes things like game controllers. The key to sequential interaction is keeping the user informed of where the current focus of interaction is.
Direct interaction uses the same interaction points as sequential but in this case they will be activated in isolation. This is exemplified by touch interactions and is probably the easiest and mode of interaction to deal with.
Location aware interactions know where the point of interaction is before it is activated. The mouse is the main example of this and it allows us to use hover states. However, as this is further up the hierarchy you can't use this to present information not available to sequential and direct interactions.
At the bottom of the hierarchy we have ambient or passive interactions such as information from sensors such as location and network. This is still a very new area and should be used with caution as they don't express a conscious desire for interaction.
Progressively enhanced CSS
For more information about this see my article on progressively enhanced CSS
- Feature detection
- Cutting the mustard
- Core content is accessible
- Use JS to add a CSS hook
- Use CSS hook to set initial presentation for enhanced functionality
- Enhance functionality using feature if present
- Polyfill missing feature
The basic formulation for feature detection is to check for the presence of the feature in it's container - frequently
window. There are exceptions and it's different for HTML features but the idea is the same - you are detecting whether the feature you want to use is supported in the browser.
Pollyfilling functionality is tempting so it's very easy to end up with a lot of code doing this. This code can be hard to maintain and test so, for each pollyfill, you should thoroughly examine if the feature you want to use really is important enough to warrant that investment of time.
Cutting the mustard
- Feature detect a minimum level of support for enhancements
- Cutting the mustard - a more detailed explanation of this technique.
People often think of accessibility as being for the disabled but, done right, it will make your site more accessible for all your users regardless of ability, device and conditions.
Accessibility can seem daunting but if you get the basics right throughout the process then it doesn't have to be a big thing. Accessibility only really becomes a problem when you try and retro-fit it to a project at the end.
- Form labels
- Tab index
- ARIA roles
We already have semantic markup and that's a brilliant foundation but there are a few more things that, if you get them right in your markup, will enhance your site's usability for all users - not just those that rely on assistive technology.
- Images must have an alt attribute, even if that is null.
- Form inputs must have labels. Some controls - like buttons - are implicity labelled but text boxes, radio buttons, checkboxes and the like need labels.
- Use the tabindex attribute to make sure that all your controls are accessible by keyboard navigation in a logical fashion. We'll come on to keyboard navigation later but it's not just for keyboards - the D-pad on game console controllers is normally mapped to this. You can actually do quite a bit with the tabindex attribute so I suggest you look at the documentation.
- ARIA roles have the promise to give a significant boost to assistive technologies but unfortunately it seems support for them in assistive technologies is slow in arriving. It's definitely worth finding out about them and putting them into your code but don't rely on them.
- Contrast - 4.5:1
- Focus highlight
- Fixed dimensions in
As with HTML, accessibility in CSS isn't just for disabled users. An accessible site will be easier for all users to use.
Designers: If you only remember one thing from this talk then remember this: The minimum accessible contrast ratio between foreground and background is 4.5:1.
Don't think of this as a restriction, treat it as a challenge. The best designers I've worked with have come up with some really creative solutions that are right on this limit. And don't forget: this contrast isn't just for blind people, it will make your site easy to read on monochrome screens, small screens, screens in sunlight, screens viewed at an angle - in fact most situations that aren't the nice big screen in ideal lighting you use to do your design work.
Don't use pixels for fixed dimensions - use ems. This allows users to change the base or minimum font sizes and your site won't fall apart.
- Set a performance budget
- Use objective measurements (not times)
- Defer non-essential items (e.g. analytics)
- Validate using real user monitoring (RUM)
There are plenty of studies that show that the faster your site is the more people will engage with it. Speed is also a factor in Google rankings and, thanks to a server configuration issue, I've seen that in action.
You should set a performance budget for your site to prevent it getting too slow as you add more without taking anything away. Sticking to a budget means that when you want to add something new you have to take something out and that forces you to think about how much value the new feature really adds.
Whilst it's tempting to think of your budget in terms of time - after all that's what performance is all about - it's not practical to accurately measure time when you are building a site. You need to define your budget in objective measurements that contribute the page speed. The key metrics you should be focusing on are:
- Number of HTTP requests
- Total page weight
- Percentage of visual rendering complete (speed index)
You can make some space in your budget by deferring non-essential items. And by essential I mean essential to your users. Analytics is a classic example of this - whilst you might conciser them essential, your users don't care. When was the last time you saw a slow website and thought: "I'm happy to wait for this if it means they get good analytics."
Whilst I did say don't set your budget using a time measurement, it's a good idea to measure how fast pages are actually loading for your users - this is known as real user monitoring. With enough data you can get a meaningful average and you can use this to ensure that changes you make to the site aren't having a negative effect on your users' load times.
- Test using real devices (devicelab.org)
- Focus your testing
- Use Opera Mini
Building sites this way may sound like you have to do more testing, in fact it should reduce the amount of testing as you should be testing in multiple devices anyway but, if you build it right, more things should just work so that means less defects and less work fixing them.
Emulators are OK but there's no substitute for testing using real devices. There's nothing quite like an entry level smart phone to highlight issues with performance and usability that you'll will be covered up by a top of the range device.
You should focus your testing. There's not really much to be gained by doing a full regression on every device and in every browser. You should think about what could cause a problem and focus on those areas in browsers you know will expose that.
The single best browser for testing is Opera Mini. Due to the way everything is rendered on the server side and sent as a static page to the device it will really test how robustly your site is built. If you site works well in Opera Mini you're probably not going to have any major problems anywhere else.
In Edinburgh we have a world class facility in the Device Lab and I recommend you go book some time for testing - they've got everything set up including a number of tools that make testing on a multiple devices much quicker and easier.
I'd also suggest booking some time to do some research, take your team down there and have a look at your site, your competitors' sites and other sites from outside your industry. Look at what's working and what's not and use that to inform which direction you take your site.
What's going to happen in the future?
Learn from the past.
Code you wrote in the past is now living in the future. Look at how that's working in new browsers.
- What did you do that worked? Do more of that!
- What did you do that broke? Don't do that again.
Browsers are very good at dealing with old websites, if you've built your site to be compatible with older browsers then it's a safe bet that new browsers will be able to handle it.
Be general, not specific
The more general you make your code the less likely it is to cause you problems. If your code targets specific browsers then when those browsers change you have to change your code in order to prevent it breaking.
When Google announced Blink and Mozilla announced their Servo rendering engines on the same day this was my reaction:
First thought: "Damn! New rendering engines." Second thought: "I already build device agnostic websites - what do I care?"— Orde Saunders (@decadecity) April 3, 2013
If you have to change your site when Apple release a new version of one of their products: you are doing it wrong.
Give up control (You never had it anyway)
One of the keys to building in a device agnostic manner is to give up control: You never really had it anyway - you just thought you did.
Whether trying to deliver the same pixel perfect site to every user or delivering reduced functionality to mobile users 'on the go', trying to exert a control we don't have over how our sites are viewed is fighting a losing battle.
I know it can seem a bit scary but once you accept that you don't have control over how your users interact with your site it's actually very liberating - you've got no choice but to get the fundamentals right and, once they're right, you have a lot more freedom with how you build up from there.
- Acknowledge and embrace unpredictability.
- Think and behave in a future-friendly way.
- Help others do the same.
Future Friendly is a philosophy that emerged as a positive reaction to the increasing varieties of devices that can be connected in the web.
It acknowledges that the only predictable thing about the future of the web is that it will be unpredictable.
By building in a device agnostic manner we embrace this unpredictability.