Refrain from using ID selectors when creating styles.
Use the 'BEM' naming convention when writing CSS selectors:
// Block is the top level 'component'
.button { }
// Elements are within a block and use '__' to nest within the top-level block
.button__icon {}
// Modifiers use '--' to alter the block
.button--small {}
.button--medium {}
.button--large {}
In place of nested selectors (e.g. .tab .label {}
), create one selector with the block & element (e.g. .tab__label {}
). When a modifier is introduced, use nested selectors to modify sub-elements (e.g. .tab--small .tab__label { font-family: 0.5em; }
)
If you are relying on another style sheet that is outside your control (e.g. Bootstrap), you can prefix your styles with a 2-3 letter acronym for the project (e.g. .sig-<selector>
).
When designing your CSS, group common elements into components that can be re-used throughout the application. Consistency throughout an application will make it much easier to design, build, and use. If you are looking for ideas for what to name components, or how to break your application into components, check out these component libraries for inspiration:
Colors should be given a human-readable CSS variable name, preferably less than 10 characters. If multiple hues of color are needed, add a number with the number increasing as the color darkens.
For example:
:root {
--red: #FF0000;
--blue: #FF0000;
--bluegrey-1: #FAFAFA;
...
--bluegrey-10: #2B3238;
}
If a color pertains to a particular state (e.g. 'success' or 'error'), you can add a variable name for that particular state.
:root {
...
--success: #2B3238;
--error: #F51818;
}
Define font sizes in em
values by setting the default font size on the body
element. Provide font sizes using em
for the default textual elements, including: body
, h1
-h6
, p
, strong
, em
, and label
.
Create modifiers for different sizes using .font--<size> {}
(e.g. .font--small
, .font--xsmall
, .font--large
, .font--xlarge
).
If a particular font size is needed for a component, create a new style using the component's name as the block and .<block>__font
as the element (e.g. menu__font
). Alternatively, you can embed the font styling inside of the component's block-level CSS selector.
When creating styles for inputs, use the CSS selector format .input-<input-type>
(e.g. .input-checkbox
). States should use the modifier syntax (e.g. .input-checkbox--hover
).
Below is an example of the states for checkboxes:
.input-checkbox {}
.input-checkbox--hover {}
.input-checkbox--focus {}
.input-checkbox--checked {}
.input-checkbox--disabled {}
.input-checkbox--error {}
Radio buttons:
.input-radio {}
.input-radio--hover {}
.input-radio--focus {}
.input-radio--selected {}
.input-radio--disabled {}
.input-radio--error {}
Text Inputs:
.input-text {}
.input-text--hover {}
.input-text--focus {}
.input-text--disabled {}
.input-text--error {}
Many components require a state which shows it has been 'activated', or that a particular component is disabled. Use .<block>--active
or .<component>--disabled
to style these states accordingly.
Here are some example states:
.component--active {}
.component--disabled {}
.component--error {}
Icons should be exported as SVG's to avoid anti-aliasing on larger resolution devices.
Icons will typically be used as background images within a container. Start by defining the container and the size (e.g. .icon { height: 40px; width: 40px; }
), and then create a selector for particular icon (e.g. .icon-success { background:url('image/success.svg'); }
).
If an icon can be embedded within another component, create an element within the block with the correct dimensions (e.g. .card__icon {}
). This will allow you to set up the icon within the component like so:
<div class="card">
<div class="card__icon icon-success"></div>
<div class="card__title">Card Title</div>
<div class="card__content">Lorem ipsum dolor...</div>
</div>
If the icon is only one color, export it in white and modify it using the fill:
CSS attribute. Otherwise, export one SVG for each state that it must respond to using the filename: icon-<name>--<state>.svg
.
For example, if an SVG needs to change color on hover, you can use: .icon-success--hover { fill: #FF0000; }
Naming is the hardest part of programming. The name of a component should be succinct and self-descriptive.
If possible, avoid using the words 'Component', 'Module', or 'Modal' in the name of your component to make it easier to distinguish.
Here are some common names for components (and their nested components) that can be used to describe your interface:
-
Layout
- Container (
.container
) - Page (
.page
) - Sheet (
.sheet
) - Section (
.section
)
- Container (
-
Navigation
- Accordion (
.accordion
)- Item (
.accordion__item
)
- Item (
- Brand (
.brand
) - Breadcrumb (
.breadcrumb
)- Crumb (
.breadcrumb__crumb
)
- Crumb (
- Button Group (
.button-group
)- Button (
.button-group__button
)
- Button (
- Menu (
.menu
)- Link (
.menu__link
)
- Link (
- Tab Group (
.tab-group
)- Tab (
.tab-group__tab
) - Panel (
.tab-group__panel
)
- Tab (
- Wizard (
.wizard
)- Step (
.wizard__step
)
- Step (
- Accordion (
-
Feedback
- Alert (
.alert
) - Banner (
.banner
) - Popover (
.popover
) - Modal (
.modal
) - Loader (
.loader
) - Toast (
.toast
)
- Alert (
-
Data Display
- Chip (
.chip
) - Grid (
.grid
) - Table (
.table
) - Figure (
.figure
) - List (
.list
) - Card (
.card
) - Divider (
.divider
)
- Chip (
-
Inputs
- Dropdown (
.input-dropdown
)- Option (
.input-dropdown__option
)
- Option (
- Checkbox (
.input-checkbox
) - Radio Button (
.input-radio
) - Slider (
.input-slider
) - Text Input (
.input-text
) - Toggle (
.input-toggle
) - Search (
.input-search
)- Suggestion (
.input-search__suggestion
) - Result (
.input-search__result
)
- Suggestion (
- Dropdown (