Snippets

These snippets are my attempt to save and organize various bits of code, best practices, and resources relating to web development and design. They also function as a to do list of sorts, for things I want to implement in my own code, but haven’t yet. The concept is inspired by Jeremy Keith’s links and CSS-Tricks, among other things. Enjoy.

JavaScript loading: Prefer DEFER Over ASYNC

ASYNC and DEFER are similar in that they allow scripts to load without blocking the HTML parser which means users see page content more quickly. But they do have differences:

  • Scripts loaded with ASYNC are parsed and executed immediately when the resource is done downloading. Whereas DEFER scripts don’t execute until the HTML document is done being parsed (AKA, DOM Interactive or performance.timing.domInteractive).
  • ASYNC scripts may load out-of-order, whereas DEFER scripts are executed in the order in which they appear in markup. (Although there’s a bug that makes DEFER’s execution order questionable in IE⇐9.)

Even though ASYNC and DEFER don’t block the HTML parser, they can block rendering. This happens when they’re parsed and executed before rendering is complete and take over the browser main thread. There’s nothing in the spec that says they have to wait until rendering is complete. ASYNC scripts execute immediately once they finish downloading, and DEFER scripts execute after DOM Interactive.

[…]

DEFER always causes script execution to happen at the same time as or later than ASYNC. Presumably, scripts are made DEFER or ASYNC because they are less important for the critical content on the page. Therefore, it’s better to use DEFER so that their execution happens outside of the main rendering time.

DEFER scripts can never block synchronous scripts, while ASYNC scripts might depending on how quickly they download. Synchronous scripts are typically made synchronous because they are important for the critical content on the page. Therefore, it’s better to use DEFER so that synchronous scripts are not blocked from executing and their critical work is completed more quickly.

Tags: 

GPU Animation: Doing It Right

Most people now know that modern web browsers use the GPU to render parts of web pages, especially ones with animation. For example, a CSS animation using the transform property looks much smoother than one using the left and top properties. But if you ask, “How do I get smooth animation from the GPU?” in most cases, you’ll hear something like, “Use transform: translateZ(0) or will-change: transform.”

These properties have become something like how we used zoom: 1 for Internet Explorer 6 (if you catch my drift) in terms of preparing animation for the GPU — or compositing, as browser vendors like to call it.

But sometimes animation that is nice and smooth in a simple demo runs very slowly on a real website, introduces visual artefacts or even crashes the browser. Why does this happen? How do we fix it?

[…]

  • Watch out for the number and size of composite layers from the very beginning — especially ones created by implicit compositing. The “Layers” panel in your browser’s development tools is your best friend.
  • Modern browsers make heavy use of compositing not just for animation but to optimize the painting of page elements. For example, position: fixed and the iframe and video elements use compositing.
  • The size of compositing layers is likely be more important than the number of layers. In some cases, the browser will try to reduce the number of composite layers (see the “Layer Squashing” section of “GPU Accelerated Compositing in Chrome“); this prevents so-called “layer explosion” and reduces memory consumption, especially when layers have large intersections. But sometimes, such optimization has a negative impact, such as when a very large texture consumes much more memory than a few small layers. To bypass this optimization, I add a small, unique translateZ() value to each element, such as translateZ(0.0001px), translateZ(0.0002px), etc. The browser will determine that the elements lie on different planes in the 3D space and, thus, skip optimization.
  • You can’t just add transform: translateZ(0) or will-change: transform to any random element to virtually improve animation performance or to get rid of visual artifacts. GPU compositing has many drawbacks and tradeoffs to be considered. When not used sparingly, compositing will decrease overall performance at best, and crash browsers at worst.

Allow me to remind you of the big disclaimer: There is no official specification for GPU compositing, and each browser solves the same problems differently. Some sections of this article may become obsolete in a few months.

Tags: 

CSS Shorthand Syntax Considered an Anti-Pattern

Typically we would view shorthand syntax as a benefit: fewer keystrokes, fewer lines of code, less data over the wire. Sounds great! However, it comes with a rather troublesome side effect: it often unsets other properties that we never intended to modify.

When we write something like:

CSS

.btn {
  background: red;
}

…we’re likely to get a red background colour applied to our button. But what we’re really saying is this:

CSS

.btn {
  background-image: initial;
  background-position-x: initial;
  background-position-y: initial;
  background-size: initial;
  background-repeat-x: initial;
  background-repeat-y: initial;
  background-attachment: initial;
  background-origin: initial;
  background-clip: initial;
  background-color: red;
}

Simply by using the shorter syntax, we have implicitly decided that we want no image to start top-left, repeat x and y, to scroll with the element, and so on…

Nearly every problem, bug, or regression in CSS at scale is happens because we did too much too soon, and further down the line we’re being affected by that. What this basically comes down to is the fact that, with CSS, you should only ever do as little as you need to do and nothing more.

Misusing shorthand syntax is a surefire way to do too much too soon, as thus it should be avoided. CSS is a lot harder to undo than it is to do.

Tags: 

Using notifications responsibly

We see an increasing number of websites using notifications irresponsibly. The moment you visit the site, you get prompted by the browser to sign up for notifications. Not only is it annoying to be asked immediately, but it is unlikely to be effective.

We wanted to set a good example for responsible use of push notifications. So we don’t ask for permission to send push notifications until the user selects the button asking to turn notifications on. And we only provide the option to subscribe at the bottom of articles.

Screenshot of Cloud Four's options to subscribe to new articles via either web notifications or email

Once someone selects that button, then we trigger the browser alert asking for permission to send notifications. If the person signs up, we send a quick notification thanking them and update the button to indicate how they can turn off notifications.

Cloud Four's Get Notifications button turns into a Turn Off Notifications button after turning on notifications.

For more on using web notifications responsibly, we recommend Best Practices for Push Notifications Permissions UX by Owen Campbell-Moore.

Tags: 

Premonish - A library for predicting what element a user will interact with next.

A screenshot of the Premonish page, with different coloured squares in the center, top left, bottom left, and bottom right, along with the Premonish header and some descriptive text " Premonish - A library for predicting what element a user will interact with next."

This is really cool. This library seems to use the pointer’s trajectory to predict what you’re heading towards, and highlights the appropriate cube. I suspect this only works with pointers that can be detected as moving, like mice and styluses that have that capability, but probably does nothing useful with touch in most cases. Either way, give it a shot, it’s eerie. The most obvious use case for this is to pre-load a link if the user starts to head for it, but of course that has the side effect of possibly wasting the user’s data if they’re on a capped connection.

Tags: 

Performant Parallaxing

Love it or hate it, parallaxing is here to stay. When used judiciously it can add depth and subtlety to a web app. The problem, however, is that implementing parallaxing in a performant way can be challenging. In this article we’ll discuss a solution that is both performant and, just as importantly, works cross-browser.

An abstracted view of what a CSS parallax effect would look like if the layers were to lift up off of the screen, and you could step to the side to see them in three axes, with arrows showing the layers moving up and down along the X axis.

TL;DR

  • Don’t use scroll events or background-position to create parallax animations.
  • Use CSS 3D transforms to create a more accurate parallax effect.
  • For Mobile Safari use position: sticky to ensure that the parallax effect gets propagated.

[…]

Both Scott Kellum and Keith Clark have done significant work in the area of using CSS 3D to achieve parallax motion, and the technique they use is effectively this:

  • Set up a containing element to scroll with overflow-y: scroll (and probably overflow-x: hidden).
  • To that same element apply a perspective value, and a perspective-origin set to top left, or 0 0.
  • To the children of that element apply a translation in Z, and scale them back up to provide parallax motion without affecting their size on screen.

The CSS for this approach looks like so:

CSS

.container {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: scroll;
  perspective: 1px;
  perspective-origin: 0 0;
}
 
.parallax-child {
  transform-origin: 0 0;
  transform: translateZ(-2px) scale(3);
}

Which assumes a snippet of HTML like this:

HTML

<div class="container”>
  <div class="parallax-child”></div>
</div>

Tags: 

Large, custom, accessible checkboxes and radio buttons on GOV.UK

A screenshot of extra large checkboxes and radio buttons on GOV.UK sites

Early in the development of GOV.UK we observed in research how a majority of users would click on radio button or checkbox controls rather than on their labels, despite the fact that the labels are much bigger and therefore easier to click (see Fitt’s Law).

[…]

We reasoned that this was because users didn’t know whether or not they could click on the labels. Many websites don’t let you click on labels, so choosing to always click on the control is perfectly rational user behaviour.

[…]

First we thought we’d try to make it really obvious that you could click our labels, so we coloured them grey and made them respond to the mouse hovering over them.

We thought this would work, so we rolled out the design across services on GOV.UK. We saw again and again though in lab research that most users still clicked on the controls.

[…]

In our latest iteration we’ve replaced the native browser controls with custom ones, which all our supported browsers will get.

We’ve also removed the grey background, as it did not have the effect on user behaviour that it was intended to.

Tags: 

Pages