This style guide aims to provide the ground rules for CFPB's CSS, such that it's highly readable and consistent across different developers on a team.
- Use soft-tabs with a four-space indent
- One line per selector
- Always end property declarations with a semicolon
- Put spaces after
:
in property declarations - Put spaces before
{
in rule declarations - Place
{
on the same line as the (last) selector and}
on its own line
For example:
.btn,
.btn__big {
color: #000;
}
Declare properties in three groups:
- Display & box model
- Changing the current
display
orbox-sizing
values - Box model properties in order from inside-out
overflow
behavior
- Changing the current
- Positioning
- Changing the current
float
orposition
values - Position properties in typical CSS clockwise fashion (
top
,bottom
,left
,right
), followed byz-index
- Changing the current
- Everything else
- Alphabetical order
We recommend this ordering so that when you first look at a component's style declaration, you can quickly get a sense of how a component is sized and positioned, which affects the flow of the rest of the page, and then move on to the properties that only affect that component itself.
.selector {
/* Display & Box Model (mode switching, then box-model from inside out, then overflow handling) */
display: inline-block;
box-sizing: border-box;
width: 100px;
height: 100px;
padding: 10px;
border: 10px solid #333;
margin: 10px;
overflow: hidden;
/* Positioning (mode switching, then positioning counterclockwise from top, then z-index */
float: left;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 10;
/* Other (alphabetical) */
background: #000 url('../img/bg.png') no-repeat center top;
color: #fff;
cursor: pointer;
font-family: sans-serif;
font-size: 16px;
font-style: italic;
font-weight: bold;
line-height: 1;
list-style: none;
text-align: right;
}
N.B.: It is not necessary to include the group headings in your actual CSS, or to include a blank line between groups. The headings and blank lines are just for added clarity in this example.
Custom BEM ("Block Element Modifier") format:
.block-name
.block-name_element-name
.block-name__block-modifier
.block-name_element-name__element-modifier
Appending an element name to a modifier class can result in a confusing class name like .list__space_item
.
Avoid this in favor of using a descendant, like this: .list__spaced .list_item
.
While the id
attribute might be fine in HTML and JavaScript, it should be avoided entirely inside stylesheets for a few reasons:
- ID selectors are not reusable
- Can lead to priority issues
.ur-name {
// ...
}
#ur-name {
// ...
}
Just assign a class name to the element.
These rules apply to your CSS property values
- If the value of a property is
0
, do not specify units - The
!important
rule should be aggressively avoided.- Keep style rules in a sensible order
- Compose styles to dissipate the need for an
!important
rule - Fine to use in limited cases
- Overlays
- Declarations of the
display: none !important;
type
- Use hex color codes
#000
unless there's an explicit need for anrgba
declaration - Avoid mixing units
- Unit-less
line-height
is preferred because it does not inherit a percentage value of its parent element, but instead is based on a multiplier of thefont-size
.
.btn {
color: #222;
}
.btn-red {
color: #f00;
}
.btn-red {
color: #f00 !important;
}
.btn {
color: #222;
}
In most cases styles should be declared mobile first, then enhanced with min-width
media queries.
By doing this we create a base experience that all devices can use and one that does not require media query support.
At the CFPB we use Less as our CSS preprocessor.
- Organize your Less code into multiple files/modules
- Prefer nested selectors
.foo { .bar {} }
vs.foo .bar {}
- Only if both
.foo
and.foo .bar
need styling
- Only if both
- Don't nest selectors beyond 3 levels deep
Styles shouldn't need to be nested more than three levels deep. This includes pseudo-selectors. If you find yourself going further, think about re-organizing your rules (either the specificity needed, or the layout of the nesting).
- Colors: (use generic variable names like recent consumerfinance.gov update)
- Breakpoints: standard variable names for commonly used breakpoints
Use JSDocs style comments for comment blocks and //
for inline comments.
Comments aren't meant to explain what the code does. Good code is supposed to be self-explanatory. If you're thinking of writing a comment to explain what a piece of code does, chances are you need to change the code itself. Good comments are supposed to explain why code does something that may not seem to have a clear-cut purpose.
/**
* Default button styles
* @class .btn
* @elements a, button
*/
.btn {
display: inline-block;
&:focus {
background-color: @btn-bg-hover;
outline: 1px dotted @btn-bg;
// outline-offset is not supported everywhere but it adds a nice touch where it is
outline-offset: 1px;
}
}
Some of this document is based on Nicolas Bevacqua's fbc-style-guide, which is licensed under the MIT license.