CSS
Cyclic Materials CSS Naming Conventions
Cyclic Materials CSS relies on structural class names and meaningful hyphens, i.e., not using hyphens merely to separate words. This helps to work around the current limits of applying CSS to the DOM, and to better communicate the relationships between classes.
The primary architectural division is between the patterns atom, molecule, and organism.
Table of Contents
- Components
- pattern
- ComponentName
- ComponentName--modifierName
- ComponentName_descendentName
- ComponentName.is-stateOfComponent
Components
The CSS responsible for component-specific styling.
Syntax: <pattern>-<ComponentName>[--modifierName|_descendentName]
This has several benefits when reading and writing HTML and CSS:
- it helps to distinguish between classes for the root of the component, descendent elements, and modifications,
- it keeps the specificity of selectors low, and
- it helps to decouple presentation semantics from document semantics.
Pattern
Components are prefixed with a pattern, which borrows from atomic design principles.
.atom-AutogrowTextarea { /* ... */ }
.molecule-Input { /* ... */ }
This makes it clear, when reading the HTML, which components are part of each pattern.
There are three distinct patterns:
Atoms
Atom components are a set of basic visual and non-visual utility components. They include components for working with layout, user input, selection and scaffolding apps. They include abstract components like color palettes, fonts, and animations.
Molecules
Molecule components are a set of visual components that implement Material Design. They are groups of components that function together as a unit.
Organisms
Organisms are groups of molecules (and atoms) joined together to form a distinct section of an interface. Organisms can consist of similar or disparate molecule types.
ComponentName
The component’s name is written in pascal case. Nothing else in HTML/CSS uses pascal case.
.molecule-InputCharCounter { /* ... */ }
<div class="molecule-InputCharCounter">
...
</div>
ComponentName--modifierName
A component modifier is a class that modifies the presentation of the base component in some form, e.g., for a certain configuration of the component. Modifier names are written in camel case and is separated from the component by two hyphens. A modifier class always extends the base class and inherits all base declarations, of which some may be overridden.
/* Core flex layout */
.atom-FlexLayout { /* ... */ }
/* Vertical flex layout */
.atom-FlexLayout--vertical { /* ... */ }
<div class="atom-Flexlayout--vertical">...</div>
ComponentName_descendentName
A component descendent is a class that is attached to the descendent node of a component. It’s responsible for applying presentation directly to the descendent on behalf of a particular component. Descendent names are written in camel case.
<div class="atom-AutogrowTextarea">
<div class="atom-AutogrowTextarea_mirrorText">...</div>
<div class="atom-AutogrowTextarea_container">
<textarea class="atom-AutogrowTextarea_textarea"></textarea>
</div>
</div>
ComponentName.is-stateOfComponent
is-stateOfComponent
is used to reflect changes to a component’s state.
The state name is camel case. These classes are never styled directly;
they should be and are always used as an adjoining class.
This means that the same state names are used in multiple contexts, but every component defines its own styles for the state, as they are scoped to the component.
.molecule-InputContainer { /* ... */ }
.molecule-InputContainer.is-Highlighted { /* ... */ }
<div class="molecule-InputContainer is-Highlighted">
...
</div>