Tags: 2e



Saturday, June 13th, 2020


I sometimes watch programmes on TG4, the Irish language broadcaster that posts most shows online. Even though I’m watching with subtitles on, I figure it can’t be bad for keeping my very rudimentary Irish from atrophying completely.

I’m usually watching music programmes but occassionally I’ll catch a bit of the news (or “nuacht”). Their coverage of the protests in America reminded me of a peculiar quirk of the Irish language. The Black community would be described as “daoine gorm” (pronunced “deenee gurum”), which literally translated would mean “blue people”. In Irish, the skin colour is referred to as “gorm”—blue.

This isn’t one of those linguistic colour differences like the way the Japanese word ao means blue and green. Irish has a perfectly serviceable word for the colour black, “dubh” (pronounced “duv”). But the term “fear dubh” (“far duv”) which literally means “black man” was already taken. It’s used to describe the devil. Not ideal.

In any case, this blue/black confusion in Irish reminded me of a delicious tale of schadenfreude. When I was writing about the difference between intentions and actions, I said:

Sometimes bad outcomes are the result of good intentions. Less often, good outcomes can be the result of bad intentions.

Back in 2017, the Geeky Gaeilgeoir wrote a post called Even Racists Got the Blues. In it, she disects the terrible translation job done by an Irish-American racist sporting a T-shirt that reads:

Gorm Chónaí Ábhar.

That’s completely nonsensical in Irish, but the intent behind the words was to say “Blue Lives Matter.” Except… even if it made grammatical sense, what this idiot actually wrote would translate as:

Black Lives Matter.

What a wonderful chef’s kiss of an own goal!

If only it were a tattoo.

Saturday, May 30th, 2020

Programming CSS to perform Sass colour functions

I wrote recently about moving away from Sass to using native CSS features. I had this to say on the topic of mixins in Sass:

These can be very useful, but now there’s a lot that you can do just in CSS with calc(). The built-in darken() and lighten() mixins are handy though when it comes to colours.

I know we will be getting these in the future but we’re not there yet with CSS.

Anyway, I had all this in the back of my mind when I was reading Lea’s excellent feature in this month’s Increment: A user’s guide to CSS variables. She’s written about a really clever technique of combining custom properites with hsl() colour values for creating colour palettes. (See also: Una’s post on dynamic colour theming with pure CSS.)

As so often happens when I’m reading something written by Lea—or seeing her give a talk—light bulbs started popping over my head (my usual response to Lea’s knowledge bombs is either “I didn’t know you could do that!” or “I never thought of doing that!”).

I immediately set about implementing this technique over on The Session. The trick here is to use separate custom properties for the hue, saturation, and lightness parts of hsl() colour values. Then, when you want to lighten or darken the colour—say, on hover—you can update the lightness part.

I’ve made a Codepen to show what I’m doing.

Let’s say I’m styling a button element. I make custom propertes for hsl() values:

button {
  --button-colour-hue: 19;
  --button-colour-saturation: 82%;
  --button-colour-lightness: 38%;
  background-color: hsl(

For my buttons, I want the borders to be slightly darker than the background colour. When I was using Sass, I used the darken() function to this. Now I use calc(). Here’s how I make the borders 10% darker:

border-color: hsl(
  calc(var(--button-colour-lightness) - 10%)

That calc() function is substracting a percentage from a percentage: 38% minus 10% in this case. The borders will have a lightness of 28%.

I make the bottom border even darker and the top border lighter to give a feeling of depth.

On The Session there’s a “cancel” button style that’s deep red.

Here’s how I set its colour:

.cancel {
  --button-colour-hue: 0;
  --button-colour-saturation: 100%;
  --button-colour-lightness: 40%;

That’s it. The existing button declarations take care of assigning the right shades for the border colours.

Here’s another example. Site admins see buttons for some actions only available to them. I want those buttons to have their own colour:

.admin {
  --button-colour-hue: 45;
  --button-colour-saturation: 100%;
  --button-colour-lightness: 40%;

You get the idea. It doesn’t matter how many differently-coloured buttons I create, the effect of darkening or lightening their borders is all taken care of.

So it turns out that the lighten() and darken() functions from Sass are available to us in CSS by using a combination of custom properties, hsl(), and calc().

I’m also using this combination to lighten or darken background and border colours on :hover. You can poke around the Codepen if you want to see that in action.

I love seeing the combinatorial power of these different bits of CSS coming together. It really is a remarkably powerful programming language.

Tuesday, April 28th, 2020

Modified machete

The Rise Of Skywalker arrives on Disney Plus on the fourth of May (a date often referred to as Star Wars Day, even though May 25th is and always will be the real Star Wars Day). Time to begin a Star Wars movie marathon. But in which order?

Back when there were a mere two trilogies, this was already a vexing problem if someone were watching the films for the first time. You could watch the six films in episode order:

  1. The Phantom Menace
  2. Attack Of The Clones
  3. Revenge Of The Sith
  4. A New Hope
  5. The Empire Strikes Back
  6. The Return Of The Jedi

But then you’re spoiling the grand reveal in episode five.

Alright then, how about release order?

  1. A New Hope
  2. The Empire Strikes Back
  3. Return Of The Jedi
  4. The Phantom Menace
  5. Attack Of The Clones
  6. Revenge Of The Sith

But then you’re front-loading the big pay-off, and you’re finishing with a big set-up.

This conundrum was solved with the machete order. It suggests omitting The Phantom Menace, not because it’s crap, but because nothing happens in it that isn’t covered in the first five minutes of Attack Of The Clones. The machete order is:

  1. A New Hope
  2. The Empire Strikes Back
  3. Attack Of The Clones
  4. Revenge Of The Sith
  5. Return Of The Jedi

It’s kind of brilliant. You get to keep the big reveal in The Empire Strikes Back, and then through flashback, you see how this came to be. Best of all, the pay-off in Return Of The Jedi has even more resonance because you’ve just seen Anakin’s downfall in Revenge Of The Sith.

With the release of the new sequel trilogy, an adjusted machete order is a pretty straightforward way to see the whole saga:

  1. A New Hope
  2. The Empire Strikes Back
  3. The Phantom Menace (optional)
  4. Attack Of The Clones
  5. Revenge Of The Sith
  6. Return Of The Jedi
  7. The Force Awakens
  8. The Last Jedi
  9. The Rise Of Skywalker

Done. But …what if you want to include the standalone films too?

If you slot them in in release order, they break up the flow:

  1. A New Hope
  2. The Empire Strikes Back
  3. The Phantom Menace (optional)
  4. Attack Of The Clones
  5. Revenge Of The Sith
  6. Return Of The Jedi
  7. The Force Awakens
  8. Rogue One
  9. The Last Jedi
  10. Solo
  11. The Rise Of Skywalker

I’m planning to watch all eleven films. This was my initial plan:

  1. Rogue One
  2. A New Hope
  3. The Empire Strikes Back
  4. The Phantom Menace
  5. Attack Of The Clones
  6. Revenge Of The Sith
  7. Solo
  8. Return Of The Jedi
  9. The Force Awakens
  10. The Last Jedi
  11. The Rise Of Skywalker

I definitely want to have Rogue One lead straight into A New Hope. The problem is where to put Solo. I don’t want to interrupt the Sith/Jedi setup/payoff.

So here’s my current plan, which I have already begun:

  1. Solo
  2. Rogue One
  3. A New Hope
  4. The Empire Strikes Back
  5. The Phantom Menace
  6. Attack Of The Clones
  7. Revenge Of The Sith
  8. Return Of The Jedi
  9. The Force Awakens
  10. The Last Jedi
  11. The Rise Of Skywalker

This way, the two standalone films work as world-building for the saga and don’t interrupt the flow once the main story is underway.

I think this works pretty well. Neither Solo nor Rogue One require any prior knowledge to be enjoyed.

And just in case you’re thinking that perhaps I’m overthinking it a bit and maybe I’ve got too much time on my hands …the world has too much time on its hands right now! Thanks to The Situation, I can not only take the time to plan and execute the viewing order for a Star Wars movie marathon, I can feel good about it. Stay home, they said. Literally saving lives, they said. Happy to oblige!

Wednesday, March 11th, 2020

A curl in every port

A few years back, Zach Bloom wrote The History of the URL: Path, Fragment, Query, and Auth. He recently expanded on it and republished it on the Cloudflare blog as The History of the URL. It’s well worth the time to read the whole thing. It’s packed full of fascinating tidbits.

In the section on ports, Zach says:

The timeline of Gopher and HTTP can be evidenced by their default port numbers. Gopher is 70, HTTP 80. The HTTP port was assigned (likely by Jon Postel at the IANA) at the request of Tim Berners-Lee sometime between 1990 and 1992.

Ooh, I can give you an exact date! It was January 24th, 1992. I know this because of the hack week in CERN last year to recreate the first ever web browser.

Kimberly was spelunking down the original source code, when she came across this line in the HTUtils.h file:

#define TCP_PORT 80 /* Allocated to http by Jon Postel/ISI 24-Jan-92 */

We showed this to Jean-François Groff, who worked on the original web technologies like libwww, the forerunner to libcurl. He remembers that day. It felt like they had “made it”, receiving the official blessing of Jon Postel (in the same RFC, incidentally, that gave port 70 to Gopher).

Then he told us something interesting about the next line of code:

#define OLD_TCP_PORT 2784 /* Try the old one if no answer on 80 */

Port 2784? That seems like an odd choice. Most of us would choose something easy to remember.

Well, it turns out that 2784 is easy to remember if you’re Tim Berners-Lee.

Those were the last four digits of his parents’ phone number.

Monday, December 9th, 2019

Checked in at Plough & Stars. Sunday night session 🎻🎵 map

Checked in at Plough & Stars. Sunday night session 🎻🎵

Sunday, November 24th, 2019

Checked in at British Airways First Lounge map

Checked in at British Airways First Lounge

Sunday, August 25th, 2019

Checked in at Chicago Brewhouse. Chicago dog! — with Jessica map

Checked in at Chicago Brewhouse. Chicago dog! — with Jessica

Saturday, August 10th, 2019


I’m going to America. But this time it’s going to be a bit different.

Here’s the backstory: I need to get to Chicago for An Event Apart in a couple of weeks. Jessica and I were talking about maybe going to Florida first to hang out with her family on the beach for a bit. We just needed to figure out the travel logistics.

Here’s the next variable to add in to the mix: Jessica is really into ballet. Like, really into ballet. She also likes boats, ships, and all things nautical.

Those two things are normally unrelated, but then a while back, Jessica tweeted this:

OMG @ENBallet on a SHIP crossing the ATLANTIC.

Dance the Atlantic 2019 Cruise

I chuckled at that, and almost immediately dismissed it as being something from another world. But then I looked at the dates, and wouldn’t you know it, it would work out perfectly for our planned travel to Florida and Chicago.

Sooo… we’re crossing the Atlantic ocean on the Queen Mary II. With ballet dancers.

It’s not a cruise. It’s a crossing:

The first rule about traveling between America and England aboard the Queen Mary 2, the flagship of the Cunard Line and the world’s largest ocean liner, is to never refer to your adventure as a cruise. You are, it is understood, making a crossing. The second rule is to refrain, when speaking to those who travel frequently on Cunard’s ships, from calling them regulars. The term of art — it is best pronounced while approximating Maggie Smith’s cut-glass accent on “Downton Abbey” — is Cunardists.

Because of the black-tie gala dinners taking place during the voyage, I am now the owner of tuxedo. I think all this dressing up is kind of like cosplay for the class system. This should be …interesting.

By all accounts, internet connectivity is non-existent on the crossing, so I’m going to be incommunicado. Don’t bother sending me any email—I won’t see it.

We sail from Southampton tomorrow. We arrive in New York a week later.

See you on the other side!

Saturday, June 29th, 2019

Checked in at Royal Pavilion Gardens. with Jessica map

Checked in at Royal Pavilion Gardens. with Jessica

Wednesday, June 19th, 2019


Shockwaves rippled across the web standards community recently when it appeared that Google Chrome was unilaterally implementing a new element called toast. It turns out that’s not the case, but the confusion is understandable.

First off, this all kicked off with the announcement of “intent to implement”. That makes it sounds like Google are intending to, well, …implement this. In fact “intent to implement” really means “intend to mess around with this behind a flag”. The language is definitely confusing and this is something that will hopefully be addressed.

Secondly, Chrome isn’t going to ship a toast element. Instead, this is a proposal for a custom element currently called std-toast. I’m assuming that should the experiment prove successful, it’s not a foregone conclusion that the final element name will be called toast (minus the sexually-transmitted-disease prefix). If this turns out to be a useful feature, there will surely be a discussion between implementators about the naming of the finished element.

This is the ideal candidate for a web component. It makes total sense to create a custom element along the lines of std-toast. At first I was confused about why this was happening inside of a browser instead of first being created as a standalone web component, but it turns out that there’s been a fair bit of research looking at existing implementations in libraries and web components. So this actually looks like a good example of paving an existing cowpath.

But it didn’t come across that way. The timing of announcements felt like this was something that was happening without prior discussion. Terence Eden writes:

It feels like a Google-designed, Google-approved, Google-benefiting idea which has been dumped onto the Web without any consideration for others.

I know that isn’t the case. And I know how many dedicated people have worked hard on this proposal.

Adrian Roselli also remarks on the optics of this situation:

To be clear, while I think there is value in minting a native HTML element to fill a defined gap, I am wary of the approach Google has taken. A repo from a new-to-the-industry Googler getting a lot of promotion from Googlers, with Googlers on social media doing damage control for the blowback, WHATWG Googlers handling questions on the repo, and Google AMP strongly supporting it (to reduce its own footprint), all add up to raise alarm bells with those who advocated for a community-driven, needs-based, accessible web.

Dave Cramer made a similar point:

But my concern wasn’t so much about the nature of the new elements, but of how we learned about them and what that says about how web standardization works.

So there’s a general feeling (outside of Google) that there’s something screwy here about the order of events. A lot discussion and research seems to have happened in isolation before announcing the intent to implement:

It does not appear that any discussions happened with other browser vendors or standards bodies before the intent to implement.

Why is this a problem? Google is seeking feedback on a solution, not on how to solve the problem.

Going back to my early confusion about putting a web component directly into a browser, this question on Discourse echoes my initial reaction:

Why not release std-toast (and other elements in development) as libraries first?

It turns out that std-toast and other in-browser web components are part of an idea called layered APIs. In theory this is an initiative in the spirit of the extensible web manifesto.

The extensible web movement focused on exposing low-level APIs to developers: the fetch API, the cache API, custom elements, Houdini, and all of those other building blocks. Layered APIs, on the other hand, focuses on high-level features …like, say, an HTML element for displaying “toast” notifications.

Layered APIs is an interesting idea, but I’m worried that it could be used to circumvent discussion between implementers. It’s a route to unilaterally creating new browser features first and standardising after the fact. I know that’s how many features already end up in browsers, but I think that the sooner that authors, implementers, and standards bodies get a say, the better.

I certainly don’t think this is a good look for Google given the debacle of AMP’s “my way or the highway” rollout. I know that’s a completely different team, but the external perception of Google amongst developers has been damaged by the AMP project’s anti-competitive abuse of Google’s power in search.

Right now, a lot of people are jumpy about Microsoft’s move to Chromium for Edge. My friends at Microsoft have been reassuring me that while it’s always a shame to reduce browser engine diversity, this could actually be a good thing for the standards process: Microsoft could theoretically keep Google in check when it comes to what features are introduced to the Chromium engine.

But that only works if there is some kind of standards process. Layered APIs in general—and std-toast in particular—hint at a future where a single browser vendor can plough ahead on their own. I sincerely hope that’s a misreading of the situation and that this has all been an exercise in miscommunication and misunderstanding.

Like Dave Cramer says:

I hear a lot about how anyone can contribute to the web platform. We’ve all heard the preaching about incubation, the Extensible Web, working in public, paving the cowpaths, and so on. But to an outside observer this feels like Google making all the decisions, in private, and then asking for public comment after the feature has been designed.

Monday, March 11th, 2019

T minus one

I’m back at CERN.

I’m back at CERN because tomorrow, March 12th, 2019, is exactly thirty years on from when Tim Berners-Lee submitted his original “vague but exciting” Information Management: A Proposal. Tomorrow morning, bright and early, there’s an event at CERN called Web@30.

Thanks to my neglibable contribution to the recreation of the WorldWideWeb browser, I’ve wrangled an invitation to attend. Remy and Martin are here too, and I know that the rest of the team are with us in spirit.

I’m so excited about this! I’m such a nerd for web history, it’s going to be like Christmas for me.

If you’re up early enough, you can watch the event on a livestream. The whole thing will be over by mid-morning. Then, Remy and I will take an afternoon flight back to England …just in time for the evening event at London’s Science Museum.

Saturday, March 9th, 2019

Updating email addresses with Mailchimp’s API

I’ve been using Mailchimp for years now to send out a weekly newsletter from The Session. But I never visit the Mailchimp website. Instead, I use the API to create a campaign each week, and then send it out. I also use the API whenever a member of The Session updates their email preferences (or changes their details).

I got an email from Mailchimp that their old API was being deprecated and I’d need to update to their more recent one. The code I was using had been happily running for about seven years, but now I’d have to change it.

Luckily, Drew has written a really handy Mailchimp API wrapper for PHP, the language that The Session’s codebase is in. Thanks, Drew! I downloaded that wrapper and updated my code accordingly.

Everything went pretty smoothly. I was able to create campaigns, send campaigns, add new subscribers, and delete subscribers. But I ran into an issue when I wanted to update someone’s email address (on The Session, you can edit your details at any time, including your email address).

Here’s the set up:

use \DrewM\MailChimp\MailChimp;
$MailChimp = new MailChimp('abc123abc123abc123abc123abc123-us1');
$list_id = 'b1234346';
$subscriber_hash = $MailChimp -> subscriberHash('currentemail@example.com');
$endpoint = 'lists/'.$listID.'/members/'.$subscriber_hash;

Now to update details, according to the API, I can use the patch method on that endpoint:

$MailChimp -> patch($endpoint, [
    'email_address' => 'newemail@example.com'

But that doesn’t work. Mailchimp effectively treats email addresses as unique IDs for subscribers. So the only way to change someone’s email address appears to be to delete them, and then subscribe them fresh with the new email address:

$MailChimp -> delete($endpoint);
$newendpoint = 'lists/'.$listID.'/members';
$MailChimp -> post($newendpoint, [
    'email_address' => 'newemail@example.com',
    'status' => 'subscribed'

That’s somewhat annoying, as the previous version of the API allowed email addresses to be updated, but this workaround isn’t too arduous.

Anyway, I figured it share this just in case it was useful for anyone else migrating to the newer API.

Update: Belay that. Turns out that you can update email addresses, but you have to be sure to include the status value:

$MailChimp -> patch($endpoint, [
    'email_address' => 'newemail@example.com',
    'status' => 'subscribed'

Okay, that’s a lot more straightforward. Ignore everything I said.

Tuesday, February 19th, 2019

Interaction 19

Right before heading to Geneva to spend the week hacking at CERN, I was in Seattle with a sizable Clearleft contingent to attend Interaction 19, the annual conference put on by the Interaction Design Association.

Ben has rounded up the highlights from my fellow Clearlefties. There are some good talks listed there: John Maeda, Nelly Ben Hayoun, and Jon Bell were thoroughly enjoyable. Some other talks were just okay, and there was one talk, by IXDA president Alok Nandi, that was almost impressive in how rambling and incoherent it was. It was like being in a scene from Silicon Valley. I remember clapping at the end; not out of appreciation, but out of relief.

If truth be told, Interaction 19 had about a day’s worth of really great content …spread out over three days. To be fair, that’s par for the course. When we went to Interaction 17 in New York, the hit/miss ratio was about the same:

There were some really good talks at the event, but alas, the muti-track format made it difficult to see all of them. Continuous partial FOMO was the order of the day.

And as I said at the time:

To be honest, the conference was only part of the motivation for the trip. Spending a week in New York with a gaggle of Clearlefties was its own reward.

So I’m willing to cut Interaction 19 a lot of slack. Even if quite a few of the talks were just so-so, getting to hang with Clearlefties in Seattle during snowmageddon was a lot of fun (and you’ll be pleased to hear that we didn’t even resort to cannibalism to survive).

But while the content of the conference was fair to middling, the organisation of it was a shambles:

Imagine the Fyre Festival but in downtown Seattle in winter. Welcome to @ixdconf. #ixd19

They sold more tickets than there were seats. I ended up watching the first morning’s keynotes being streamed to a screen in a conference room in a different building.

Now, I’ve been at events with keynotes that have overflow rooms—South by Southwest does this. But that’s at a different scale. This is a conference with a known number of attendees, each one of them spending over a thousand dollars to attend. I’m pretty sure that a first-come, first-served policy isn’t the best way of treating those attendees.

Anyway, here’s what I submitted for that round-up of the best talks, but which, for reasons of prudence, was omitted from the final post:

I really enjoyed the keynote by Liz Jackson on inclusive design. I would’ve enjoyed it even more if I could’ve seen it in person. Instead I watched it live-streamed to a meeting room two buildings over because the conference sold more tickets than they had seats for. This was after queueing in the cold for registration. So I feel like I learned a lot from Interaction 19 …about how not to organise a conference.

Still, as Ben notes:

We all enjoyed ourselves thoroughly, despite best efforts by the West Coast snow to disrupt the entire city.

I’m going to be back in Seattle in just under two weeks for An Event Apart. Now that’s a conference! It runs like a well-oiled machine, and every talk in its single track has been curated for excellence …with one exception.

Wednesday, January 30th, 2019

Checked in at Jolly Brewer. Banjo time. — with Jessica map

Checked in at Jolly Brewer. Banjo time. — with Jessica

Saturday, November 24th, 2018


I just wrapped up my last speaking gig of the year. It came at the end of a streak of attending European conferences without speaking at any of them—quite a nice feeling!

I already mentioned that I was in Berlin for the (excellent) Indie Web Camp. That was immediately followed by a one-day Accessibility Club conference. It was really, really good.

I have to say, I was initially apprehensive when I saw the sheer amount of speakers on the schedule. I was worried that my attention couldn’t handle it all. But the talks were a mixture of shorter 20 minute presentations, and a few longer 40 minute presentations. That worked really well—the day fairly zipped by. And just in case you think it would hard to have an entire day devoted to accessibility, the breadth of talks was remarkably diverse. Hats off to a well-organised and well-executed event!

The next day was Beyond Tellerrand. This has my favourite conference format: two days; one track; curated; a mix of design and development (see also An Event Apart and Smashing Conference). Marc’s love and care shines through every pore of the event. I thoroughly enjoyed the talks, and the hanging out with lovely people.

Alas, I had to miss the final afternoon of Beyond Tellerrand to head home to Brighton. I needed to get back for FF Conf. It was excellent, as always. Remy and Julie really give it their all. Remy even stepped in to give a (great) talk himself this year, when a speaker couldn’t make it.

A week later, I went to Iceland for Material. I really enjoyed last year’s inaugural event, and if anything, this year’s topped it. I just love how eclectic and different the talks are, and yet it all weirdly hangs together in a thoughtfully curated way. (Oh, and Remy, when you start to put together the line-up for next year’s FF Conf, be sure to check out Charlotte Dann—her talk at Material was the perfect mix of code and creativity.)

As well as sharing an organiser with Accessibility Club, Material had a similar format—keynote talks from invited presenters, interspersed with shorter talks by locals. The mix was great. I won’t even try to describe the range of topics. I’m not sure I could explain how a conference podium morphed into a bar at the end of one of the talks. I think the best description of Material would be to say it’s like the inside of Brian’s head. In a good way.

I was supposed to be back in Brighton for one night after Material, but the stormy weather kept myself and Jessica in Reykjavik for an extra night. Thanks to Brian’s hospitality, we had a bed for the night.

There followed a long travel day as we made our way from Reykjavik to Gatwick, and then straight on to Thessaloniki, where we spent five days even though we only had the clothes we packed for the brief trip to Iceland. (Yes, we went shopping.)

I was there to speak at Voxxed Days. These events happen in various locations around the world, and just a few weeks ago, I spoke at the one in Bristol. It was …different.

After experiencing so many lovingly crafted events—Accessibility Club, Beyond Tellerrand, FF Conf, and Material—I’m afraid that Voxxed Days Thessaloniki was quite a comedown. It’s not that it was corporate per se—I believe it’s organised by developers for developers—but it felt like it was for people who worked in corporate environments. There were multiple tracks (I’m really not a fan of that), and some great speakers on the line-up like Stephanie and Simona, but the atmosphere felt kind of grim in a David Brentian sort of way. It probably wasn’t helped by the cheeky chappie of an MC who referred to one of the speakers as “darling.”

Anyway, I spoke first thing on the first day and I didn’t end up sticking around long. Normally I don’t speak and run, but I didn’t fancy the vibe of the exhibitor hall with its booth-babesque sales teams. Voxxed Days doesn’t pay its speakers so I didn’t feel any great obligation to hang around. The magnificent food and rembetika music of Thessaloniki was calling.

I just got back from Greece, and that wraps up my conference attending (and speaking) for 2018. I’ve already got a couple of events lined up for 2019. I’m delighted to be speaking at the return of Colly’s New Adventures conference. I’m less delighted about preparing a brand new talk I promised—I’m really feeling the pressure to deliver the goods at such an auspicious event with an intimidatingly superb line-up of speakers.

I’m also going to be preparing a different all-new talk for An Event Apart Seattle in March. For once, I’m going to try to make it somewhat practical and talk about service workers. If you know of any other events that might want a presentation like that in 2019, drop me a line.

Perhaps I will see you in Nottingham or in Seattle. If you’re planning on going to New Adventures, use the discount code ADACTIO10 to get 10% of the price of the conference or workshop ticket. If you’re planning on going to An Event Apart, use the discount code AEAKEITH for $100 off.

Sunday, November 4th, 2018


Checked in at Mozilla Berlin. with Tantek, Calum, aaronpk

Thursday, November 1st, 2018

Checked in at Jolly Brewer. Playing tunes. map

Checked in at Jolly Brewer. Playing tunes.

Friday, October 26th, 2018

Service workers and browser extensions

I quite enjoy a good bug hunt. Just yesterday, myself and Cassie were doing some bugfixing together. As always, the first step was to try to reproduce the problem and then isolate it. Which reminds me…

There’ve been a few occasions when I’ve been trying to debug service worker issues. The problem is rarely in reproducing the issue—it’s isolating the cause that can be frustrating. I try changing a bit of code here, and a bit of code there, in an attempt to zero in on the problem, butwith no luck. Before long, I’m tearing my hair out staring at code that appears to have nothing wrong with it.

And that’s when I remember: browser extensions.

I’m currently using Firefox as my browser, and I have extensions installed to stop tracking and surveillance (these technologies are usually referred to as “ad blockers”, but that’s a bit of a misnomer—the issue isn’t with the ads; it’s with the invasive tracking).

If you think about how a service worker does its magic, it’s as if it’s sitting in the browser, waiting to intercept any requests to a particular domain. It’s like the service worker is the first port of call for any requests the browser makes. But then you add a browser extension. The browser extension is also waiting to intercept certain network requests. Now the extension is the first port of call, and the service worker is relegated to be next in line.

This, apparently, can cause issues (presumably depending on how the browser extension has been coded). In some situations, network requests that should work just fine start to fail, executing the catch clauses of fetch statements in your service worker.

So if you’ve been trying to debug a service worker issue, and you can’t seem to figure out what the problem might be, it’s not necessarily an issue with your code, or even an issue with the browser.

From now on when I’m troubleshooting service worker quirks, I’m going to introduce a step zero, before I even start reproducing or isolating the bug. I’m going to ask myself, “Are there any browser extensions installed?”

I realise that sounds as basic as asking “Are you sure the computer is switched on?” but there’s nothing wrong with having a checklist of basic questions to ask before moving on to the more complicated task of debugging.

I’m going to make a checklist. Then I’m going to use it …every time.

Tuesday, October 9th, 2018

Checked in at Mudhouse. Caffeinating map

Checked in at Mudhouse. Caffeinating

Monday, September 24th, 2018

Preparing a conference talk

I gave a talk at the State Of The Browser conference in London earlier this month. It was a 25 minute spiel called The Web Is Agreement.

While I was putting the talk together, I posted some pictures of my talk preparation process. People seemed to be quite interested in that peek behind the curtain, so I thought I’d jot down the process I used.

There are two aspects to preparing a talk: the content and the presentation. I like to keep the preparation of those two parts separate. It’s kind of like writing: instead of writing and editing at the same time, it’s more productive to write any old crap first (to get it out of your head) and then go back and edit—“write drunk and edit sober”. Separating out those two mindsets allows you to concentrate on the task at hand.

So, to begin with, I’m not thinking about how I’m going to present the material at all. I’m only concerned with what I want to say.

When it comes to preparing the subject matter for a talk, step number zero is to banish your inner critic. You know who I mean. That little asshole with the sneering voice that says things like “you’re not qualified to talk about this” or “everything has already been said.” Find a way to realise that this demon is a) speaking from inside your head and b) not real. Maybe try drawing your inner critic. Ridiculous? Yes. Yes, it is.

Alright, time to start. There’s nothing more intimidating than a blank slidedeck, except maybe a blank Photoshop file, or a blank word processing document. In each of those cases, I find that starting with software is rarely a good idea. Paper is your friend.

I get a piece of A3 paper and start scribbling out a mind map. “Mind map” is a somewhat grandiose term for what is effectively a lo-fi crazy wall.

Mind mapping.
Step 1

The idea here is to get everything out of my head. Don’t self-censor. At this stage, there are no bad ideas. This is a “yes, and…” exercise, not a “no, but…” exercise. Divergent, not convergent.

Not everything will make it into the final talk. That’s okay. In fact, I often find that there’s one thing that I’m really attached to, that I’m certain will be in the talk, that doesn’t make the cut. Kill your darlings.

I used to do this mind-mapping step by opening a text file and dumping my thoughts into it. I told myself that they were in no particular order, but because a text file reads left to right and top to bottom, they are in an order, whether I intended it or not. By using a big sheet of paper, I can genuinely get things down in a disconnected way (and later, I can literally start drawing connections).

For this particular talk, I knew that the subject matter would be something to do with web standards. I brain-dumped every vague thought I had about standards in general.

The next step is what I call chunking. I start to group related ideas together. Then I give a label to each of these chunks. Personally, I like to use a post-it note per chunk. I put one word or phrase on the post-it note, but it could just as easily be a doodle. The important thing is that you know what the word or doodle represents. Each chunk should represent a self-contained little topic that you might talk about for 3 to 5 minutes.

Step 2

At this point, I can start thinking about the structure of the talk: “Should I start with this topic? Or should I put that in the middle?” The cost of changing my mind is minimal—I’m just moving post-it notes around.

With topics broken down into chunks like this, I can flesh out each one. The nice thing about this is that I’ve taken one big overwhelming task—prepare a presentation!—and I’ve broken it down into smaller, more manageable tasks. I can take a random post-it note and set myself, say, ten or fifteen minutes to jot down an explanation of it.

The explanation could just be bullet points. For this particular talk, I decided to write full sentences.

Step 3

Even though, in this case, I was writing out my thoughts word for word, I still kept the topics in separate files. That way, I can still move things around easily.

Crafting the narrative structure of a talk is the part I find most challenging …but it’s also the most rewarding. By having the content chunked up like this, I can experiment with different structures. I like to try out different narrative techniques from books and films, like say, flashback: find the most exciting part of the talk; start with that, and then give the backstory that led up to it. That’s just one example. There are many possible narrative stuctures.

What I definitely don’t do is enact the advice that everyone is given for their college presentations:

  1. say what you’re going to say,
  2. say it, and
  3. recap what you’ve said.

To me, that’s the equivalent of showing an audience the trailer for a film right before watching the film …and then reading a review of the film right after watching it. Just play the film! Give the audience some credit—assume the audience has no knowledge but infinite intelligence.

Oh, and there’s one easy solution to cracking the narrative problem: make a list. If you’ve got 7 chunks, you can always give a talk on “Seven things about whatever” …but it’s a bit of a cop-out. I mean, most films have a three-act structure, but they don’t start the film by telling the audience that, and they don’t point out when one act finishes and another begins. I think it’s much more satisfying—albeit more challenging—to find a way to segue from chunk to chunk.

Finding the narrative thread is tricky work, but at least, by this point, it’s its own separate task: if I had tried to figure out the narrative thread at the start of the process, or even when I was chunking things out, it would’ve been overwhelming. Now it’s just the next task in my to-do list.

I suppose, at this point, I might as well make some slides.

Step 4

I’m not trying to be dismissive of slides—I think having nice slides is a very good thing. But I do think that they can become the “busy work” of preparing a presentation. If I start on the slides too soon, I find they’ll take up all my time. I think it’s far more important to devote time to the content and structure of the talk. The slides should illustrate the talk …but the slides are not the talk.

If you don’t think of the slides as being subservient to the talk, there’s a danger that you’ll end up with a slidedeck that’s more for the speaker’s benefit than the audience’s.

It’s all too easy to use the slides as a defence mechanism. You’re in a room full of people looking towards you. It’s perfectly reasonable for your brain to scream, “Don’t look at me! Look at the slides!” But taken too far, that can be interpreted as “Don’t listen to me!”

For this particular talk, there were moments when I wanted to make sure the audience was focused on some key point I was making. I decided that having no slide at all was the best way of driving home my point.

But slidedeck style is quite a personal thing, so use whatever works for you.

It’s a similar story with presentation style. Apart from some general good advice—like, speak clearly—the way you present should be as unique as you are. I have just one piece of advice, and it’s this: read Demystifying Public Speaking by Lara Hogan—it’s really, really good!

(I had to apologise to Lara last time I saw her, because I really wanted her to sign my copy of her book …but I didn’t have it, because it’s easily the book I’ve loaned out to other people the most.)

I did a good few run-throughs of my talk. There were a few sentences that sounded fine written down, but were really clumsy to say out loud. It reminded me of what Harrison Ford told George Lucas during the filming of Star Wars: “You can type this shit, George, but you can’t say it.”

I gave a final run-through at work to some of my Clearleft colleagues. To be honest, I find that more nerve-wracking than speaking on a stage in front of a big room full of strangers. I think it’s something to do with the presentation of self.

Finally, the day of the conference rolled around, and I was feeling pretty comfortable with my material. I’m pretty happy with how it turned out. You can read The Web Is Agreement, and you can look at the slides, but as with any conference talk, you kinda had to be there.