…This implies no device-specific markup, or anything which requires control over fonts or colors. – WWW Project, HTML constraints
h1, h2, h3, h4 /* etc */ { font-weight: bold; font-size: something big I dunno; } p { margin-block: 1em; } a:link { color: blue; text-decoration: underline; }
The web would have become a giant fax machine where pictures of text would be passed along. – Håkon Lie, 2014 interview
💥🙈⁉️💥 <button style="color: teal" type="submit">…</button> button { color: violet; } [type=submit] { color: vibrant; }
🖥 User Agent Defaults 👥 User Preferences 🎨 Author Styles ❗🎨 Author Important ❗👥 User Important ❗🖥 User Agent Important
Layers of Abstraction #banner { /* single element */ } .warning { /* class of elements */ } p, li { /* type of element */ } * { /* all of the elements */ }
@layer default { /* least powerful */ } @layer theme { /* … */ } @layer components { /* more powerful */ } /* unlayered styles: most powerful */
See the Pen Layers live code by @miriamsuzanne on CodePen. specificity & order add one layer add second layer re-order layers duplicate layer add layer list add nested layer inspect with dev tools
Establish A Layer Order /* first & easy to find */ @layer reset, design-system, components, utilities;
<style>/* keep this before linked styles */ @layer reset, design-system, components, utilities; </style> <link rel="stylesheet" href="…">
<style> @layer reset, defaults, theme, components, utilities; @import url(reset.css) layer(reset); @import url(defaults.css) layer(defaults); @import url(theme.css) layer(theme); @import url(components.css) layer(components); @import url(utilities.css) layer(utilities); </style>
@import url(bootstrap.css) layer(bootstrap.core); @layer bootstrap.overrides { /* anything here will override bootstrap */ }
/* Vue example */ <template>…</template> <script>…</script> <style> @layer components { /* all our component styles */ } </style>
The best selectors Don’t Need Naming Conventions .form–-submit__invalid { /* ❌ */ } form:has(:invalid) button[type=submit] { /* ✅ */ }
Bonus… Less Naming Things .form–-submit__invalid { /* ❌ */ } form:has(:invalid) button[type=submit] { /* ✅ */ }
Bonus… Encourage Proper HTML .form–-submit__invalid { /* ❌ */ } form:has(:invalid) button[type=submit] { /* ✅ */ }
@layer Resets @layer Themes @layer Components ❗important Components ❗important Themes ❗important Resets
Designing With Code Writing resilient and maintainable CSS oddbird.dev/learn/courses/design-with-code/