Modular Code
1. Frontend build
- Modular CSS is a way of organising your CSS, and other assets, into discrete and re‑usable chunks.
- The individual chunks are concatenated and optimised.
- Indiego uses Gulp, an npm JavaScript taskrunner.
2. Code Organisation
The code organisation is based on Inverted Triangle CSS by Harry Roberts, from the most applicable styles (variables, base) to specific modules (objects and components) and to very specific trumping utilities and shameful hacks.
- Variables: global variables and site-wide settings eg
responsive.css
- Base: unclassed HTML elements eg
a {}
- Objects: cosmetic-free objects, abstractions, and design patterns eg
o-media.css
- Components: discrete, complete chunks of UI eg
button.css
- Utilities: high-specificity, very explicit selectors that trump
everything else. Overrides and helper classes eg
.u-hiddenvisually {}
- Shame: temporarily disorganised CSS lives in
shame.css
All files relating to a particular module go in that module folder: eg JavaScript, PNGs, JPEGs, SVGs, CSS, template snippet for styleguide etc.
Simplified directory structure
src
├── css
│ ├── settings
│ └── shame.css
├── img
├── js
└── modules
├── components
│ └── forms
| └── button
├── objects
└── utilities
3. CSS Syntax
Modified BEM syntax
In short:
.block__element--modifier {}
This is a modified BEM syntax from @CSSWizardry
.block {}
.block__element {}
.block--modifier {}
The block
is the module (object or component), the block__element
is a descendant of that module and the block--modifier
is a variation on that module.
For example:
.search {}
.search__field {}
.search--full {}
BEM ground rules
- Hyphen to separate words in long names & two underscores to separate the name of the block from the name of the element:
block-name__element-name
- CSS class for a block coincides with its block name
- A modifier is a property of a block or an element that alters its look or behavior.
- A modifier has a name and a value. Several modifiers can be used at once.
- Double dash to separate name of block/element from name of modifier:
menu menu--big
Namespacing
To add clarity to the block__element--modifier
convention, use “namespacing”: prefixing a module with an identifying character:
.o-object {}
.component {}
.u-utility {}
.js-javascript {}
._-hack {}
.is-state {}, has-state {}
For example, .button {}
, .o-media {}
, .u-cf
, _-messy-hack
. The odd one is out component – no c-
prefix here, because components are the most common type of module, and if it doesn’t have a prefix, it’ll be a component.
4. Principles of Modular Code
Why Modular Code?
- Each module is written as separate files in their own directory.
- Version control is much easier.
- Finding specific modules is simple.
- Building a style guide requires minimal setup.
Some key principles
Build what you need. Start simple. Stay simple.
- ID-based CSS selectors must not be used. IDs have a much higher specificity, which can then lead to all sorts of specifity wars when trying to apply a style.
- HTML elements must not be used in CSS selectors. This means classes can be applied to any element eg
<input class="button" type="submit">
and<button class="button">pushme</button>
. - Only use the module for one bit of functionality. This is the Single Responsibility Principle.
- Class names should be functional & independent of content. Again, this makes a module re-usable in different contexts.
- Modules must have unique names.
Visibility
A guiding principle in Kanban development is to make work visible (Kanban 看板 literally means billboard in Japanese). To this end, use a styleguide, from the beginning. Indiego recommends Fractal, a magnificent, automated, styleguide builder.
Credits & further reading
- MindBEMding – getting your head ’round BEM syntax by Harry Roberts
- More transparent UI code with namespaces by Harry Roberts
- About HTML semantics and front-end architecture by Nicolas Gallagher
- SUIT CSS naming conventions by Nicolas Gallagher
- SUIT CSS documentation by Nicolas Gallagher
- SUIT CSS utilities by Nicolas Gallagher
- Scalable and Modular Architecture for CSS by Jonathan Snook
- BEM Methodology (Block Element Modifier) by Yandex
- BEM Resources (awesome) by Stu Robson