CSS Naming Conventions (based on BEM for React)
A "Quick" explanation for css naming:
Given this example HTML:
<button class="Button Button___primary">
<i class="Icon Icon___small Button_leftIcon"/>
<span class="Button_label">Click Me!</span>
<i class="Icon Icon___small Button_rightIcon"/>
</button>
A component has three naming considerations as follows:
The component itself representing the Block in BEM
The components child elements representing the Element in BEM
The components modifiers representing the Modifier in BEM
Blocks:
There are technically 3 Blocks above – the outer button and the two inner icons. The icons are Blocks as they are also components that are imported into the button component. So, the Block class names are:
.Button
for the Button component.Icon
for the Icon components
Block names use UpperCamelCase (also known as PascalCase).
Generally speaking, Block classes are used to visually style the component and its child elements and not define any placement styles within its parent container.
Block class names should match the React component name.
Elements:
There are 3 Elements above – the two icon Elements and the span tag containing the button's text. While the icons are components and therefore are Blocks in their own right, they are also Elements from the buttons perspective, so they receive Element class names as well:
.Button_leftIcon
.Button_label
.Button_rightIcon
Element names start with the Block name and add the Element name using lowerCamelCase (also know as just camelCase) separated by a single underscore. Element class names are only really necessary if you need to modify the Element's styles in the context of the parent Block.
Elements within a parent block that are components should be styled from the Blocks perspective using the Element class name (i.e. .Button_leftIcon
) and not the Element's component name (i.e..Icon
).
Generally speaking, Element classes are used to position the element within the Block and not strictly to apply visual styling. Though visual styling can be applied if it doesn't make sense to support the needed styling within a child component's default styles or if the Element doesn't necessarily warrant the creation of a separate component.
Modifiers:
The overall button and the two icons above have modifiers applied:
.Button___primary
on the button to override the generic button with primary styling.Icon___small
on the two icons to override the generic icon size to make them small iconsNote that this modifier name is from the perspective of the icon and not specifically the button because the icon already supports the size the button needs. If you needed an icon size within the button that the icon didn't already support and doesn't make sense to add to the icon component directly, you could use an element modifier class name like
.Button_rightIcon___superExtraSmall
. This approach should be used sparingly though!
Modifier names start with the Block name and add the Modifier name using lowerCamelCase (also know as just camelCase) separated by three underscores to help visually distinguish them from Element names that use a single underscore.
Modifiers can also be used for component state changes like .Button___toggled
when a button is toggled to apply different visual styling when that state is triggered. That said, HTML attributes can also be used for consistency to indicate state changes as some html elements already have state attributes. Eg. [disabled]
or [data-toggled="true"]
or ...