slides.oddbird.net/layers/oddtreat22/

Cascading Layers of !mportance

@ OddBird Retreat (lightning)
<button style='color: blue'></button>
button { color: violet; }

💥🙈⁉️💥

<button style='color: blue'></button>
button { color: violet; }

Multiple or Unknown ⁉️

color: teal;
color: violet;
color: oklch(79.269% 0.171 70.67);

On every html element,
For every css property
We need exactly one value

Cascade filters out
Inheritance fills in

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

– Håkon Lie

Cascade 🗺 Origins

  1. 🖥 User Agent (browser)
  2. 👥 User
  3. 🎨 Author (document/us)

Cascade 🗺 Origins

  1. 🖥 User Agent (goes first)
  2. 👥 User
  3. 🎨 Author (most power)

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 Defaults (goes first)
  2. 👥 User Preferences
  3. 🎨 Author Styles
  4. ❗🎨 Author Important
  5. ❗👥 User Important
  6. ❗🖥 User Agent Important (most power)

👎🏼 Override Styles

in the current layer

👍🏼 Protect Styles

from more powerful layers

Often Isolated

  1. 🎨 Author Styles
  2. ❗🎨 Author Important
  3. ❗…
  4. ❗…
  • * (universal)
  • type
  • .class & [attr]
  • #IDs (single-use)
  1. Universal *
  2. Element types
  3. Reusable .classes & [attributes]
  4. Unique #IDs (most powerful)
@layer generic {
audio[controls] { display: block; }
}

@layer generic {
[hidden] { display: none !important; }
}
@layer generic {
audio[controls] { display: block; }
[hidden] { display: none !important; }
}
  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 {}
@layer framework {
#menu .dropdown .menu-item {
background: whitesmoke;
}
}

@layer override {
.menu-item {
background: lightcyan;
}
}
@layer default {}
@layer theme {}

/* still a lower layer than "theme" styles */
@layer default {}

Establish layer Order

@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 {}
@import url(framework.css) layer(framework.base);

@layer framework.overrides {
/* anything here will override framework.base */
}

❗️Important Layers Reverse

(exactly like origins)

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

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

Already Sorting Layers

  • tools (Sass, no output)
  • config (Sass, no output)
  • reset
  • initial
  • patterns
  • layout
  • components (Sometimes SFC)
  • utilities (eg .visually-hidden)
/* first styles in the document */
@layer reset, initial, patterns, layout, components, utilities;

Wrap Components

<template></template>
<script></script>
<style lang='scss'>
@layer components {
/* all our component styles */
}
</style>

Can’t Layer @use

@use 'patterns' layer(patterns);
@layer
{ @use 'patterns'; }
/* '_patterns.scss' */

@layer patterns {
/* all our css is nested */
}
/* 'screen.scss' */
@use 'sass:meta';

@layer patterns
{
@include meta.load-css('patterns');
}
/* '_patterns.scss' */

@mixin css {
/* all our css is nested */
}
/* 'screen.scss' */
@use 'patterns';

@layer patterns
{
@include patterns.css();
}

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

Fine to Use Meaningful Selectors

Like #ids and nesting

Also Can use :where()

To lower specificity in some cases