Tags: work



Tuesday, July 17th, 2018

Should I try to use the IE version of Grid Layout? Revisited for 2018

Rachel follows up on my recent post about CSS grid in old IE with her thoughts.

As Jeremy notes, the usefulness of a tool like Autoprefixer is diminishing, which is a good thing. It is becoming far easier to code in a way that supports all browsers, where support means usable in an appropriate way for the technology the user has in front of them. Embrace that, and be glad for the fact that we can reduce complexity based on the increasing interoperability of CSS in our browsers.

Friday, July 13th, 2018

CSS grid in Internet Explorer 11

When I was in Boston, speaking on a lunchtime panel with Rachel at An Event Apart, we took some questions from the audience about CSS grid. Inevitably, a question about browser support came up—specifically about support in Internet Explorer 11.

(Technically, you can use CSS grid in IE11—in fact it was the first browser to ship a version of grid—but the prefixed syntax is different to the standard and certain features are missing.)

Rachel gave a great balanced response, saying that you need to look at your site’s stats to determine whether it’s worth the investment of your time trying to make a grid work in IE11.

My response was blunter. I said I just don’t consider IE11 as a browser that supports grid.

Now, that might sound harsh, but what I meant was: you’re already dividing your visitors into browsers that support grid, and browsers that don’t …and you’re giving something to those browsers that don’t support grid. So I’m suggesting that IE11 falls into that category and should receive the layout you’re giving to browsers that don’t support grid …because really, IE11 doesn’t support grid: that’s the whole reason why the syntax is namespaced by -ms.

You could jump through hoops to try to get your grid layout working in IE11, as detailed in a three-part series on CSS Tricks, but at that point, the amount of effort you’re putting in negates the time-saving benefits of using CSS grid in the first place.

Frankly, the whole point of prefixed CSS is that is not used after a reasonable amount of time (originally, the idea was that it would not be used in production, but that didn’t last long). As we’ve moved away from prefixes to flags in browsers, I’m seeing the amount of prefixed properties dropping, and that’s very, very good. I’ve stopped using autoprefixer on new projects, and I’ve been able to remove it from some existing ones—please consider doing the same.

And when it comes to IE11, I’ll continue to categorise it as a browser that doesn’t support CSS grid. That doesn’t mean I’m abandoning users of IE11—far from it. It means I’m giving them the layout that’s appropriate for the browser they’re using.

Remember, websites do not need to look exactly the same in every browser.

Wednesday, July 11th, 2018

Tuesday, July 10th, 2018

Twitter and Instagram progressive web apps

Since support for service workers landed in Mobile Safari on iOS, I’ve been trying a little experiment. Can I replace some of the native apps I use with progressive web apps?

The two major candidates are Twitter and Instagram. I added them to my home screen, and banished the native apps off to a separate screen. I’ve been using both progressive web apps for a few months now, and I have to say, they’re pretty darn great.

There are a few limitations compared to the native apps. On Twitter, if you follow a link from a tweet, it pops open in Safari, which is fine, but when you return to Twitter, it loads anew. This isn’t any fault of Twitter—this is the way that web apps have worked on iOS ever since they introduced their weird web-app-capable meta element. I hope this behaviour will be fixed in a future update.

Also, until we get web notifications on iOS, I need to keep the Twitter native app around if I want to be notified of a direct message (the only notification I allow).

Apart from those two little issues though, Twitter Lite is on par with the native app.

Instagram is also pretty great. It too suffers from some navigation issues. If I click through to someone’s profile, and then return to the main feed, it also loads it anew, losing my place. It would be great if this could be fixed.

For some reason, the Instagram web app doesn’t allow uploading multiple photos …which is weird, because I can upload multiple photos on my own site by adding the multiple attribute to the input type="file" in my posting interface.

Apart from that, though, it works great. And as I never wanted notifications from Instagram anyway, the lack of web notifications doesn’t bother me at all. In fact, because the progressive web app doesn’t keep nagging me about enabling notifications, it’s a more pleasant experience overall.

Something else that was really annoying with the native app was the preponderance of advertisements. It was really getting out of hand.

Well …(looks around to make sure no one is listening)… don’t tell anyone, but the Instagram progressive web app—i.e. the website—doesn’t have any ads at all!

Here’s hoping it stays that way.

Accessibility for Teams

I really, really like the way that this straightforward accessibility guide is subdivided by discipline. As Maya wrote in the blog post announcing its launch:

Each person on a team, whether you’re a manager, designer, or developer, has a role to play. Your responsibilities are different depending on your role. So that’s how we structured the guide, with a separate section for each of five roles:

  • Product management
  • Content design
  • UX design
  • Visual design
  • Front-end development

StaticGen | Top Open Source Static Site Generators

There are a lot of static site generators out there!

When 7 KB Equals 7 MB - Cloud Four

I remember Jason telling me about this weird service worker caching behaviour a little while back. This piece is a great bit of sleuthing in tracking down the root causes of this strange issue, followed up with a sensible solution.

Ways to think about machine learning — Benedict Evans

This strikes me as a sensible way of thinking about machine learning: it’s like when we got relational databases—suddenly we could do more, quicker, and easier …but it doesn’t require us to treat the technology like it’s magic.

An important parallel here is that though relational databases had economy of scale effects, there were limited network or ‘winner takes all’ effects. The database being used by company A doesn’t get better if company B buys the same database software from the same vendor: Safeway’s database doesn’t get better if Caterpillar buys the same one. Much the same actually applies to machine learning: machine learning is all about data, but data is highly specific to particular applications. More handwriting data will make a handwriting recognizer better, and more gas turbine data will make a system that predicts failures in gas turbines better, but the one doesn’t help with the other. Data isn’t fungible.

Monday, July 9th, 2018

devMode.fm // Going Offline: Service Workers with Jeremy Keith

I talked for an hour about service workers ‘n’ stuff

(Also available on Huffduffer.)

Thursday, July 5th, 2018

The trimCache function in Going Offline

Paul Yabsley wrote to let me know about an error in Going Offline. It’s rather embarrassing because it’s code that I’m using in the service worker for adactio.com but for some reason I messed it up in the book.

It’s the trimCache function in Chapter 7: Tidying Up. That’s the reusable piece of code that recursively reduces the number of items in a specified cache (cacheName) to a specified amount (maxItems). On page 95 and 96 I describe the process of creating the function which, in the book, ends up like this:

 function trimCache(cacheName, maxItems) {
   cacheName.open( cache => {
     .then( items => {
       if (items.length > maxItems) {
           trimCache(cacheName, maxItems)
         ); // end delete then
       } // end if
     }); // end keys then
   }); // end open
 } // end function

See the problem? It’s right there at the start when I try to open the cache like this:

cacheName.open( cache => {

That won’t work. The open method only works on the caches object—I should be passing the name of the cache into the caches.open method. So the code should look like this:

caches.open( cacheName )
.then( cache => {

Everything else remains the same. The corrected trimCache function is here:

function trimCache(cacheName, maxItems) {
  .then( cache => {
    .then(keys => {
      if (keys.length > maxItems) {
          trimCache(cacheName, maxItems)
        ); // end delete then
      } // end if
    }); // end keys then
  }); // end open then
} // end function

Sorry about that! I must’ve had some kind of brainfart when I was writing (and describing) that one line of code.

You may want to deface your copy of Going Offline by taking a pen to that code example. Normally I consider the practice of writing in books to be barbarism, but in this case …go for it.

Wednesday, July 4th, 2018

Going Offline - Polytechnic

This is a lovely review of Going Offline from Garrett:

With his typical self-effacing humour (chapter titles include Making Fetch Happen and Cache Me If You Can), and easy manner, Jeremy explains how Service Workers, uh, work, the clever things you can do with them, and most importantly, how to build your own.

Best of all, he’s put it into action!

To that end, this site now has its own home-grown, organic, corn fed, Service Worker.

Sunday, July 1st, 2018

Keynote: The Building Blocks Of The Indie Web - YouTube

Here’s the video of the talk I gave at Design4Drupal last week in Boston. There’s a good half an hour of questions at the end.

Keynote: The Building Blocks Of The Indie Web

Design-Driven Companies. Are We There Yet? » Mike Industries

Mike talks about the pros and cons of working with companies at different stages of design maturity:

  1. design hostile,
  2. design ignorant,
  3. design agnostic,
  4. design interested, and
  5. design driven.

Tuesday, June 26th, 2018

10 Progressive Web App Examples that Brand Owners can Learn From - Iflexion

Adriana Blum lists progressive web apps that are doing very, very well from Twitter, Trivago, Starbucks, Forbes, Debebhams, West Elm, Washington Post, Pinterest, AliExpress, and Lancôme.

Instead of choosing between the immediacy of a mobile website and the rich experience offered by native apps, you can now offer your target audiences the best of both and improve the commercial performance of your business to boot.

Saturday, June 23rd, 2018

New tools for art direction on the web

I’m in Boston right now, getting ready to speak at An Event Apart. This will be my second (and last) Event Apart of the year—the other time was in Seattle back in April. After that event, I wrote about how inspired I was:

It was interesting to see repeating, overlapping themes. From a purely technical perspective, three technologies that were front and centre were:

  • CSS grid,
  • variable fonts, and
  • service workers.

From listening to other attendees, the overwhelming message received was “These technologies are here—they’ve arrived.”

I was itching to combine those technologies on a project. Coincidentally, it was around that time that I started planning to publish The Gęsiówka Story. I figured I could use that as an opportunity to tinker with those front-end technologies that I was so excited about.

But I was cautious. I didn’t want to use the latest exciting technology just for the sake of it. I was very aware of the gravity of the material I was dealing with. Documenting the story of Gęsiówka was what mattered. Any front-end technologies I used had to be in support of that.

First of all, there was the typesetting. I don’t know about you, but I find choosing the right typefaces to be overwhelming. Despite all the great tips and techniques out there for choosing and pairing typefaces, I still find myself agonising over the choice—what if there’s a better choice that I’m missing?

In this case, because I wanted to use a variable font, I had a constraint that helped reduce the possibility space. I started to comb through v-fonts.com to find a suitable typeface—I was fairly sure I wanted a serious serif.

I had one other constraint. The font file had to include English, Polish, and German glyphs. That pretty much sealed the deal for Source Serif. That only has one variable axis—weight—but I decided that this could also be an interesting constraint: how much could I wrangle out of a single typeface just using various weights?

I ended up using font weights of 75, 250, 315, 325, 340, 350, 400, and 525. Most of them were for headings or one-off uses, with a font-weight of 315 for the body copy.

(And can I just say once again how impressed I am that the founding fathers of CSS were far-sighted enough to keep those font weight ranges free for future use?)

Getting the typography right posed an interesting challenge. This was a fairly long piece of writing, so it really needed to be readable without getting tiring. But at the same time, I didn’t want it to be exactly pleasant to read—that wouldn’t do the subject matter justice. I wanted the reader to feel the seriousness of the story they were reading, without being fatigued by its weight.

Colour and type went a long way to communicating that feeling. The grid sealed the deal.

The Gęsiówka Story is mostly one single column of text, so on the face of it, there isn’t much opportunity to go crazy with CSS Grid. But I realised I could use a grid to create a winding effect for the text. I had to be careful though: I didn’t want it to become uncomfortable to read. I wanted to create a slightly unsettling effect.

Every section element is turned into a seven-column grid container:

section {
    display: grid;
    grid-column-gap: 2em;
    grid-template-columns: 2em repeat(5, 1fr) 2em;

The first and last columns are the same width as the gutters (2em), effectively creating “outer” gutters for the grid. Each paragraph within the section takes up six of the seven columns. I use nth-of-type to alternate which six columns are used (the first six or the last six). That creates the staggered indendation:

section > p {
    grid-column: 1/7;
section > p:nth-of-type(even) {
    grid-column: 2/8;

Staggered grid.

That might seem like overkill just to indent every second paragraph by 4em, but I then used the same grid dimensions to layout figure elements with images and captions.

section > figure {
    display: grid;
    grid-column-gap: 2em;
    grid-template-columns: 2em repeat(5, 1fr) 2em;

Then I can lay out differently proportioned images across different ranges of the grid:

section > figure.landscape > img {
    grid-column: 1/5;
section > figure.landscape > figcaption {
    grid-column: 5/8;
section > figure.portrait > img {
    grid-column: 1/4;
section > figure.portrait > figcaption {
    grid-column: 4/8;

Because they’re positioned on the same grid as the paragraphs, everything lines up nicely (and yes, if subgrid existed, I wouldn’t have to redeclare the grid dimensions for the figures).

Finally, I wanted to make sure that the whole thing could be read offline. After all, once you’ve visited the URL once, there’s really no reason to make any more requests to the server. Static documents—and books—are the perfect candidates for an “offline first” approach: always look in the cache, and only go to the network as a last resort.

In this case I used a variation of my minimal viable service worker script, and the result is a very short set of instructions. There’s a little bit of pre-caching going on: I grab the variable font and the HTML page itself (which includes the CSS inlined).

So there you have it: variable fonts, CSS grid, and service workers: three exciting front-end technologies, all of which can be applied as progressive enhancements on top of the core content.

Once again, I find that it’s personal projects that offer the most opportunities to try out new or interesting techniques. And The Gęsiówka Story is a very personal project indeed.

I discovered a browser bug - JakeArchibald.com

Jake’s blow-by-blow account of uncovering a serious browser vulnerability is fascinating. But if you don’t care for the technical details, skip ahead to to how different browser makers handled the issue—it’s very enlightening. (And if you do care for the technical details, make sure you click on the link to the PDF version of this post.)

I Don’t Believe in Full-Stack Engineering • Robin Rendle

A good ol’ rant from Robin.

HTML and CSS and JavaScript have always been looked down upon by many engineers for their quirks. When they see a confusing and haphazardly implemented API across browsers (HTML/CSS/JS), I see a swarming, writhing, and constantly improving interface that means we can read stuff that was written fifteen years ago and our browsers can still parse it.

Before jumping to conclusions, read the whole thing. Robin isn’t having a go at people who consider themselves full-stack developers; he’s having a go at the people who are only hiring back-end developers and expecting them to automatically be “full stack.”

Wednesday, June 20th, 2018

The three lessons that changed how I think about design systems

  1. Know where you stand before starting the journey
  2. Make sure everyone is speaking the same language
  3. Integrate the right tools into your team’s workflow

Monday, June 18th, 2018

The crooked timber of humanity | 1843

Tom Standage—author of the brilliant book The Victorian Internet—relates a tale of how the Chappe optical telegraph was hacked in 19th century France, thereby making it one of the earliest recorded instances of a cyber attack.

Praise for Going Offline

I’m very, very happy to see that my new book Going Offline is proving to be accessible and unintimidating to a wide audience—that was very much my goal when writing it.

People have been saying nice things on their blogs, which is very gratifying. It’s even more gratifying to see people use the knowledge gained from reading the book to turn those blogs into progressive web apps!

Sara Soueidan:

It doesn’t matter if you’re a designer, a junior developer or an experienced engineer — this book is perfect for anyone who wants to learn about Service Workers and take their Web application to a whole new level.

I highly recommend it. I read the book over the course of two days, but it can easily be read in half a day. And as someone who rarely ever reads a book cover to cover (I tend to quit halfway through most books), this says a lot about how good it is.

Eric Lawrence:

I was delighted to discover a straightforward, very approachable reference on designing a ServiceWorker-backed application: Going Offline by Jeremy Keith. The book is short (I’m busy), direct (“Here’s a problem, here’s how to solve it“), opinionated in the best way (landmine-avoiding “Do this“), and humorous without being confusing. As anyone who has received unsolicited (or solicited) feedback from me about their book knows, I’m an extremely picky reader, and I have no significant complaints on this one. Highly recommended.

Ben Nadel:

If you’re interested in the “offline first” movement or want to learn more about Service Workers, Going Offline by Jeremy Keith is a really gentle and highly accessible introduction to the topic.

Daniel Koskine:

Jeremy nails it again with this beginner-friendly introduction to Service Workers and Progressive Web Apps.

Donny Truong

Jeremy’s technical writing is as superb as always. Similar to his first book for A Book Apart, which cleared up all my confusions about HTML5, Going Offline helps me put the pieces of the service workers’ puzzle together.

People have been saying nice things on Twitter too…

Aaron Gustafson:

It’s a fantastic read and a simple primer for getting Service Workers up and running on your site.

Ethan Marcotte:

Of course, if you’re looking to take your website offline, you should read @adactio’s wonderful book

Lívia De Paula Labate:

Ok, I’m done reading @adactio’s Going Offline book and as my wife would say, it’s the bomb dot com.

If that all sounds good to you, get yourself a copy of Going Offline in paperbook, or ebook (or both).