Tags: 40

13

sparkline

HTTPS + service worker + web app manifest = progressive web app

I gave a quick talk at the Delta V conference in London last week called Any Site can be a Progressive Web App. I had ten minutes, but frankly I only needed enough time to say the title of the talk because, well, that was also the message.

There’s a common misconception that making a Progressive Web App means creating a Single Page App with an app-shell architecture. But the truth is that literally any website can benefit from the performance boost that results from the combination of HTTPS + Service Worker + Web App Manifest.

See how I define a progressive web app as being HTTPS + service worker + web app manifest? I’ve been doing that for a while. Here’s a post from last year called Progressing the web:

Literally any website can be a progressive web app:

That last step can be tricky if you’re new to service workers, but it’s not unsurmountable. It’s certainly a lot easier than completely rearchitecting your existing website to be a JavaScript-driven single page app.

Later I wrote a post called What is a Progressive Web App? where I compared the definition to responsive web design.

Regardless of the specifics of the name, what I like about Progressive Web Apps is that they have a clear definition. It reminds me of Responsive Web Design. Whatever you think of that name, it comes with a clear list of requirements:

  1. A fluid layout,
  2. Fluid images, and
  3. Media queries.

Likewise, Progressive Web Apps consist of:

  1. HTTPS,
  2. A service worker, and
  3. A Web App Manifest.

There’s more you can do in addition to that (just as there’s plenty more you can do on a responsive site), but the core definition is nice and clear.

But here’s the thing. Outside of the confines of my own website, it’s hard to find that definition anywhere.

On Google’s developer site, their definition uses adjectives like “reliable”, “fast”, and “engaging”. Those are all great adjectives, but more useful to a salesperson than a developer.

Over on the Mozilla Developer Network, their section on progressive web apps states:

Progressive web apps use modern web APIs along with traditional progressive enhancement strategy to create cross-platform web applications. These apps work everywhere and provide several features that give them the same user experience advantages as native apps. 

Hmm …I’m not so sure about that comparison to native apps (and I’m a little disturbed that the URL structure is /Apps/Progressive). So let’s click through to the introduction:

PWAs are web apps developed using a number of specific technologies and standard patterns to allow them to take advantage of both web and native app features.

Okay. Specific technologies. That’s good to hear. But instead of then listing those specific technologies, we’re given another list of adjectives (discoverable, installable, linkable, etc.). Again, like Google’s chosen adjectives, they’re very nice and desirable, but not exactly useful to someone who wants to get started making a progressive web app. That’s why I like to cut to the chase and say:

  • You need to be running on HTTPS,
  • Then you can add a service worker,
  • And don’t forget to add a web app manifest file.

If you do that, you’ve got a progressive web app. Now, to be fair, there’a lot that I’m leaving out. Your site should be fast. Your site should be responsive (it is, after all, on the web). There’s not much point mucking about with service workers if you haven’t sorted out the basics first. But those three things—HTTPS + service worker + web app manifest—are specifically what distinguishes a progressive web app. You can—and should—have a reliable, fast, engaging website before turning it into a progressive web app.

Jason has been thinking about progressive web apps a lot lately (he should write a book or something), and he said to me:

I agree with you on the three things that comprise a PWA, but as far as I can tell, you’re the first to declare it as such.

I was quite surprised by that. I always assumed that I was repeating the three ingredients of a progressive web app, not defining them. But looking through all the docs out there, Jason might be right. It’s surprising because I assumed it was obvious why those three things comprise a progressive web app—it’s because they’re testable.

Lighthouse, PWA Builder, Sonarwhal and other tools that evaluate your site will measure its progressive web app score based on the three defining factors (HTTPS, service worker, web app manifest). Then there’s Android’s Add to Home Screen prompt. Here finally we get a concrete description of what your site needs to do to pass muster:

  • Includes a web app manifest…
  • Served over HTTPS (required for service workers)
  • Has registered a service worker with a fetch event handler

(Although, as of this month, Chrome will no longer show the prompt automatically—you also have to write some JavaScript to handle the beforeinstallprompt  event).

Anyway, if you’re looking to turn your website into a progressive web app, here’s what you need to do (assuming it’s already performant and responsive):

  1. Switch over to HTTPS. Certbot can help you here.
  2. Add a web app manifest.
  3. Add a service worker to your site so that it responds even when there’s no network connection.

That last step might sound like an intimidating prospect, but help is at hand: I wrote Going Offline for exactly this situation.

Good griddance

I’m not great at estimation, but I still try to do it on any project I’m working, even if it’s just for my own benefit. I break down different bits of the work, and ask myself two questions:

  1. How important is this?
  2. How long will it take?

If I were smart, I’d plot the answers on a graph. I start doing the important stuff, beginning with whatever won’t take too long. Then I’ve got a choice: either do the stuff that’s not all that important, but won’t take long—or do the stuff that will take quite a while, but is quite important. Finally, there’s stuff that’s not important and will take quite a while to do. I leave that to the end. If it never ends up getting done, it’s not the end of the world.

I guess it’s not really about estimation; it’s more about prioritisation.

Anyway, I’m working on a fun little project right now—the website for one of Clearleft’s many excellent events. There was one particular part of the design that I had estimated would take quite a while to do, so I didn’t get around to it until today. It was a layout that I figured would take maybe half a day of wrangling CSS.

I used CSS grid and I was done in five minutes. That’s not an exaggeration. It was literally five minutes.

I thought to myself, “Well, I want these elements to be arranged in two rows of three columns, but I want that particular one to always be in the last column of the top row.”

Normally my next step would be to figure out how to translate those wishes into floats and clears, or maybe flexbox. But this time, there was almost no translation. I could more or less write the CSS like I would write English.

I want these elements to be arranged in rows of three columns.

display: grid;
grid-template-columns: 1fr 1fr fr

I want that particular one to always be in the last column of the top row.

grid-row: 1;
grid-column: 3;

That was it. I was done.

I think I may need to recalibrate the estimation part of my brain to account for just how powerful CSS grid is.

Fit For Purpose: Making Sense of the New CSS by Eric Meyer

Time for even more CSS goodness at An Event Apart Seattle (Special Edition). Eric’s talk is called Fit For Purpose: Making Sense of the New CSS. Here are my notes…

Eric isn’t going to dive quite as deeply as Rachel, but he is going to share some patterns he has used.

Feature queries

First up: feature queries! Or @supports, if you prefer. You can ask a browser “do you support this feature?” If you haven’t used feature queries, you might be wondering why you have to say the property and the value. Well, think about it. If you asked a browser “do you support display?”, it’s not very useful. So you have to say “do you support display: grid?”

Here’s a nice pattern from Lea Verou for detecting support for custom properties:

@supports (--css: variables)

Here’s a gotcha:

@supports (clip-path: polygon())

That won’t work because polygon() is invalid. This will work:

@supports (clip-path: polygon(0 0))

So to use feature queries, you need to understand valid values for properties.

You can chain feature queries together, or just pick the least-supported thing you’re testing for and test just for that.

Here’s a pattern Eric used when he only wanted to make text sideways, but only if grid is supported:

@supports (display: grid) {
    ...
    @supports (writing-mode: sideways-lr) {
        ...
    }
}

That’s functionally equivalent to:

@supports (display: grid) {
    ...
}
@supports (display:grid) and (writing-mode: sideways-lr) {
    ...
}

Choose whichever pattern makes sense to you. More to the point, choose the pattern that makes sense to your future self when you revisit your code.

Feature queries need to work together with media queries. Sometimes there are effects that you only want to apply on larger viewports. Do you put your feature queries inside your media queries? Or do you put your media queries inside your feature queries?

  • MOSS: Media Outside Support Statements
  • MISO: Media Inside Supports Object

Use MOSS when you have more media switches than support blocks. Use MISO when you only have a few breakpoints but lots of feature queries.

That’s one idea that Eric has. It’ll be interesting to see how this develops.

And remember, CSS is still CSS. Sometimes you don’t need a feature query at all. You could just use hanging-punctuation without testing for it. Browsers that don’t understand it will just ignore it. CSS has implicit feature queries built in. You don’t have to put your grid layout in a feature query, but you might want to put grid-specific margins and widths inside a feature query for display: grid.

Feature queries really help us get from now to the future.

Flexbox

Let’s move on to flexbox. Flexbox is great for things in a line.

On the An Event Apart site, the profile pictures have social media icons lined up at the bottom. Sometimes there are just a few. Sometimes there are a lot more. This is using flexbox. Why? Because it’s cool. Also, because it’s flexbox, you can create rules about how the icons should behave if one of the icons is taller than the others. (It’s gotten to the point that Eric has forgotten that vertically-centring things in CSS is supposed to be hard. The jokes aren’t funny any more.) Also, what if there’s no photo? Using flexbox, you can say “if there’s no photo, change the direction of the icons to be vertical.” Once again, it’s all about writing less CSS.

Also, note that the profile picture is being floated. That’s the right tool for the job. It feels almost transgressive to use float for exactly the purpose for which it was intended.

On the An Event Apart site, the header is currently using absolute positioning to pull the navigation from the bottom of the page source to the top of the viewport. But now you get overlap at some screen sizes. Flexbox would make it much more robust. (Eric uses the flexbox inspector in Firefox Nightly to demonstrate.)

With flexbox, what works horizontally works vertically. Flexbox allows you to align things, as long as you’re aligning in one direction. Flexbox makes things springy. Everything’s related and pushing against each other in a way that makes sense for this medium. It’s intuitive, even though it takes a bit of getting used to …because we’ve picked up some bad habits. To quote Yoda, “You must unlearn what you have learned.” A lot of the barrier is getting over what we’ve internalised. Eric envies the people starting out now. They get to start fresh. It’s like when people who never had to table layouts see code from that time period: it (quite rightly) doesn’t make any sense. That’s what it’s going to be like when people starting out today see the float-based layouts from Bootstrap and the like.

Grid

That’s going to happen with grid too. We must unlearn what we have learned from twenty years of floats and positioning. What makes it worth is:

  1. Flexbox and grid are pretty easy to get used to, and
  2. It’s amazing what you can do!

Eric quotes from an article called How We adopted CSS Grid at Scale:

…we agreed to use CSS Grid at the layout level and Flexbox at the component level (arranging child items of components). Although there’s some overlap and in some cases both could be used interchangeably, abiding by this rule helped us avoid any confusion in gray areas.

Don’t be afraid to set these kind of arbitrary limits that aren’t technological, but are necessary for the team to work well together.

Eric hacked his Wordpress admin interface to use grid instead of floats for an activity component (a list of dates and titles). He initially turned each list item into a separate grid. The overall list didn’t look right. What Eric really needed was a subgrid capability, so that the mini grids (the list items) would relate to one another within the larger grid (the list). But subgrid doesn’t exist yet.

In this case, there’s a way to fake it using display: contents. Eric made the list a grid and used display: contents on the list items. It’s as though you’re saying that the contents of the li are really the contents of the ul. That works in this particular case.

The feature queries for that looked like:

@supports (display: grid) {
    ...
    @supports (display: contents) {
        ...
    }
}

Eric is also using the grid “ASCII art” (named areas) technique on his personal site. This works independent of source order. For that reason, make sure your source order makes sense.

Using media queries, Eric defines entirely different layouts simply by using different ASCII art. He’s switching templates.

For a proposed redesign of the An Event Apart site, Eric used CSS grid as a prototyping tool. He took a PDF, sliced it up, exported JPGs, and then used grid to lay out those images in a flexible grid. Rapid prototyping! The Firefox grid inspector really helps here. In less than an hour, he had a working layout. He could test whether the layout was sensible and robust. Then he swapped out the sliced images for real content. That took maybe another hour (mostly because it was faster to re-type the text than try to copy and paste from a PDF). CSS makes it that damn easy now!

So even if you’re not going to put things like grid into production, they can still be enormously useful as design tools (and you’re getting to grips with this new stuff).

See also:

Ubiquity and consistency

I keep thinking about this post from Baldur Bjarnason, Over-engineering is under-engineering. It took me a while to get my head around what he was saying, but now that (I think) I understand it, I find it to be very astute.

Let’s take a single interface element, say, a dropdown menu. This is the example Laura uses in her article for 24 Ways called Accessibility Through Semantic HTML. You’ve got two choices, broadly speaking:

  1. Use the HTML select element.
  2. Create your own dropdown widget using JavaScript (working with divs and spans).

The advantage of the first choice is that it’s lightweight, it works everywhere, and the browser does all the hard work for you.

But…

You don’t get complete control. Because the browser is doing the heavy lifting, you can’t craft the details of the dropdown to look identical on different browser/OS combinations.

That’s where the second option comes in. By scripting your own dropdown, you get complete control over the appearance and behaviour of the widget. The disadvantage is that, because you’re now doing all the work instead of the browser, it’s up to you to do all the work—that means lots of JavaScript, thinking about edge cases, and making the whole thing accessible.

This is the point that Baldur makes: no matter how much you over-engineer your own custom solution, there’ll always be something that falls between the cracks. So, ironically, the over-engineered solution—when compared to the simple under-engineered native browser solution—ends up being under-engineered.

Is it worth it? Rian Rietveld asks:

It is impossible to style select option. But is that really necessary? Is it worth abandoning the native browser behavior for a complete rewrite in JavaScript of the functionality?

The answer, as ever, is it depends. It depends on your priorities. If your priority is having consistent control over the details, then foregoing native browser functionality in favour of scripting everything yourself aligns with your goals.

But I’m reminded of something that Eric often says:

The web does not value consistency. The web values ubiquity.

Ubiquity; universality; accessibility—however you want to label it, it’s what lies at the heart of the World Wide Web. It’s the idea that anyone should be able to access a resource, regardless of technical or personal constraints. It’s an admirable goal, and what’s even more admirable is that the web succeeds in this goal! But sometimes something’s gotta give, and that something is control. Rian again:

The days that a website must be pixel perfect and must look the same in every browser are over. There are so many devices these days, that an identical design for all is not doable. Or we must take a huge effort for custom form elements design.

So far I’ve only been looking at the micro scale of a single interface element, but this tension between ubiquity and consistency plays out at larger scales too. Take page navigations. That’s literally what browsers do. Click on a link, and the browser fetches that URL, displaying progress at it goes. The alternative, as exemplified by single page apps, is to do all of that for yourself using JavaScript: figure out the routing, show some kind of progress, load some JSON, parse it, convert it into HTML, and update the DOM.

Personally, I tend to go for the first option. Partly that’s because I like to apply the rule of least power, but mostly it’s because I’m very lazy (I also have qualms about sending a whole lotta JavaScript down the wire just so the end user gets to do something that their browser would do for them anyway). But I get it. I understand why others might wish for greater control, even if it comes with a price tag of fragility.

I think Jake’s navigation transitions proposal is fascinating. What if there were a browser-native way to get more control over how page navigations happen? I reckon that would cover the justification of 90% of single page apps.

That’s a great way of examining these kinds of decisions and questioning how this tension could be resolved. If people are frustrated by the lack of control in browser-native navigations, let’s figure out a way to give them more control. If people are frustrated by the lack of styling for select elements, maybe we should figure out a way of giving them more control over styling.

Hang on though. I feel like I’ve painted a divisive picture, like you have to make a choice between ubiquity or consistency. But the rather wonderful truth is that, on the web, you can have your cake and eat it. That’s what I was getting at with the three-step approach I describe in Resilient Web Design:

  1. Identify core functionality.
  2. Make that functionality available using the simplest possible technology.
  3. Enhance!

Like, say…

  1. The user needs to select an item from a list of options.
  2. Use a select element.
  3. Use JavaScript to replace that native element with a widget of your own devising.

Or…

  1. The user needs to navigate to another page.
  2. Use an a element with an href attribute.
  3. Use JavaScript to intercept that click, add a nice transition, and pull in the content using Ajax.

The pushback I get from people in the control/consistency camp is that this sounds like more work. It kinda is. But honestly, in my experience, it’s not that much more work. Also, and I realise I’m contradicting the part where I said I’m lazy, but that’s why it’s called work. This is our job. It’s not about what we prefer; it’s about serving the needs of the people who use what we build.

Anyway, if I were to rephrase my three-step process in terms of under-engineering and over-engineering, it might look something like this:

  1. Start with user needs.
  2. Build an under-engineered solution—one that might not offer you much control, but that works for everyone.
  3. Layer on a more over-engineered solution—one that might not work for everyone, but that offers you more control.

Ubiquity, then consistency.

The meaning of AMP

Ethan quite rightly points out some semantic sleight of hand by Google’s AMP team:

But when I hear AMP described as an open, community-led project, it strikes me as incredibly problematic, and more than a little troubling. AMP is, I think, best described as nominally open-source. It’s a corporate-led product initiative built with, and distributed on, open web technologies.

But so what, right? Tom-ay-to, tom-a-to. Well, here’s a pernicious example of where it matters: in a recent announcement of their intent to ship a new addition to HTML, the Google Chrome team cited the mood of the web development community thusly:

Web developers: Positive (AMP team indicated desire to start using the attribute)

If AMP were actually the product of working web developers, this justification would make sense. As it is, we’ve got one team at Google citing the preference of another team at Google but representing it as the will of the people.

This is just one example of AMP’s sneaky marketing where some finely-shaved semantics allows them to appear far more reasonable than they actually are.

At AMP Conf, the Google Search team were at pains to repeat over and over that AMP pages wouldn’t get any preferential treatment in search results …but they appear in a carousel above the search results. Now, if you were to ask any right-thinking person whether they think having their page appear right at the top of a list of search results would be considered preferential treatment, I think they would say hell, yes! This is the only reason why The Guardian, for instance, even have AMP versions of their content—it’s not for the performance benefits (their non-AMP pages are faster); it’s for that prime real estate in the carousel.

The same semantic nit-picking can be found in their defence of caching. See, they’ve even got me calling it caching! It’s hosting. If I click on a search result, and I am taken to page that has a URL beginning with https://www.google.com/amp/s/... then that page is being hosted on the domain google.com. That is literally what hosting means. Now, you might argue that the original version was hosted on a different domain, but the version that the user gets sent to is the Google copy. You can call it caching if you like, but you can’t tell me that Google aren’t hosting AMP pages.

That’s a particularly low blow, because it’s such a bait’n’switch. One of the reasons why AMP first appeared to be different to Facebook Instant Articles or Apple News was the promise that you could host your AMP pages yourself. That’s the very reason I first got interested in AMP. But if you actually want the benefits of AMP—appearing in the not-search-results carousel, pre-rendered performance, etc.—then your pages must be hosted by Google.

So, to summarise, here are three statements that Google’s AMP team are currently peddling as being true:

  1. AMP is a community project, not a Google project.
  2. AMP pages don’t receive preferential treatment in search results.
  3. AMP pages are hosted on your own domain.

I don’t think those statements are even truthy, much less true. In fact, if I were looking for the right term to semantically describe any one of those statements, the closest in meaning would be this:

A statement used intentionally for the purpose of deception.

That is the dictionary definition of a lie.

Update: That last part was a bit much. Sorry about that. I know it’s a bit much because The Register got all gloaty about it.

I don’t think the developers working on the AMP format are intentionally deceptive (although they are engaging in some impressive cognitive gymnastics). The AMP ecosystem, on the other hand, that’s another story—the preferential treatment of Google-hosted AMP pages in the carousel and in search results; that’s messed up.

Still, I would do well to remember that there are well-meaning people working on even the fishiest of projects.

Except for the people working at the shitrag that is The Register.

(The other strong signal that I overstepped the bounds of decency was that this post attracted the pond scum of Hacker News. That’s another place where the “well-meaning people work on even the fishiest of projects” rule definitely doesn’t apply.)

Notifications

I’ve written before about how I use apps on my phone:

If I install an app on my phone, the first thing I do is switch off all notifications. That saves battery life and sanity.

The only time my phone is allowed to ask for my attention is for phone calls, SMS, or FaceTime (all rare occurrences). I initiate every other interaction—Twitter, Instagram, Foursquare, the web. My phone is a tool that I control, not the other way around.

To me, this seems like a perfectly sensible thing to do. I was surprised by how others thought it was radical and extreme.

I’m always shocked when I’m out and about with someone who has their phone set up to notify them of any activity—a mention on Twitter, a comment on Instagram, or worst of all, an email. The thought of receiving a notification upon receipt of an email gives me the shivers. Allowing those kinds of notifications would feel like putting shackles on my time and attention. Instead, I think I’m applying an old-school RSS mindset to app usage: pull rather than push.

Don’t get me wrong: I use apps on my phone all the time: Twitter, Instagram, Swarm (though not email, except in direst emergency). Even without enabling notifications, I still have to fight the urge to fiddle with my phone—to check to see if anything interesting is happening. I’d like to think I’m in control of my phone usage, but I’m not sure that’s entirely true. But I do know that my behaviour would be a lot, lot worse if notifications were enabled.

I was a bit horrified when Apple decided to port this notification model to the desktop. There doesn’t seem to be any way of removing the “notification tray” altogether, but I can at least go into System Preferences and make sure that absolutely nothing is allowed to pop up an alert while I’m trying to accomplish some other task.

It’s the same on iOS—you can control notifications from Settings—but there’s an added layer within the apps themselves. If you have notifications disabled, the apps encourage you to enable them. That’s fine …at first. Being told that I could and should enable notifications is a perfectly reasonable part of the onboarding process. But with some apps I’m told that I should enable notifications Every. Single. Time.

Instagram Swarm

Of the apps I use, Instagram and Swarm are the worst offenders (I don’t have Facebook or Snapchat installed so I don’t know whether they’re as pushy). This behaviour seems to have worsened recently. The needling has been dialed up in recent updates to the apps. It doesn’t matter how often I dismiss the dialogue, it reappears the next time I open the app.

Initially I thought this might be a bug. I’ve submitted bug reports to Instagram and Swarm, but I’m starting to think that they see my bug as their feature.

In the grand scheme of things, it’s not a big deal, but I would appreciate some respect for my deliberate choice. It gets pretty wearying over the long haul. To use a completely inappropriate analogy, it’s like a recovering alcoholic constantly having to rebuff “friends” asking if they’re absolutely sure they don’t want a drink.

I don’t think there’s malice at work here. I think it’s just that I’m an edge-case scenario. They’ve thought about the situation where someone doesn’t have notifications enabled, and they’ve come up with a reasonable solution: encourage that person to enable notifications. After all, who wouldn’t want notifications? That question, if it’s asked at all, is only asked rhetorically.

I’m trying to do the healthy thing here (or at least the healthier thing) in being mindful of my app usage. They sure aren’t making it easy.

The model that web browsers use for notifications seems quite sensible in comparison. If you arrive on a site that asks for permission to send you notifications (without even taking you out to dinner first) then you have three options: allow, block, or dismiss. If you choose “block”, that site will never be able to ask that browser for permission to enable notifications. Ever. (Oh, how I wish I could apply that browser functionality to all those sites asking me to sign up for their newsletter!)

That must seem like the stuff of nightmares for growth-hacking disruptive startups looking to make their graphs go up and to the right, but it’s a wonderful example of truly user-centred design. In that situation, the browser truly feels like a user agent.

Words

I like words. I like the way they can be tethered together to produce a satisfying sentence.

Jessica likes words even more than I do (that’s why her website is called “wordridden”). She studied linguistics and she’s a translator by trade—German into English. Have a read of her post about translating Victor Klemperer to get an inkling of how much thought and care she puts into it.

Given the depth of enquiry required for a good translation, I was particularly pleased to read this remark by John Le Carré:

No wonder then that the most conscientious editors of my novels are not those for whom English is their first language, but the foreign translators who bring their relentless eye to the tautological phrase or factual inaccuracy – of which there are far too many. My German translator is particularly infuriating.

That’s from an article called Why we should learn German, but it’s really about why we should strive for clarity in our use of language:

Clear language — lucid, rational language — to a man at war with both truth and reason, is an existential threat. Clear language to such a man is a direct assault on his obfuscations, contradictions and lies. To him, it is the voice of the enemy. To him, it is fake news. Because he knows, if only intuitively, what we know to our cost: that without clear language, there is no standard of truth.

It reminds me of one of my favourite Orwell essays, Politics and the English Language:

Political language — and with variations this is true of all political parties, from Conservatives to Anarchists — is designed to make lies sound truthful and murder respectable, and to give an appearance of solidity to pure wind.

But however much I agree with Le Carré’s reprise of Orwell’s call for clarity, I was brought up short by this:

Every time I hear a British politician utter the fatal words, “Let me be very clear”, these days I reach for my revolver.

Le Carré’s text was part of a speech given in Berlin, where everyone would get the reference to the infamous Nazi quote—Wenn ich Kultur höre … entsichere ich meinen Browning—and I’m sure it was meant with a sly wink. But words matter.

Words are powerful. Words can be love and comfort — and words can be weapons.

eLife goes live

The World Wide Web was forged in the crucible of science. Tim Berners-Lee was working at CERN, the European Centre for Nuclear Research, a remarkable place where the pursuit of knowledge—rather than the pursuit of profit—is the driving force.

I often wonder whether the web as we know it—an open, decentralised system—could’ve been born anywhere else. These days it’s easy to focus on the success stories of the web in the worlds of commerce and social networking, but I still find there’s something that really “clicks” with the web and the science (Zooniverse being a classic example).

At Clearleft we’ve been lucky enough to work on science-driven projects like the Wellcome Library and the Wellcome Trust. It’s incredibly rewarding to work on projects where the bottom line is measured in knowledge-sharing rather than moolah. So when we were approached by eLife to help them with an upcoming redesign, we jumped at the chance.

We usually help organisations through our expertise in user-centred design, but in this case the design and UX were already in hand. The challenge was in the implementation. The team at eLife knew that they wanted a modular pattern library to keep their front-end components documented and easily reusable. Given Clearleft’s extensive experience with building pattern libraries, this was a match made in heaven (or whatever the scientific non-theistic equivalent of heaven is).

A group of us travelled up from Brighton to Cambridge to kick things off with a workshop. Before diving into code, it was important to set out the aims for the redesign, and figure out how a pattern library could best support those aims.

Right away, I was struck by the great working relationship between design and front-end development within eLife—there was a great collaborative spirit to the endeavour.

Some goals for the redesign soon emerged:

  • Promote the HTML reading experience as a 1st choice for readers.
  • Align the online experience with the eLife visual identity.

That led to some design principles:

  • Focus on content not site furniture.
  • Remove visual clutter and provide no more than the user needs at any stage of the experience.
  • Aid discovery of value added content beyond the manuscript.

Those design principles then informed the front-end development process. Together we came up with a priority of concerns:

  1. Access
  2. Maintainability
  3. Performance
  4. Taking advantage of browser capabilities
  5. Visual appeal

It’s interesting that maintainability was such a high priority that it superseded even performance, but we also proposed a hypothesis at the same time:

Maintainability doesn’t negatively impact performance.

The combination of the design principles and priorities led us to formulate approaches that could be used throughout the project:

  • Progressive enhancement.
  • Small-screen first responsive images.
  • Only add libraries as needed.

Then we dived into the tech stack: build tools, version control approaches, and naming methodologies. BEM was the winner there.

None of those decisions were set in stone, but they really helped to build a solid foundation for the work ahead. Graham camped out in Cambridge for a while, embedding himself in the team there as they began the process of identifying, naming, and building the components.

The work continued after Clearleft’s involvement wrapped up, and I’m happy to say that it all paid off. The new eLife site has just gone live. It’s looking—and performing—beautifully.

What a great combination: the best of the web and the best of science!

eLife is a non-profit organisation inspired by research funders and led by scientists. Our mission is to help scientists accelerate discovery by operating a platform for research communication that encourages and recognises the most responsible behaviours in science.

Open source

Building and maintaining an open-source project is hard work. That observation is about as insightful as noting the religious affiliation of the pope or the scatological habits of woodland bears.

Nolan Lawson wrote a lengthy post describing what it feels like to be an open-source maintainer.

Outside your door stands a line of a few hundred people. They are patiently waiting for you to answer their questions, complaints, pull requests, and feature requests.

You want to help all of them, but for now you’re putting it off. Maybe you had a hard day at work, or you’re tired, or you’re just trying to enjoy a weekend with your family and friends.

But if you go to github.com/notifications, there’s a constant reminder of how many people are waiting

Most of the comments on the post are from people saying “Yup, I hear ya!”

Jan wrote a follow-up post called Sustainable Open Source: The Maintainers Perspective or: How I Learned to Stop Caring and Love Open Source:

Just because there are people with problems in front of your door, that doesn’t mean they are your problems. You can choose to make them yours, but you want to be very careful about what to care about.

There’s also help at hand in the shape of Open Source Guides created by Nadia Eghbal:

A collection of resources for individuals, communities, and companies who want to learn how to run and contribute to an open source project.

I’m sure Mark can relate to all of the tales of toil that come with being an open-source project maintainer. He’s been working flat-out on Fractal, sometimes at work, but often at home too.

Fractal isn’t really a Clearleft project, at least not in the same way that something like Silverback or UX London is. We’re sponsoring Fractal as much as we can, but an open-source project doesn’t really belong to anyone; everyone is free to fork it and take it. But I still want to make sure that Mark and Danielle have time at work to contribute to Fractal. It’s hard to balance that with the bill-paying client work though.

I invited Remy around to chat with them last week. It was really valuable. Mind you, Remy was echoing many of the same observations made in Nolan’s post about how draining this can be.

So nobody here is under any illusions that this open-source lark is to be entered into lightly. It can be a gruelling exercise. But then it can also be very, very rewarding. One kind word from somebody using your software can make your day. I was genuinely pleased as punch when Danish agency Shift sent Mark a gift to thank him for all his hard work on Fractal.

People can be pretty darn great (which I guess is an underlying principle of open source).

Unlabelled search fields

Adam Silver is writing a book on forms—you may be familiar with his previous book on maintainable CSS. In a recent article (that for some reason isn’t on his blog), he looks at markup patterns for search forms and advocates that we should always use a label. I agree. But for some reason, we keep getting handed designs that show unlabelled search forms. And no, a placeholder is not a label.

I had a discussion with Mark about this the other day. The form he was marking up didn’t have a label, but it did have a button with some text that would work as a label:

<input type="search" placeholder="…">
<button type="submit">
Search
</button>

He was wondering if there was a way of using the button’s text as the label. I think there is. Using aria-labelledby like this, the button’s text should be read out before the input field:

<input aria-labelledby="searchtext" type="search" placeholder="…">
<button type="submit" id="searchtext">
Search
</button>

Notice that I say “think” and “should.” It’s one thing to figure out a theoretical solution, but only testing will show whether it actually works.

The W3C’s WAI tutorial on labelling content gives an example that uses aria-label instead:

<input type="text" name="search" aria-label="Search">
<button type="submit">Search</button>

It seems a bit of a shame to me that the label text is duplicated in the button and in the aria-label attribute (and being squirrelled away in an attribute, it runs the risk of metacrap rot). But they know what they’re talking about so there may well be very good reasons to prefer duplicating the value with aria-label rather than pointing to the value with aria-labelledby.

I thought it would be interesting to see how other sites are approaching this pattern—unlabelled search forms are all too common. All the markup examples here have been simplified a bit, removing class attributes and the like…

The BBC’s search form does actually have a label:

<label for="orb-search-q">
Search the BBC
</label>
<input id="orb-search-q" placeholder="Search" type="text">
<button>Search the BBC</button>

But that label is then hidden using CSS:

position: absolute;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px, 1px, 1px, 1px);

That CSS—as pioneered by Snook—ensures that the label is visually hidden but remains accessible to assistive technology. Using something like display: none would hide the label for everyone.

Medium wraps the input (and icon) in a label and then gives the label a title attribute. Like aria-label, a title attribute should be read out by screen readers, but it has the added advantage of also being visible as a tooltip on hover:

<label title="Search Medium">
  <span class="svgIcon"><svg></svg></span>
  <input type="search">
</label>

This is also what Google does on what must be the most visited search form on the web. But the W3C’s WAI tutorial warns against using the title attribute like this:

This approach is generally less reliable and not recommended because some screen readers and assistive technologies do not interpret the title attribute as a replacement for the label element, possibly because the title attribute is often used to provide non-essential information.

Twitter follows the BBC’s pattern of having a label but visually hiding it. They also have some descriptive text for the icon, and that text gets visually hidden too:

<label class="visuallyhidden" for="search-query">Search query</label>
<input id="search-query" placeholder="Search Twitter" type="text">
<span class="search-icon>
  <button type="submit" class="Icon" tabindex="-1">
    <span class="visuallyhidden">Search Twitter</span>
  </button>
</span>

Here’s their CSS for hiding those bits of text—it’s very similar to the BBC’s:

.visuallyhidden {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
}

That’s exactly the CSS recommended in the W3C’s WAI tutorial.

Flickr have gone with the aria-label pattern as recommended in that W3C WAI tutorial:

<input placeholder="Photos, people, or groups" aria-label="Search" type="text">
<input type="submit" value="Search">

Interestingly, neither Twitter or Flickr are using type="search" on the input elements. I’m guessing this is probably because of frustrations with trying to undo the default styles that some browsers apply to input type="search" fields. Seems a shame though.

Instagram also doesn’t use type="search" and makes no attempt to expose any kind of accessible label:

<input type="text" placeholder="Search">
<span class="coreSpriteSearchIcon"></span>

Same with Tumblr:

<input tabindex="1" type="text" name="q" id="search_query" placeholder="Search Tumblr" autocomplete="off" required="required">

…although the search form itself does have role="search" applied to it. Perhaps that helps to mitigate the lack of a clear label?

After that whistle-stop tour of a few of the web’s unlabelled search forms, it looks like the options are:

  • a visually-hidden label element,
  • an aria-label attribute,
  • a title attribute, or
  • associate some text using aria-labelledby.

But that last one needs some testing.

Update: Emil did some testing. Looks like all screen-reader/browser combinations will read the associated text.

Accessible progressive disclosure revisited

I wrote a little while back about making an accessible progressive disclosure pattern. It’s very basic—just a few ARIA properties and a bit of JavaScript sprinkled onto some basic HTML. The HTML contains a button element that toggles the aria-hidden property on a chunk of markup.

Earlier this week I had a chance to hang out with accessibility experts Derek Featherstone and Devon Persing so I took the opportunity to pepper them with questions about this pattern. My main question was “Should I automatically focus the toggled content?”

Derek’s response was very perceptive. He wanted to know why I was using a button. Good question. When you think about it, what I’m doing is pointing from one element to another. On the web, we point with links.

There are no hard’n’fast rules about this kind of thing, but as Derek put it, it helps to think about whether the action involves controlling something (use a button) or taking the user somewhere (use a link). At first glance, the progressive disclosure pattern seems to be about controlling something—toggling the appearance of another element. But if I’m questioning whether to automatically focus that element, then really I’m asking whether I want to take the user to that place in the document—in other words, linking to it.

I decided to update the markup. Here’s what I had before:

<button aria-controls="content">Reveal</button>
<div id="content"></div>

Here’s what I have now:

<a href="#content" aria-controls="content">Reveal</a>
<div id="content"></div>

The logic in the JavaScript remains exactly the same:

  1. Find any elements that have an aria-controls attribute (these were buttons, now they’re links).
  2. Grab the value of that aria-controls attribute (an ID).
  3. Hide the element with that ID by applying aria-hidden="true" and make that element focusable by adding tabindex="-1".
  4. Set aria-expanded="false" on the associated link (this attribute can be a bit confusing—it doesn’t mean that this element is not expanded; it means the element it controls is not expanded).
  5. Listen for click events on those links.
  6. Toggle the aria-hidden and aria-expanded when there’s a click event.
  7. When aria-hidden is set to false on an element (thereby revealing it), focus that element.

You can see it in action on CodePen.

See the Pen Accessible toggle (link) by Jeremy Keith (@adactio) on CodePen.

New edition

Six years ago I wrote a book and the brand new plucky upstart A Book Apart published it.

Six years! That’s like a geological age in internet years.

People liked the book. That’s very gratifying. I’m quite proud of it, and it always gives me a warm glow when someone tells me they enjoyed reading it.

Jeffrey asked me a while back about updating the book for a second edition—after all, six years is crazy long time for a web book to be around. I said no, because I just wouldn’t have the time, but mostly because—as the old proverb goes—you can step in the same river twice. Proud as I am of HTML5 For Web Designers, I consider it part of my past.

“What about having someone else update it?” Well, that made me nervous. I feel quite protective of my six year old.

“What about Rachel Andrew?” Ah, well, that’s a different story! Absolutely—if there’s one person I trust to bring the up to date, it’s Rachel.

She’s done a fine, fine job. The second edition of HTML5 For Web Designers is now available.

I know what you’re going to ask: how much difference is there between the two editions? Well, in the introduction to the new edition, I’m very pleased to say that Rachel has written:

I’ve been struck by how much has remained unchanged in that time.

There’s a new section on responsive images. That’s probably the biggest change. The section on video has been expanded to include captioning. There are some updates and tweaks to the semantics of some of the structural elements. So it’s not a completely different book; it’s very much an update rather than a rewrite.

If you don’t have a copy of HTML5 For Web Designers and you’ve been thinking that maybe it’s too out-of-date to bother with, rest assured that it is now bang up to date thanks to Rachel.

Jeffrey has written a lovely new foreword for the second edition:

HTML5 for Web Designers is a book about HTML like Elements of Style is a book about commas. It’s a book founded on solid design principles, and forged at the cutting edge of twenty-first century multi-device design and development.

101000

The travelling time is underway. I’m in Denmark right now, leading an HTML5 workshop at NoMA, the Nordic Multimedia Academy, and thanks to some excellent questions from the students, it’s all going smoothly.

Last week I was in Belgium for the Phare conference, which also went smoothly. I enjoyed giving my presentation and I really enjoyed the excellent hospitality of the Ghentians.

While I was in Belgium, the occasion of my fortieth birthday arrived with a sense of long-foreseen inevitability. I spent it in Bruges.

Four zero. The big four oh. Two squared times ten. The answer to life, the universe and everything minus two.

The photons that were reflected from Earth at the time of my birth are arriving at GJ 1214 b. Or, to put in another way, the light that left GJ 1214 at the moment of my birth is entering our solar system, perhaps even reaching the retinas of human beings somewhere on this planet who happen to be looking into just the right part of the sky at just the right time.