Smashing Workshop
towards a cascade-aligned programming
workshops.oddbird.net/smashing24/conventions/
What are you trying? Are you happy with it?
(as a point of reference)
Your mileage will vary
Doesn’t mean we all need to
I think they are all pretty neat and I see the point…
— Chris Coyier, @chriscoyier
But I’m a bunch of years into this and still generally… write the selector I need and then style with that.
Conventions won’t save us
Conventions can develop over time
– Test potential solutions
pen.new
#header { … } #nav { … } #main { … } #footer { … }
header { … } nav { … } main { … } footer { … }
Building with accessible semantics from the get-go can give you expressive, meaningful style hooks for free.
— Ben Myers, Style with Stateful, Semantic Selectors
/* expressive semantics */ form:has(:invalid) [type="submit"] { … } /* some name we came up with? */ .form__btn--submit--invalid { … }
a[href*="://"] { /* external links */ } a[href^="https:"] { /* secure links */ } a[href$=".pdf"] { /* pdf links */ } button[aria-pressed=true] { /* pressed buttons */ } img:not([alt]) { /* images without alt text */ }
.flow > * + * { margin-top: var(--flow-space, 1em); }
@container (inline-size > 60ch) { … }
No “intervention by the author”
YUI, Blueprint, 960gs, etc…
<div class=" column col6of12 last " >
<div class="
column col6of12 last
" >
CSS frameworks decrease the maintainability of code.
— Natalie Downe, CSS Systems
(this was before RWD & Media Queries)
(which may provide sizing)
(the variable axis for blocks)
A CSS “object” is a repeating visual pattern, that can be abstracted into an independent snippet of HTML, CSS, and possibly JavaScript.
— Nicole Sullivan, OOCSS
Avoid even unique component styles
(Unique components, without unique CSS)
width
height
SMACSS, BEM, ITCSS, CUBE, etc…
Truly effective responsive design must begin with the content first.
— Jeremy Keith, Responsive Enhancement Workshop
Most of the work is already done for you with global and high-level styles.
— Andy Bell, CUBE CSS
Styles should be reusable…
/* .page header { … } */ .page__header { … }
header.masthead { … }
/* Runs the risk of becoming out of date; not very maintainable. */ .blue { color: blue; } /* Depends on location in order to be rendered properly. */ .header span { color: blue; } /* Too specific; limits our ability to reuse. */ .header-color { color: blue; } /* Nicely abstracted, very portable, doesn’t risk becoming out of date. */ .highlight-color { color: blue; }
From p {} through .text-center {}
p {}
.text-center {}
@layer settings { … } @layer tools { … } @layer generic { … } @layer elements { … } @layer objects { … } @layer components { … } @layer overrides { … }
.wrapper { margin-inline: auto; padding-inline: 1rem; max-width: 60rem; }
hidden { display: none !important; } visually-hidden:not(:focus-within) { clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; }
.bg-primary { background: #ff00ff; } .bg-secondary { background: #ffbf81; } [data-bg=primary] { background: #ff00ff; } [data-bg=secondary] { background: #ffbf81; }
[data-bg] { background: var(--canvas-color); } [data-bg=primary] { --canvas-color: #ff00ff; } [data-bg=secondary] { --canvas-color: #ffbf81; }
[data-layout] { display: grid; }
[style*='--canvas-color:'] { background: var(--canvas-color); }
(just, like, my opinion)
(not the issues I’m having)
.block { } .block--modifier { } .block__element { } .block__element--modifier { }
No .combined.selectors
.combined.selectors
@layer
Or custom properties, or :where(), or…
:where()
header button { /* inside-of */ } .header__button { /* belongs-to */ }
<style scoped>…</style>
@scope
render( <button css={css` padding: 32px; background-color: hotpink; font-size: 24px; border-radius: 4px; &:hover { color: ${color}; } `} >...</button> )
(otherwise ‘tools’ become obstacles)
Can it handle colors and lengths?
color
length
<button class="css-1h3ivcl">...</button>
<div class="Bgc(#0280ae.5) C(#fff) P(20px)">...</div>
<body class="bg-green black-70 pa4"> <h1 class="f1">...</h1> </body>
<div class="md:flex"> <div class="md:flex-shrink-0"> <img class="rounded-lg md:w-56" src="..." alt=""> </div> <div class="mt-4 md:mt-0 md:ml-6"> <div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">...</div> </div> </div>
¯\_
(ツ)
_/¯
When you… reduce the amount of time you spend writing and editing CSS… you must instead spend more time changing HTML classes…
— Nicolas Gallagher
.btn { @apply font-bold py-2 px-4 rounded; } .btn-blue { @apply bg-blue-500 text-white; } .btn-blue:hover { @apply bg-blue-600; }
Websites don’t need to cannot possibly look the same in every browser.
— The web, paraphrased
The fact we can control a paper page is really a limitation of that medium.
— John Allsopp, A Dao of Web Design
Be the browser’s mentor, not its micromanager.
— Andy Bell
Define some constraints. Let the language work out the details.
— Keith J Grant
CSS Systems, OOCSS, ITCSS, CUBE…
(even before @layer)
(We ❤ “intelligent” selectors)
[aria-hidden] & [hidden] & ??
[aria-hidden]
[hidden]
[aria-expanded] & [aria-pressed]
[aria-expanded]
[aria-pressed]
visually-hidden | etc.
visually-hidden
.warning { border-color: red; }
.warning
{ border-color: red; }
.bc-r { border-color: red; }
.bc-r
[data-theme] { background-color: var(--theme-bg, var(--global-bg, transparent)); color: var(--theme-color, var(--global-color, inherit)); }
[data-theme='light'] { --theme-bg: var(--neutral-light); --theme-color: var(--neutral-dark); --theme-link: var(--primary-dark); } [data-theme='dark'] { --theme-bg: var(--neutral-dark); --theme-color: var(--neutral-light); --theme-link: var(--primary-light); }
.is-success | .is-error ➡ [data-msg="success | error"]
.is-success
.is-error
[data-msg="success
|
error"]
To guide our conventions
CSS is unlike anything else… designed for the realities of a flexible, multilingual, multi-device web.
— Rachel Andrew
Navigate slides using the arrow-keys.