Bootstrap CSS Coding Standards
Syntax
Use two spaces instead of tabs for indentation — this is the only way to ensure consistent formatting across all environments.
When grouping selectors, place individual selectors on a new line.
For readability, add a space before the opening brace of declaration blocks.
The closing brace of a declaration block should be on its own line.
Insert a space after the colon of each declaration.
For more accurate error reporting, each declaration should be on its own line.
All declarations should end with a semicolon. The semicolon after the last declaration is optional, but omitting it might lead to errors in your code.
For properties with comma-separated values, insert a space after each comma (e.g.,
box-shadow
).Do not insert spaces after commas within
rgb()
,rgba()
,hsl()
,hsla()
, orrect()
values. This helps distinguish between multiple color values (comma only) and multiple attribute values (comma and space).For fractional values less than 1, omit the leading zero (e.g., use
.5
instead of0.5
;-.5px
instead of-0.5px
).Hexadecimal values should be in lowercase, such as
#fff
. Lowercase characters are easier to distinguish when scanning the document.Use shorthand hexadecimal values where possible, such as
#fff
instead of#ffffff
.Quote attributes in selectors, e.g.,
input[type="text"]
. Although optional in some cases, it is recommended for consistency.Omit units for zero values, e.g., use
margin: 0;
instead ofmargin: 0px;
.
For questions about the terminology used here, refer to the Cascading Style Sheets - Syntax on Wikipedia.
/* Bad CSS */
.selector, .selector-secondary, .selector[type=text] {
padding:15px;
margin:0px 0px 15px;
background-color:rgba(0, 0, 0, 0.5);
box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
}
/* Good CSS */
.selector,
.selector-secondary,
.selector[type="text"] {
padding: 15px;
margin-bottom: 15px;
background-color: rgba(0,0,0,.5);
box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}
Declaration Order
Related property declarations should be grouped together and arranged in the following order:
Positioning
Box model
Typographic
Visual
Positioning comes first because it can remove elements from the normal document flow and override box model styles. The box model comes next as it determines the size and position of the component.
Other properties only affect the component's internal or do not impact the first two groups, so they come last.
For a complete list of properties and their order, refer to Recess.
.declaration-order {
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box-model */
display: block;
float: right;
width: 100px;
height: 100px;
/* Typography */
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
color: #333;
text-align: center;
/* Visual */
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
border-radius: 3px;
/* Misc */
opacity: 1;
}
Avoid Using @import
Compared to the <link>
tag, the @import
directive is much slower, not only increasing the number of additional requests but also causing unpredictable issues. Here are some alternative methods:
- Use multiple
<link>
elements - Compile multiple CSS files into one using CSS preprocessors like Sass or Less
- Use systems like Rails or Jekyll that provide CSS file merging functionality
For more information, please refer to Steve Souders' article.
<!-- Use link elements -->
<link rel="stylesheet" href="core.css">
<!-- Avoid @imports -->
<style>
@import url("more.css");
</style>
Position of Media Queries
Place media queries as close as possible to the relevant rules. Do not bundle them in a single style file or at the bottom of the document. If separated, they will be forgotten in the future. Here is a typical example:
.element { ... }
.element-avatar { ... }
.element-selected { ... }
@media (min-width: 480px) {
.element { ...}
.element-avatar { ... }
.element-selected { ... }
}
Prefixed Properties
When using vendor-prefixed properties, align the values vertically for easy multi-line editing.
In Textmate, use Text → Edit Each Line in Selection (⌃⌘A). In Sublime Text 2, use Selection → Add Previous Line (⌃⇧↑) and Selection → Add Next Line (⌃⇧↓).
/* Prefixed properties */
.selector {
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
box-shadow: 0 1px 2px rgba(0,0,0,.15);
}
Single-Line Rule Declarations
For styles with only one declaration, for readability and quick editing, place the statement on the same line. For styles with multiple declarations, separate each declaration onto its own line.
This is crucial for error detection—for example, a CSS validator points out a syntax error on line 183. If it's a single-line, single-declaration, you won't miss the error; if it's a single-line, multiple-declaration, you need to carefully analyze to avoid missing the error.
/* Single declarations on one line */
.span1 { width: 60px; }
.span2 { width: 140px; }
.span3 { width: 220px; }
/* Multiple declarations, one per line */
.sprite {
display: inline-block;
width: 16px;
height: 15px;
background-image: url(../img/sprite.png);
}
.icon { background-position: 0 0; }
.icon-home { background-position: 0 -20px; }
.icon-account { background-position: 0 -40px; }
Shorthand Property Declarations
Limit the use of shorthand property declarations when explicit setting of all values is necessary. Commonly overused shorthand properties include:
padding
margin
font
background
border
border-radius
Most of the time, we do not need to specify all values for shorthand property declarations. For example, HTML heading elements only need to set top and bottom margin values, so only override these two values when necessary. Overusing shorthand property declarations can lead to code confusion and unintended side effects due to unnecessary value overrides. This is a very useful article on shorthand properties from the MDN (Mozilla Developer Network) for users who are not very familiar with shorthand property declarations and their behavior.
/* Bad example */
.element {
margin: 0 0 10px;
background: red;
background: url("image.jpg");
border-radius: 3px 3px 0 0;
}
/* Good example */
.element {
margin-bottom: 10px;
background-color: red;
background-image: url("image.jpg");
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
Nesting in Less and Sass
Avoid unnecessary nesting. Just because you can nest, it doesn't mean you should. Use nesting only when it is necessary to scope styles to a parent element (i.e., descendant selectors) and when there are multiple elements that need to be nested.
// Without nesting
.table > thead > tr > th { … }
.table > thead > tr > td { … }
// With nesting
.table > thead > tr {
> th { … }
> td { … }
}
Comments
Code is written and maintained by people. Make sure your code is descriptive, well commented, and approachable by others. Good comments convey context and purpose. Don't reiterate a component or class name.
For longer comments, write full sentences; for general notes, concise phrases will do.
/* Bad example */
/* Modal header */
.modal-header {
...
}
/* Good example */
/* Wrapping element for .modal-title and .modal-close */
.modal-header {
...
}
Class Naming
Class names should only use lowercase characters and dashes (not underscores, nor camelCase). Dashes should be used for related class naming (similar to namespaces) (e.g.,
.btn
and.btn-danger
).Avoid overly arbitrary shorthand.
.btn
stands for button, but.s
doesn't mean anything.Class names should be as short as possible but as long as necessary.
Use meaningful names. Use names that are structured or purposeful, not presentational.
Prefix class names based on the closest parent or base class.
Use
.js-*
classes to denote behavior (as opposed to style), and do not include these classes in your CSS.
The above guidelines also apply to naming Sass and Less variables.
/* Bad example */
.t { ... }
.red { ... }
.header { ... }
/* Good example */
.tweet { ... }
.important { ... }
.tweet-header { ... }
Selectors
Use class names for common elements to optimize rendering performance.
Avoid attribute selectors (e.g.,
[class^="..."]
) for frequently occurring components. Browser performance can be affected by these.Keep selectors short and limit the number of elements in the selector to no more than 3.
Only use scoped class names when necessary (i.e., descendant selectors) (e.g., when not using prefixed classes—prefixes act as namespaces).
Further reading:
-Scope CSS classes with prefixes
/* Bad example */
span { ... }
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
/* Good example */
.tweet-username { ... }
.page-container .stream .stream-item .tweet .tweet-header .tweet-username { ... }
.avatar { ... }
/* Good example */
.avatar { ... }
.tweet-header .username { ... }
.tweet .avatar { ... }
Code Organization
Organize code by component.
Establish consistent commenting conventions.
Use consistent whitespace to separate code into blocks, which aids in scanning large documents.
If using multiple CSS files, split them by component rather than by page, as pages will be reorganized, while components will be moved.
/* * Component section heading */ .element { ... } /* * Component section heading * * Sometimes you need to include optional context for the entire component. Do that up here if it's important enough. */ .element { ... } /* Contextual sub-component or modifier */ .element-heading { ... }
Editor Configuration
Set your editor to the following settings to avoid common code inconsistencies and differences:
Use two spaces for indentation instead of tabs (soft-tab).
Remove trailing whitespace when saving.
Set file encoding to UTF-8.
Add a blank line at the end of the file.
Refer to the documentation and add these settings to the project's .editorconfig
file. For example: Bootstrap's .editorconfig example. For more information, see about EditorConfig.