« resources

Smashing Workshop

Modern & Resilient

managing support across the platform

workshops.oddbird.net/smash24/resilient/

Cmd/Ctr-K for Controls

New Features!

The color-mix() Function is Cool!

Does color-mix() Have Support??

Hand written note says I like you, do you like me?

Can I use… Color-Mix()?

X's, checks, and question marks scribbled all over the note in random red and green variations
70.35% Partial???

Browser Support is Not A Binary

Arbitrary Cutoff? 95% ? 100% ? Last Two ?

screenshot
Change your CanIUse settings [Features with 100% browser support are capped at 97.98%]

Support stats Are Updated Manually

Usage stats Vary Widely

MDN

Mozilla Developer Network

screenshot
Baseline summaries [web.dev]

⚠️ Warning A11y Support Not Included

Baseline Does Not Really Cover Baseline Support by Adrian Roselli

Also… Web Platform Tests

File and Follow Browser Issues

How do we do… Progressive Enhancement?

We Already Do Progressive Enhancement

Responsive ➡ Resilient

Not Re-Writing For Every Viewport

[Viewport Sizes]

Consider… Features Not Browsers

avatar

If you have to entirely re-engineer for IE… you’re Doing It Wrong.

— Natalie Downe, CSS Systems

Don’t Assume Correlations

Now… Evergreen Browsers

Re-Define What ‘Support’ Means

Not identical, but equivalent

avatar

There is a difference between support and optimization.

— Brad Frost, support vs optimization (2011)

Start from Your Baseline Functionality

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

— Jeremy Keith, Resilient Web Design

This is… Progressive Enhancement

avatar

You can use it and not use it at the same time, because it works and it doesn’t work at the same time. It’s Quantum CSS! It’s Magic!

— Jen Simmons, Intro to Resilient CSS

Headshot of Jen Simmons.

Jen Simmons Resilient Videos

Some issues… No Fallback Needed

CSS is Resilient

CSS Errors Silently

A feature Of CSS (& HTML)

Error recovery using ; and (matched) }; [present, debug]
  • CSS uses semi-colon and matched curly brackets to recover

Testing fallbacks… Comment Out The Code

No Fallback [present, debug]
screenshot
Dave Rupert [Getting started with View Transitions]

Some issues…Silent’ Fallback

  1. Filtering

  2. Cascading
  3. Defaulting
  4. Resolving
  5. Formatting
  6. Constraining
Value Processing
  • That silent error handling happens before the cascade
  • When browsers discard any declaration they don’t understand
  • Including…
css…
h2 {
  color: myFakeColor;
}
  • Known properties (like color)
  • With unknown values, like myFakeColor
  • This is considered a syntax error, easy to catch early
screenshot
See also ‘formal syntax’ on MDN [www.w3.org]
  • Which is done by type checking the value
  • Each property has a formal syntax
  • Allowing clearly defined data types.
  • A color is different from a keyword, a length, or a number
  • We can look at the formal syntax of a property
  • To see what value types are allowed
css…
.example {
  --yes: calc(3em * 2);
  --no: calc(3em * 2px);
}
  • There are some other type-checking edge cases to watch for
  • Like the difference between a number (without units)
  • And a length, percentage, or duration (with units)
  • For example, we can’t multiply two lengths,
  • but we can multiply a length times a number
Not All Zeros are Equal [present, debug]
  • Even more confusing,
  • Zero (without units) is sometimes allowed as a length or percentage
  • But not always!
  • Be careful using 0 when you mean something like 0 degrees

Order of Appearance

And parse-time validation

  • We can use this parse-time (syntax) validation
  • Along with order-of-appearance
  • To silently fall back from one value to another
css…
h2 {
  color: green;

  /* discarded by old browsers before cascade */
  /* wins cascade when read as valid syntax */
  color: oklch(0deg 50% 50%);
}
  • We can use a well-supported value
  • And then provide a second declaration with something new
  • Old browsers will discard the new syntax as invalid at parse time
  • (when filtering declarations)
  • But new browsers will keep both values around in the cascade
  • And the second one will win
  • So order doesn’t matter for old browsers,
  • But it does matter for newer browsers
Subgrid Form [present, debug]
Wide Gamut Colors (fallback) [present, debug]
  • This can work great for using new color formats
  • But we run into problems if we want store those colors
  • In custom properties
Invalid At Computed Value Time [present, debug]
  • We talked about this some,
  • But I want to go into it a bit more
  • Because this Invalid At Computed Value Time behavior
  • Is becoming more and more common in CSS
css…
.ಠ_ಠ {
  --(╯°□°)╯: ︵┻━┻;
}
“… is valid CSS.” --Tab Atkins (on Twitter, years ago)
ಠ_ಠ Valid Table-Flip [present, debug]
  • It doesn’t do anything
  • Unless we make it do something
css…
.ಠ_ಠ {
  --(╯°□°)╯: ︵┻━┻;
}
✅ Valid
  • According to CSS syntax rules
  • Valid to define

Syntactically Valid

(otherwise discarded at parse-time)

  • Declarations must be syntactically valid
  • But what’s that mean?
css…
.ಠ_ಠ {
  --(╯°□°)╯: ︵┻━┻;
  color: var(--(╯°□°)╯);
}
🤔 Valid?
  • Valid to access on (say) color prop
css…
.ಠ_ಠ {
  color: ︵┻━┻;
}
❌ Valid
  • Only becomes invalid
  • After we replace the variable
  • Color property requires color syntax

var() output Not Validated
Until Applied

  • Parse-time validation early, before cascade
  • We don’t know cascaded value

Variable substitution After Cascade is Complete

  • Var substitution has to wait
  • Go by syntax alone
css…
.ಠ_ಠ {
  --(╯°□°)╯: ︵┻━┻;
  color: var(--(╯°□°)╯);
}
✅ Valid (but will fail later)
  • Valid, but will fail later
  • Will fail after the cascade
  • Which is a problem…
css…
button {
  --fancy-color: oklch(0.8 0.1 0);

  color: pink;
  color: var(--fancy-color);
}
  • If we have a fancy color in the var
  • And try to provide a fallback
  • By repeating the property…
css…
button {
  --fancy-color: oklch(0.8 0.1 0);

  /* color: pink; DISCARDED by cascade */
  color: var(--fancy-color);
}
  • Fallback will be removed by the cascade
  • Before we know if the fancy color is supported
css…
button {
  --fancy-color: oklch(0.8 0.1 0);

  /* color: pink; DISCARDED by cascade */
  /* color: var(--fancy-color); INVALID */
}
  • In a browser without OKLCH
  • The variable will fail when subbed
  • We end up without any color!

Properties using var() become… Invalid At Computed Value Time

result: the property is un-set
Invalid At Computed Value Time [present, debug]
  • It doesn’t have a value
  • Solution:
  • Use @supports when setting variables

More and more Invalid at Computed Value Time

custom functions, if() function, etc
  • This is a behavior we’re likely to see more and more in CSS
  • And hopefully we’ll also see some new features
  • To help provide better used-value time fallbacks
  • For now the only option is using @supports

Support Queries

MDN Page
Wide Gamut Colors (v2) [present, debug]

Selector Queries

MDN Page
Selector Fallback :has() [present, debug]

:is() and :where() Are Forgiving Selector Lists

But Not Nesting

Forgiving Selector Lists [present, debug]

Preference Queries

MDN Page

@media Not Just Print & Viewport Sizes

prefers-color-scheme

light | dark | no-preference

prefers-contrast

low | high | no-preference

prefers-reduced-motion

reduce | no-preference

prefers-reduced-transparency

reduce | no-preference

The real advance in accessibility, is providing options and adapting to user preferences.

— Kate Kalcevich

  • Adapting to preferences isn’t just a fun way
  • to play with interactions (but it is fun!)
  • Providing options is central to accessibility

While the author (or publisher) often wants to give the documents a distinct look and feel, the user will set preferences to make all documents appear more similar.

— Håkon Lie, Cascading HTML style sheets – a proposal

  • And CSS was designed for it, from the start!
We're Not Alone, with browser logos, a guy in construction clothes carrying a laptop, and ET
  • It’s the whole reason we’re here today

People don’t think of themselves as disabled, so they don’t think the accessibility preference area applies to them.

— Eric W Bailey, Accessibility preference settings, information architecture, and internalized ableism

  • All of us use the web
  • And all of us have preferences
  • And a web that respects us people
  • Is a more usable web for everyone
Media Prefers… [present, debug]
screenshot
[No Motion Isn’t Always prefers-reduced-motion]
Reduced Motion [present, debug]

Media Features

MDN Page
css…
@media (hover: none) { }
@media (pointer: coarse) { }

How do you sell this To The Boss or Client?

We Don’t

It’s just the job we do

The web Is For People

Those people Rely On Our Services

Our job is Making The Web Usable

We don’t always Optimize For Every Situation

We do try to Support Everyone

The details Vary Across Projects

Sort issues By Impact Priority

Content should be viewable and accessible by default.

— W3C, Platform Design Principles

  • another design principle of the w3c
  • content should be viewable and accessible by default

At minimum Avoid Making Things Worse

First Do No Harm

  • This is our job as designers (engineers)
  • everything else we do in this workshop
  • everything else in CSS
  • built around this political vision
  • protect the content, protect the user
  • First, Do no harm
« resources

Smashing Workshop

Modern & Resilient

Bring this workshop to your company.
Slide Controls

View:

Navigate slides using the arrow-keys.