JavaScript

Focus rings on Discord

This is a fascinating deep dive by the people at Discord on their development of a focus ring component and all the problems they had to overcome:

Browsers implement default focus rings that apply to all elements, but the ability to style these is (currently) very limited. These rings, while they have recently improved greatly in Chrome and Edge, are also not very pleasant when integrated with the rest of Discord’s design, and other browsers like Firefox are almost entirely invisible in most cases due to the thinness and low contrast of their styles.

As such, we want to implement a custom focus ring style. At a glance, this seems relatively simple, but when dealing with the variety of use cases Discord has for these rings, the list of requirements quickly grows, and the options for implementations shrink.

Ideally, we want to match the browser’s focus ring behavior exactly. Within Discord, this means that a comprehensive focus ring implementation needs to:

  • Perfectly map to the element that has focus (with exceptions listed below).
  • Follow elements as they move when containers scroll.
  • Follow elements as they animate and transition within the document.
  • Not be clipped off when the focused element is bounded by overflow: hidden or other bounding techniques.
  • Respect occlusion of overlapping elements, but not be occluded by an element’s own z-index.

Additionally, to be able to implement pleasant and overall better focus styles for various elements in the app, we have additional requirements to be able to:

  • Apply the focus ring on a different element than the actual focused element
  • Provide positional offsets to adjust ring placement around the element.
  • Adjust ring styles to match the look and feel of the surrounding context (could include changing border radius, color, shape, and more)
  • Specify a style for when focus is within an element, for example to indicate the bounds of a widget.

See the source link for the rest.

Why browser diversity matters: Chrome unilaterally creates de facto standards

Yet another great example of why browser diversity matters and why Chrome’s overwhelming presence in both mobile and desktop use is harmful to the open web: some developers mistake Chrome’s adoption of an API as a web standard, when both Mozilla and Apple have serious concerns about the security of said API:

In issue #509 of JavaScript Weekly, Chrome’s new File System Access API was mistakenly referred to as an “open standard.” The author probably assumed that a feature with a specification and an implementation in Chrome must therefore be a web standard, but that is not necessarily the case.

The API in question is currently hosted by the Web Incubator Community Group (WICG), a place where browser vendors can propose, discuss, and develop new web platform features, and receive feedback from the wider community.

[…]

Google has been developing the File System Access API for at least the past two years and decided to ship it in Chrome in October (last month). As part of this process, Google asked both Apple and Mozilla for their official positions on the API. So far, their responses have not been positive (Apple, Mozilla).

It seems that Google decided to ship the File System Access API in Chrome without endorsement from Apple or Mozilla because it believes that this feature “moves the web platform forward”:

Interoperability risk is the risk that browsers will not eventually converge on an interoperable implementation of the proposed feature. … If a change has high interop/compat risk but is expected to significantly move the web forward, Chromium will sometimes welcome it.

Standardization and support from Apple or Mozilla is not a requirement for shipping a web platform feature in Chrome. However, because of Chrome’s large market share, there is a risk of such a feature becoming a de facto standard:

Changes to Chrome’s functionality create de facto standards. Market participants must adhere to these standards or risk their technology no longer being compatible with most websites.

Accessibility issues with toasts and how to mitigate them

You may have recently read Adrian Roselli’s Scraping Burned Toast, Chris Coyier’s summary of the current “toast conversation”. Or maybe you’ve browsed the GitHub repository for A Standard ‘Toast’ UI Element and its WICG discussion thread.

Or maybe you’re familiar with the concept of toasts from Android development and Material Design.

But regardless of how familiar you are with the concept of a “toast”, work has been progressing on try to pave the existing cow paths different UI library definitions have set for said potential component. Unfortunately, the level of concern given to the accessibility and inclusive UX of a toast component varies quite a bit, depending on which component library you review.

[…]

Defining a toast

[…]

At a high level, toasts should be used to indicate the completion of a task or process initiated by the user or the application itself. For instance, a notification verifying the saving of a file, that a message had been properly sent, or a that a meeting was about to start.

If someone were to ignore, or miss a toast message, due to its timed display, there should be no negative impact on their current activities or the status that the message conveyed. Using the previous examples, ignoring a toast message would still mean that a file was saved, that a message was sent, or that a meeting was about to start.

[…]

Inclusive UX of a toast

A toast component should be considered a type of status message, and thus should be given a role="status". This will ensure that when a toast is displayed on screen, its contents will be, politely, communicated to assistive technologies, such as screen readers.

Ideally, a toast component should contain no interactive controls, as by doing so an immediate divergence of inclusive UX is introduced.

 

See the source link for a list of issues and some ways to mitigate them.

The self-fulfilling prophecy of poor mobile performance

There are plenty of stories floating around about how some organization improved performance and suddenly saw an influx of traffic from places they hadn’t expected. This is why. We build an experience that is completely [unusable] for them, and is completely invisible to our data. We create, what Kat Holmes calls, a “mismatch”. So we look at the data and think, “Well, we don’t get any of those low-end Android devices so I guess we don’t have to worry about that.” A self-fulfilling prophecy.

I’m a big advocate for ensuring you have robust performance monitoring in place. But just as important as analyzing what’s in the data, is considering what’s not in the data, and why that might be.

Spoiler: server-rendered HTML can work offline

The architecture astronauts who, for the past decade, have been selling us on the necessity of React, Redux, and megabytes of JS, cannot comprehend the possibility of building an email app in 2020 with server-rendered HTML 😴

[…]

The effects are truly toxic. Last decade’s obsession with SPAs has poisoned the minds of even the brightest teachers in our industry.

Like, there’s no way this stuff can work offline, right?!

Briefly read up on how HEY is implemented. Is this a correct summary of the pros and cons of its [server]-centric approach?
– Pro: Works fast on older devices.
– Con: Can’t be used offline.

Hey now

Progressive enhancement is at the heart of everything I do on the web. It’s the bedrock of my speaking and writing too. Whether I’m writing about JavaScript, Ajax, HTML, or service workers, it’s always through the lens of progressive enhancement. Sometimes I explicitly bang the drum, like with Resilient Web Design. Other times I don’t mention it by name at all, and instead talk only about its benefits.

I sometimes get asked to name some examples of sites that still offer their core functionality even when JavaScript fails. I usually mention Amazon.com, although that has other issues. But quite often I find that a lot of the examples I might mention are dismissed as not being “web apps” (whatever that means).

The pushback I get usually takes the form of “Well, that approach is fine for websites, but it wouldn’t work something like Gmail.”

It’s always Gmail. Which is odd. Because if you really wanted to flummox me with a product or service that defies progressive enhancement, I’d have a hard time with something like, say, a game (although it would be pretty cool to build a text adventure that’s progressively enhanced into a first-person shooter). But an email client? That would work.

[…]

Can you build something that works just like Gmail without using any JavaScript? No. But that’s not what progressive enhancement is about. It’s about providing the core functionality (reading and writing emails) with the simplest possible technology (HTML) and then enhancing using more powerful technologies (like JavaScript).

Progressive enhancement isn’t about making a choice between using simpler more robust technologies or using more advanced features; it’s about using simpler more robust technologies and then using more advanced features. Have your cake and eat it.

Fortunately I no longer need to run this thought experiment to imagine what it would be like if something like Gmail were built with a progressive enhancement approach. That’s what HEY is.

Sam Stephenson describes the approach they took:

HEY’s UI is 100% HTML over the wire. We render plain-old HTML pages on the server and send them to your browser encoded as text/html. No JSON APIs, no GraphQL, no React—just form submissions and links.

If you think that sounds like the web of 25 years ago, you’re right! Except the HEY front-end stack progressively enhances the “classic web” to work like the “2020 web,” with all the fidelity you’d expect from a well-built SPA.

See? It’s not either resilient or modern—it’s resilient and modern. Have your cake and eat it.

And yet this supremely sensible approach is not considered “modern” web development:

The architecture astronauts who, for the past decade, have been selling us on the necessity of React, Redux, and megabytes of JS, cannot comprehend the possibility of building an email app in 2020 with server-rendered HTML.

[…]

Their focus is very much on people above technology. They’ve taken a human-centric approach to their product and a human-centric approach to web development …because ultimately, that’s what progressive enhancement is.

Always bet on HTML

In September of 2019, Zach Leatherman tweeted

Which has a better First Meaningful Paint time?

  1. a raw 8.5MB HTML file with the full text of every single one of my 27,506 tweets
  2. a client rendered React site with exactly one tweet on it

(Spoiler: @____lighthouse reports 8.5MB of HTML wins by about 200ms)

Take a moment to wrap your head around that.

It’s perceivably faster to load 8.5 megabytes of HTML than it is to load a single tweet with a client-side React app.

[…]

Real companies can and do build apps with HTML first

The folks at Basecamp just released a new email product, Hey, that tries to address a lot of the stuff that people find frustrating about email.

Neither product is really my cup of tea, but what I find super interesting is how Hey is built.

It’s core is server-rendered HTML. Basecamp is a Ruby on Rails shop (their CTO created Rails). Almost every view in the app is created on a server.

Then, they sprinkle just a little vanilla JS on top to turn things up to 11.

Basecamp uses a project they open sourced called Turbolinks. This JavaScript plugin intercepts link clicks and progressively enhances a server-side app into a single-page app (or SPA) by fetching additional pages with Ajax and only replacing the stuff that needs updating.

By using this approach, if the JS fails or isn’t supported, the app still loads and works and gives people the full experience. It also means you don’t have to wait for the full JS package to load before you can start using the app.

You still get the benefits of faster page loading that SPAs sometimes give you, but you don’t have to maintain two code bases or do complicated server-to-client hand offs (“rehydration” as they call it in the React world).

Leaflet - a JavaScript library for interactive maps

Leaflet is the leading open-source JavaScript library for mobile-friendly interactive maps. Weighing just about 38 KB of JS, it has all the mapping features most developers ever need.

Leaflet is designed with simplicity, performance and usability in mind. It works efficiently across all major desktop and mobile platforms, can be extended with lots of plugins, has a beautiful, easy to use and well-documented API and a simple, readable source code that is a joy to contribute to.

Brutalist Web Design

The term brutalism is often associated with Brutalist Architecture, however it can apply to other forms of construction, such as web design.

[…]

The term brutalism is derived from the French béton brut, meaning “raw concrete”. Although most brutalist buildings are made from concrete, we’re more interested in the term raw. Concrete brutalist buildings often reflect back the forms used to make them, and their overall design tends to adhere to the concept of truth to materials.

A website’s materials aren’t HTML tags, CSS, or JavaScript code. Rather, they are its content and the context in which it’s consumed. A website is for a visitor, using a browser, running on a computer [or mobile device] to read, watch, listen, or perhaps to interact. A website that embraces Brutalist Web Design is raw in its focus on content, and prioritization of the website visitor.

Brutalist Web Design is honest about what a website is and what it isn’t. A website is not a magazine, though it might have magazine-like articles. A website is not an application, although you might use it to purchase products or interact with other people. A website is not a database, although it might be driven by one.

They list the following principles: