Scalable and Modular Architecture for CSS

Cover of the book Scalable and Modular Architecture for CSS (SMACSS) by Jonathan Snook

SMACSS by Jonathan Snook is referenced in numerous articles about on CSS and so I finally decided to read it. I can see now how the ideas in this book would have served as a seed for conventions like ITCSS and BEM.

Structured and organized CSS is easier to build on and maintain. Naming conventions improve clarity. Independence from HTML structure means that components can be moved around freely. A balance between class name only selectors, and nested selectors is key for maintainable CSS. Overall our goal should be to increase semantics and decrease reliance on specific HTML structure.

SMACSS attempts to achieve this by creating categories of elements and by creating some conventions on how to split and write your CSS. The author makes it clear that these are just guidelines and need to change as per the project and its realities.

Continue reading “Scalable and Modular Architecture for CSS”

πŸ”– ABEM: A more useful adaptation ofΒ BEM (archive)

ABEM brings BEM and Atomic Design together by adding some variations to the BEM convention:

  • Prefix blocks with a-, m- or o- to signify its level.
  • Allow block names to be camelCase, changing .o-subscribe-form__field-item to .o-subscribeForm__fieldItem. This makes grouping of the class names easier and our brains can parse the shapes faster.
  • Use selectors that have multiple classes, especially for modifiers.
  • Modifier classes should have a - prefix.

For example:

.m-signUpForm--isOpen { display: block }
/* ... would become... */
.m-signUpForm.-isOpen { display: block }

This makes the HTML easier to read too:

<section class="m-signUpForm m-signUpForm--isOpen"></section>
<!-- ...would become... -->
<section class="m-signUpForm -isOpen"></section>

Applying modifiers like this has its drawbacks since it applies to all child elements too. The article goes into detail on how to resolve this.

πŸ”– BEMIT: Taking the BEM Naming Convention a Step Further (archive)

BEM only tells us about how classes relate to each other. They don’t provide an insight into the global non-relative meaning of the class. This is where namespaces based on ITCSS help.

Namespaces like o- for objects and c- for components should be added as a prefix to the normal BEM classes. Now by looking at class names β€” like o-card and c-user__photo β€” we are able to reason about its scope, where else we can use it, and how we can reuse or modify it.

Responsive classes should be added as suffixes with with an @. For example – u-hidden@print or o-layout@md. The @ symbol needs to be escaped in the CSS like so .u-hidden\@print.

πŸ”– MindBEMding – getting your head ’round BEM syntax (archive)

BEM class names are meant to be descriptive of their place, relationships and states.

.person {}
.person__hand {}
.person--female {}
.person--female__hand {}
.person__hand--left {}

In the above example it is important to note the order of --modifiers and __elements:

  • A person has an element hand with the modifier for which side.
  • A person has a modifier for gender that has the element hand.

Good BEM naming requires us to understand which category something falls into. Just because a something lives inside a block doesn’t always mean that it is an element. It could be a block in its own right. For example, something like a site logo on the header could be .header__logo, but if you are going to reuse the logo in the footer too you could separate it out into its own block .site-logo.

πŸ”– More Transparent UI Code with Namespace (archive)

CSS code should be transparent and self-documenting. Naming conventions like BEM help us see how components and its elements relate to each other. Namespaces give us a more global sense of the classes, in a non-relative way. Using namespaces gives us:

  • Clarity of what a class does and its scope
  • Confidence to know what changes will have side effects

These are the suggested namespaces:

  • o- for objects that are used a wide variety of contexts
  • c- for components which are a distinct part of the design
  • u- for utilities that are often used along side other classes
  • t- for themes (if your app has them)
  • s- for scopes that contain content coming from elsewhere (like a CMS)
  • is- or has- for states
  • _ for ugly hacks
  • js- for any DOM that has a JavaScript behavior on it
  • qa- for running automated tests or other test engineering requirements

πŸ”– Font sizing with rem (archive)

Defining font sizes in px gives you control but it prevents the user from increasing the font size on some browsers (till IE9). em is more accessible and allows for resizing, but since the unit is relative to the font size of its parent it has a compounding effect which is hard to manage.

The rem unit is relative only to the root html element’s font size. By setting the html‘s font size to 62.5% you can use rems almost like px, in that 1.4rem would be 14px (because 62.5 Γ— 1.6 = 100, 16px being the usual browser default text size)

πŸ”– The Comprehensive 8pt Grid Guide (archive)

The system uses points not pixels because the pixel density of devices wary and we want to keep our designs consistent across different densities. iPhones for example could be rendering 2x or 3x the number of pixels. So, we design for the smallest size, and get perfect rendering by multiplying by 2 or 3.

Font sizes may stray from multiples of 8 but the line heights shouldn’t so as to maintain vertical rhythm. For example, a font size of 12px is acceptable as long as the line height is 16px.

Should be constructed in the 8pt grid and exported for higher density screens.

For the horizontal layout, customize your column grid library or settings to make sure the gutters are a multiple of 8. Setup variables to use later when setting dimensions, margin and padding:

:root {
  --small-space: 8px;
  --medium-space: 16px;
  --large-space: 24px;
  --x-large-space: 32px
  /* and so on */

ITCSS is a way of planning and structuring CSS for large and long-running project.

Selectors move from generic to specific, this means lower specificity selectors (those that affect a lot of DOM) appear towards the top, and the specificity increases as the project progresses. Ordering things this way takes advantage of the way CSS actually works.

ITCSS defines seven layers:

ITCSS structure

Settings: Global project settings like font sizes and color palettes.

Tools: Globally used mixins and functions.

Generic: Things like CSS resets and box-sizing rules.

Elements: Bare, unclassed HTML elements. Should bind directly to tags (h1 {}).

Objects: Layout systems and containers.

Components: Recognizable pieces of the UI. Should bind to classes only (.post-title {}).

Trumps: Inelegant and heavy-handed helper classes, hacks and overrides.

The CSS files should be broken down and kept as granular as possible. The recommended naming convention is _<layer>.<partial>.scss (for example: _settings.colors.scss, _elements.headings.scss, _components.tabs.scss). These can then be imported in the above order in the final stylesheet.

πŸ”– Manage large CSS projects with ITCSS

OOCSS is a way to create stylesheets that are reusable, scalable and easier to maintain. It has two main principles:

Skin & Structure: Structure is how things are laid out, and skin is the styling. These should be separated.

Container & Content: Content refers to images and paragraphs, and containers are the divs in which content lives. Containers should have their own classes, and the contents should not be scoped to their containers.

πŸ”– OOCSS – The Future of Writing CSS

BEM is a CSS naming convention where everything is a class and nothing is nested.

Block is a top level abstraction of a component.

.btn {}

Elements inside the block are denoted by two underscores. These shouldn’t exist outside of blocks.

.btn__price {}
.btn__text {}

Modifiers manipulate the block to add states, themes and styles. This is denoted by two dashes.

.btn--orange {}
.btn--big {}

While this makes the markup a bit verbose you get the advantage of understanding the CSS and component structure by looking at the HTML:

<a class="btn btn--big btn--orange" href="https://css-tricks.com">
  <span class="btn__price">$9.99</span>
  <span class="btn__text">Subscribe</span>

πŸ”– BEM 101 | CSS Tricks