Scaling CSS Layout Beyond Pixels Stephanie Eckles @5t3ph • ModernCSS.dev

fl quite literally make or break your layout. In this new world, strict pixel values are so Web 2.0. Let’s review modern CSS techniques for building

the users’ browsing environment is not predictable

Started from the farm, now I’m here

.stage { width: 800px; height: 600px; display: grid; place-items: center; grid-template-areas: “stage”; overflow: hidden; & > * { grid-area: stage; text-align: center; } }

Evolution of Web Design fl fi fi Small, nite, absolute canvas In nite, exible, adaptive canvas

Jen Simmons “Getting Out Of Our Ruts” - An Event Apart, 2016

Jen Simmons “Getting Out Of Our Ruts” - An Event Apart, 2016

Jen Simmons “Everything You Know About Web Design Just Changed” - View Source, 2018

Jen Simmons “Everything You Know About Web Design Just Changed” - View Source, 2018

Jen Simmons “Everything You Know About Web Design Just Changed” - View Source, 2018

  1. Contracting & Expanding how designs adapt to available space

  1. Flexibility allowing variable rate adaptations

  1. Viewport purposely using viewport edges & units

fi Rachel Andrew “Making Things Better: Rede ning the Technical Possibilities of CSS” - An Event Apart, 2019

these are ok, actually? (but we can build them better)

the following techniques are guaranteed* to surprise and delight * not a legally-binding guarantee, YMMV, etc, etc your designers you

using adaptive layout techniques is a trust exercise between devs, designers, and the browser

flexibility within constraints

find comfort with variability adapt to the environment

clamp() the slinky of web design Global 90% Chromium v79 Firefox v75 Safari v13.1

clamp(min, ideal, max max) min ideal

font-size: 1rem ideal, 4vw max) 3rem clamp(min,

padding: 1rem ideal, 3% 1.5rem clamp(min, max) width: clamp(min, 30ch ideal, 80% max) 80ch

using clamp() for intrinsic design , y ya gn i s de ns! e k to ✓ designers provide min and max ✓ devs determine dynamic dimensions

min() and max() context-dependent options Global 90% Chromium v79 Firefox v75 Safari v13.1

min | max(2+ values) uses smallest value uses largest value

min( 100vw - 3rem, 80ch ) selected when viewport < 80ch selected when viewport > 80ch

.container { } width: min( 100vw - 3rem, 80ch ) margin-inline: auto;

.container { width: min( 100vw - 3rem, var(- -container-max, 80ch) margin-inline: auto; )

allows intrinsic sizing Global 94% Chromium v22 Firefox v3 fi

  • width property + pre xes Safari v6.1

fi sizing keywords available inline space fit-content min-content max-content t-content mincontent max-content

t-content t-content will grow but not over ow mincontent fl max-content has over ow potential max-content fl fi fi available inline space

width: fit-content contentrelative width without changing the display value! fl Macaroon tiramisu souf é tart chocolate cake

grid units & functions slinky potential everywhere Global 93% Chromium v57 Firefox v52 Safari v10.1

CSS grid is the perfect toolset for achieving flexibility within constraints

grid-template-columns: repeat( auto-fit, minmax(30ch, 1fr ) ) fi fi fi de ne a recurring pattern create as many tracks that t de nes a range minimum value maximum value

grid-template-columns: repeat( auto-fit, minmax(30ch, 1fr ) )

repeat( auto-fit, minmax( min( 100%, var(- -grid-min, 30ch) ), 1fr ) )

grid-template-columns: fit-content( 20ch ) minmax(50%, 1fr)

grid-template-columns: fit-content( var(- -sidebar-max, 20ch) ) minmax(50%, 1fr)

but what about spacing?

24px 32px 32px

gap, padding, & margin

gap, padding, & margin have different purposes

gap, padding, & margin use appropriate units & adaptive methods

goal: make spacing contextual so it flexes beyond the happy path

padding - box spacing clamp() with % & rem relative to the inline size

24px 32px 32px clamp()

24px 32px 32px 🙅 🎉 clamp() min()

main, .card { padding: clamp(1.5rem, 6%, 3rem) } main { width: min(100%, 60ch) }

main, .card { padding: clamp(1.5rem, 6%, 3rem) } main { width: min(100%, 60ch) }

main, .card { padding: clamp(1.5rem, 6%, 3rem) } main { width: min(100%, 60ch) } behavior up to 400% zoom

behavior comparison at 400% zoom clamp() px

:root { - -padding-sm: clamp(1rem, } 3%, 1.5rem);

  • -padding-md: clamp(1.5rem, 6%, 3rem);
  • -padding-lg: clamp(3rem, 12%, 6rem); , y ya gn i s de ns! e k to

margin - block layout spacing min() with viewport units, rem create contextual spacing

margin-block-start: min(4rem, 8vh); } static fl fl .block- ow { ex

.block- ow { margin-block-start: min(4rem, 8vh); fl }

.block- ow { margin-block-start: min(4rem, 8vh); } fl 8vh at 400% zoom

:root { - -block- ow-sm: min(2rem, 4vh); - -block- ow-md: min(4rem, 8vh); - -block- ow-lg: fl fl fl } min(8rem, 16vh); , y ya gn i s de ns! e k to

:is(body, .block- ow) > * + * { margin-block-start: var(- -block- ow, var(- -block- ow-md) ); fl fl fl }

gap - layout component spacing clamp() with vmax & rem

gap ! x o b x e l f & d i r g n i e l b a l i a v a

gap: clamp(1.5rem, 6vmax, 3rem); , y ya gn i s de ns! e k to

gap: clamp(1.5rem, 6vmax, 3rem); = gap: 48px = gap: 40px

gap: clamp(1.5rem, 6vmax, 3rem); zoom 400% = gap: 24px

:root { - -layout-gap-sm: clamp(1rem, 3vmax, 1.5rem) }

  • -layout-gap-md: clamp(1.5rem, 6vmax, 3rem);
  • -layout-gap-lg: 4rem); clamp(3rem, 8vmax,

  • { box-sizing: border-box; margin: 0; } body { font-family: system-ui; background-color: #28173c; color: #cc92ff; } body > * + * { margin-block-start: min(4rem, 8vh); } header { color: #28173c; background-color: #cc92ff; text-align: center; display: grid; gap: max(1rem, 2vmax); padding-block: clamp(3rem, 12%, 6rem); } main { width: min(100% - 8vmin, 120ch); margin-inline: auto; } ul { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 30ch), 1fr)); gap: max(2rem, 4vmax); } ul li > * + * { margin-block-start: 1em; }

Steph, why are you so 🤔 anti-media queries?

I’m pro-selective use of media queries Viewport-relative media queries aren’t scalable and are no longer the best tool for the job

things I couldn’t fit in this talk… container queries container units :has()

☙ Why haven’t we already embraced Intrinsic Web Design? ❧

hard to relinquish control feel trapped by processes not empowered to create or request change

spicy take incoming… necessary the rigidity of design systems and frameworks is at odds with intrinsic web design

intrinsic web design cheatsheet clamp() min() / max() fit-content / () grid auto-fit grid minmax start using contextual spacing gap, margin, and padding

ModernCSS.dev/spacing 5t3ph.dev/workshop

The web’s greatest strength, I believe, is often seen as a limitation, as a defect. It is the nature of the web to be flexible, and it should be our role as designers and developers to embrace this flexibility, and produce pages which, by being flexible, are accessible to all. John Allsop A Dao of Web Design, 2000

Scaling CSS Layout Beyond Pixels Stephanie Eckles @5t3ph • ModernCSS.dev