I think they are all pretty neat and I see the point, but I’m a bunch of years into this and still generally… – Chris Coyier, @chriscoyier
Once you become experienced, you can break the rules in creative ways. – Eric Meyer, Structural Naming (2004)
We often hear “Are you using OOCSS or BEM?” but these things are not mutually exclusive. In fact, most of the time, we’re… mixing them up, customizing them to suit our own needs. – Una Kravets, Atomic OOBEMITSCSS
WWW parsers should ignore tags which they do not understand, and ignore attributes which they do not understand of tags which they do understand. – WWW Project
Link States a:link {color: blue;} /* specificity = 1,1 */a:visited {color: purple;} /* specificity = 1,1 */a:hover {color: magenta;} /* specificity = 1,1 */a:active {color: red;} /* specificity = 1,1 */
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
<figure class="media"> <img class="fixedMedia" src="myImg.png" /> <figcaption class="text">...</figcaption></figure>
<article class="media"> <img class="fixedMedia" src="myImg.png" /> <header class="text">...</header></article>
<div class="media media_reverse"> <img class="fixedMedia" src="myImg.png" /> <div class="text">...</div></div>
Organized on Category Base (element type) Layout (use #id) Module (use .classes) State (use !important) Theme (i.e. “skin”)
Layout Styles #article { float: left; }.l-flipped #article { float: right; }.l-fixed #article { width: 600px; }
/* 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; }
NameSpaces Components » .c-<name> Objects » .o-<name> Utilities » .u-<name> States » .is-<name>/.has-<name> Media » .<name>@<media>
<div class="o-media@md c-user c-user--premium"> <img src="" alt="" class="o-media__img@md c-user__photo c-avatar" /> <p class="o-media__body@md c-user__bio">...</p></div>
<a am-Button>Normal button</a><a am-Button='large'>Large button</a><a am-Button='rounded'>Rounded button</a><a am-Button='large rounded'>Large rounded button</a>
[data-attr] ➡ Presence (even if empty) [data-attr="..."] ➡ Exact match [data-attr*="..."] ➡ Any match [data-attr~="..."] ➡ Space-delimited (like classes) [data-attr|="..."] ➡ Hyphen-delimited [data-attr^="..."] ➡ Starts with… [data-attr$="..."] ➡ Ends with… [data-attr="..." i|s] ➡ Case sensativity
<article-component data-scope='article'> <h2 data-scope='article'>...</h2> <sub-component data-scope='article' data-scope='sub'> <!-- internals of sub only have scope='sub' --> </sub-component> <footer data-scope='article'>...</footer></article-component>
<article data-scope="article instance-id"> h2[data-scope~=article] { /* all instances */}h2[data-scope~=instance-id] { /* unique instance */}
Emotion render( <button css={css` padding: 32px; background-color: hotpink; font-size: 24px; border-radius: 4px; &:hover { color: ${color}; } `} >...</button>)
Tailwind CSS <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>
.btn { @apply font-bold py-2 px-4 rounded; } .btn-blue { @apply bg-blue-500 text-white; } .btn-blue:hover { @apply bg-blue-600; }
When you… reduce the amount of time you spend writing and editing CSS… you must instead spend more time changing HTML classes… – Nicolas Gallagher
.bg-primary { background: #ff00ff; }.bg-secondary { background: #ffbf81; }.color-primary { color: #ff00ff; }.color-secondary { color: #ffbf81; }
Class Grouping <article class="[ card ] [ section box ] [ bg-base color-primary ]" data-state="reversed"></article>
<style>/* keep this before linked styles */@layer defaults, components, utilities;</style><link rel="stylesheet" href="…">
@import url(bootstrap.css) layer(bootstrap.vendor);@layer bootstrap.overrides { /* anything here will override bootstrap */}
/* Vue example */<template>…</template><script>…</script><style>@layer components { /* all our component styles */}</style>
a:link,a:visited { color: var(--theme-link, var(--link-focus, var(--global-link)));}a:hover,a:focus,a:active { --link-focus: var(--theme-focus, var(--global-focus));}
[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);}
@layer reset { *, ::before, ::after { box-sizing: border-box; } html { line-sizing: normal; } body { margin: 0; }}@layer base { }@layer components { }@layer utilities { }
CSS is unlike anything else… designed for the realities of a flexible, multilingual, multi-device web. – Rachel Andrew