# CSS Style Guide
## Concepts
### Think in terms of components
Think in terms of everything as a component: a button, a footer with buttons in
it, a list, a list item, the container around the list, the list title, etc.
Keep components as granular as possible.
Compose large, complex components out of smaller, simpler components.
### Introduce as little specificity as possible
Rules will need to overwrite other rules, and we can only do that via
specificity. For that reason, it's important to avoid introducing specificity
unless absolutely needed and that when we do so, we introduce as little as
possible.
## Quick reference
Here are some examples of how to structure your styles. The
rules that underly these examples are below.
```less
.localNavButton {
padding: 5px;
border: 1px solid black;
/**
* 1. This button can appear in a "pressed" aka "pinned" state.
*/
&.localNavButton-is-pressed {
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2); /* 1 */
}
}
/**
* 1. Center icon and text vertically.
*/
.localNavButton__icon,
.localNavButton__text {
display: inline-block; /* 1 */
vertical-align: middle; /* 1 */
}
.localNavButton__icon {
color: gray;
opacity: 0.5;
}
.localNavButton__text {
color: black;
}
.localNavButton--primary {
border-color: blue;
// Introduce specificity to color the descendant component.
.localNavButton__icon,
.localNavButton__text {
color: blue;
}
}
```
```html
```
## Rules
### Use uniquely-named "base classes" to represent components
This component will be represented in the styles as a **base class**:
```less
// We can use a namespace like "kb" to make sure we don't affect
// other styles accidentally, especially when we're using a generic
// name like "button".
.localNavButton {
background-color: gray;
color: black;
border-radius: 4px;
padding: 4px;
}
```
### Create "descendant classes" to represent child components which can't stand on their own
In this example, the text and the icon are very tightly coupled to the button
component. They aren't supposed to be used outside of this component. So we
can indicate this parent-child relationship with a double-underscore and by
indenting the **descendant classes**.
```less
.localNavButton {
/* ... */
}
.localNavButton__icon {
display: inline-block;
vertical-align: middle;
}
.localNavButton__text {
display: inline-block;
vertical-align: middle;
font-weight: 300;
}
```
```html
```
### Think of deeply-nested child components as "subcomponents" instead of descendants
Some components can have subcomponents that have their own subcomponents, and so on.
In this kind of situation, using the descendant class rule above, would get
pretty hairy. Consider a table component:
```less
// ======================== Bad! ========================
// These styles are complex and the multiple double-underscores increases noise
// without providing much useful information.
.kbTable {
/* ... */
}
.kbTable__body {
/* ... */
}
.kbTable__body__row {
/* ... */
}
.kbTable__body__row__cell {
/* ... */
}
```
In this situation, it's better to create separate subcomponent base classes
in their own files. It's important to still name the classes in a way that
indicates their relationship, by incorporating the name of the root base class.
```less
// kbTable.less
.kbTable {
/* ... */
}
```
```less
// kbTableBody.less
.kbTableBody {
/* ... */
}
```
```less
// kbTableRow.less
.kbTableRow {
/* ... */
}
.kbTableRow__cell {
/* ... */
}
```
This is an example of how we can use files and class names to scale a component
as it grows in complexity.
### Represent states with "state classes"
If a user interacts with a component, or a change in application state needs to
be surfaced in the UI, then create **state classes**. These classes will be applied
to components in response to these changes.
Notice that all states contain a boolean keyword, typically "is".
```less
.localNavButton {
/* ... */
/**
* 1. This button can appear in a "pressed" aka "pinned" state.
*/
&.localNavButton-is-pressed {
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2); /* 1 */
}
}
```
### Variations on a component are represented with "modifier classes"
If the UI calls for a component to change along a single axis of semantic
meaning, create modifier classes. **Modifier classes** are different than states,
in that they will not be applied to a component as a result of user interaction
or a change in application state.
```less
.localNavButton {
/* ... */
}
.localNavButton--primary {
color: white;
background-color: blue;
}
.localNavButton--danger {
color: white;
background-color: red;
}
```
```html