slides.oddbird.net/css-next/smashingsf/

Styling the Intrinsic Web

slides.oddbird.net/css-next/smashingsf/

@ SmashingConf SF 2022
Painting of a young white woman
in a white gown and head scarf,
sitting alone on tall a cloth-draped box,
with her arms crossed
and her head looking down,
resting on one hand.

New Content!!!

<P><FONT SIZE="4" COLOR="BLUE"></FONT></P>
<P><FONT SIZE="4" COLOR="BLUE"></FONT></P>
<P><FONT SIZE="4" COLOR="BLUE"></FONT></P>
<P><FONT SIZE="4" COLOR="BLUE"></FONT></P>
<P><FONT SIZE="4" COLOR="BLUE"></FONT></P>

We use Classes & Attributes

/* <a href="#" class="rad">…</a> */
a { color: teal; }
.rad { color: violet; }
[href] { color: orange; }

on every html element,
every css property
must have exactly one value

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

– Kate Kalcevich, this morning (paraphrase)

7 year old Miriam with her hands on her knees

1989 The Artist (it me)

Not paying attention

Everyone has Input

  • 🖥 User Agent (Browser)
  • 👥 User (Preferences)
  • 🎨 Author (Site)

We’re designing unknown content with unknown collaborators on an infinite and unknowable canvas, across operating systems, interfaces, writing-modes, & languages

– me

The fact we can control a paper page is really a limitation of that medium.

– John Allsopp, 2000

There are too many variables to consider.

– Keith J Grant

The point of CSS is to make it so you don’t have to worry about them all.

– Keith J Grant

Define some constraints. Let the language work out the details.

– Keith J Grant

Provide hints that the browser may or may not use.

– Håkon Lie

Tina Turner as Aunty Entity
in the Mad Max Thunderdome,
with the law
'Two styles enter, one style leaves'
in bold text

every css property
on every html element
must have exactly one value

Cascade filters out
Inheritance fills in

An ordered list (cascade) of style sheets … can be referenced from the same document.

– Håkon Lie

The user/browser specifies initial preferences and hands the remaining influence over to the document.

– Håkon Lie

Cascade Origins

  • 🖥 User Agent (Browser)
  • 👥 User (Preferences)
  • 🎨 Author (Site)
/* browser styles */
body { margin: 8px; }

/* every designer */
body { margin: 0; }
  1. 🎨 Author (Site)
  2. 👥 User (Preferences)
  3. 🖥 User Agent (Browser)

If conflicts arise the user should have the last word, but one should also allow the author to attach style hints.

– Håkon Lie

  1. ❗🖥 User Agent Important
  2. ❗👥 User Important
  3. ❗🎨 Author Important
  4. 🎨 Author Styles
  5. 👥 User Preferences
  6. 🖥 User Agent Defaults

👎🏼 Override Styles

in the current origin

👍🏼 Protect Styles

from more powerful origins

Solitude painting from earlier
  1. ❗…
  2. ❗…
  3. ❗🎨 Author Important
  4. 🎨 Author Styles
  • * (universal)
  • type
  • .class & [attr]
  • #IDs (single-use)
  1. Unique #IDs
  2. Reusable .classes & [attributes]
  3. Element types
  4. Universal *
Same triangle flipped vertically,
with all the labels rotated
and numbered 1-7 from bottom to top
table[rules]:not([rules=""])> tr > td,
table[rules]:not([rules=""])> * > tr > td,
table[rules]:not([rules=""])> tr > th,
table[rules]:not([rules=""])> * > tr > th,
table[rules]:not([rules=""])> td,
table[rules]:not([rules=""])> th

{
border-width: thin;
border-style: none;
}
  1. Unique #IDs
  2. Reusable .classes & [attributes]
  3. Element types
  4. Universal *
.block .element.modifier { /* 3 */ }
.block__element--modifier { /* 1 */ }
.🤬-bootstrap {
font-weight: bold !important;
}
@layer generic {
audio[controls] { display: block; }
[hidden] { display: none !important; }
}
@import url(reset.css) layer(reset);

@layer generic {
audio[controls] { display: block; }
[hidden] { display: none !important; }
}
  1. Utilities
  2. Components
  3. Themes
  4. Frameworks
  5. Resets
  1. Overrides
  2. Components
  3. Objects
  4. Elements
  5. Generic
  6. Tools
  7. Settings
@layer settings {}
@layer tools {}
@layer generic {}
@layer elements {}
@layer objects {}
@layer components {}
@layer overrides {}
  1. @layer settings { … }
  2. @layer tools { … }
  3. @layer generic { … }
  4. @layer elements { … }
  5. @layer objects { … }
  6. @layer components { … }
  7. @layer overrides { … }
@layer framework {
#menu .dropdown .item:hover {
background: whitesmoke;
}

.menu-item {
background: lightcyan;
}
}
@layer framework {
#menu .dropdown .item:hover {
background: whitesmoke;
}
}

@layer override {
.menu-item {
background: lightcyan;
}
}
@layer generic {
audio[controls] { display: block; }
}

@layer generic {
[hidden] { display: none !important; }
}
@layer generic {
audio[controls] { display: block; }
[hidden] { display: none !important; }
}
@layer default {}
@layer theme {}

/* still a lower layer than "theme" styles */
@layer default {}
@layer generic, elements, objects, components, overrides;
/* establish layer order */
@layer one, two, three;

/* add code to layers as needed */
@import url(two.css) layer(two);
@layer three {}
@layer one {}
@layer two {}

Unlayered styles Default Highest Priority

@layer tools {
@layer custom {}
}

/* access nested layers */
@layer tools.custom {}
@layer components {
@layer defaults, structures, themes, utilities;
}
/* tools.css */
@layer theme {}
@layer components {}
@import url(tools.css) layer(tools);

@layer tools.theme {}
@layer tools.custom {}

❗️Important Layers Reverse

(exactly like origins)

  1. Important Resets
  2. Important Themes
  3. Important Components
  4. Components
  5. Themes
  6. Resets

if we need to… Layers -> Override
Importance -> Protect

@import url(bootstrap.css) layer(bootstrap);

@layer bootstrap.my-overrides {
/* anything here will override bootstrap */
}
.block .element.modifier { /* 3 */ }
.block__element--modifier { /* 1 */ }

1. Avoid Naming Conflicts

(across large teams & projects)

2. By Expressing Membership

(through lower boundaries & proximity)

.title { /* global */ }
.post .title { /* nested */ }

.post__title { /* BEM */ }
.post__title { /* BEM */ }
.title[data-JKGHJ] { /* Vue */ }
wireframe of a site, with multiple nested components
Diagram shows a widget with solid boundaries,
which cannot be penetrated
in either direction
(global styles can't get in, widget styles can't get out)

Build-tools Provide Scoped Styles

BEM, CSS Modules, Vue, JSX, Stylable, etc

@scope (.media) to (.content) {
img { /* only images that are "in scope" */ }
}
.light-theme a { color: purple; }
.dark-theme a { color: plum; }

Proximity >> Combinator??

.light-theme >> a { color: purple; }
.dark-theme >> a { color: plum; }

Scoped Selector Syntax??

@scope (.media) to (.content) {
img {}
}

(.media / .content) img {}

⚠️ Layout Loops?

CSS Context vs Content

2020 Proposals

  • David Baron: @container
    limited by containment
  • Brian Kardell: switch()
    limited to paint
.container {
contain: size layout style;
}

2D size containment Is Too Restrictive

Too Complicated

.sidebar, main, .grid-item {
contain: inline-size layout style;
}

More Declarative

.sidebar, main, .grid-item {
container-type: inline-size;
}
<div class="container">
<div class="container">
<div class="container">
We can nest containers!
</div>
</div>
</div>
@container (min-width: 40em) {
.card { /* ... */ }
h2 { /* ... */ }
}
.container { container-type: inline-size; }

@container (width > 30em) {
.container { padding: 2em; }
}
.sidebar {
container-type: inline-size;
container-name: sidebar;
}

@container sidebar (width > 30em) {
.container { padding: 2em; }
}

Finding Containers

  1. For each matched element
  2. Find the nearest ancestor that has…
    • Any required container types
    • Any required container name
@container (width > 30em) { /* CQ support */ }

@supports not (container-type: inline-size) {
@media (width > 40em) { /* no CQ support */ }
}

Container Query Units

cqw | cqh | cqi | cqb | cqmin | cqmax

@container style(--colors: invert) {}

Technical Ingredients…

  • Fluid grids (%)
  • Flexible images (%)
  • Media queries

Flexbox & (Sub)Grids &

min-/max-content, fit-content, minmax(), clamp(), etc…

  1. Fluid & Fixed
  2. Stages of Squishiness
  3. Truly Two-Dimensional Layouts
  4. Nested Contexts
  5. Expand & Contract Content
  6. Media Queries, As Needed

Our medium is not done. Our medium is still going through radical changes.

– Jen Simmons, Designing with Grid