: for each declaration.box-shadow).rgb(), rgba(), hsl(), hsla(), or rect() values. This helps differentiate multiple color values (comma, no space) from multiple property values (comma with space)..5 instead of 0.5 and -.5px instead of -0.5px).#fff. Lowercase letters are much easier to discern when scanning a document as they tend to have more unique shapes.#fff instead of #ffffff.input[type="text"]. They’re only optional in some cases, and it’s a good practice for consistency.margin: 0; instead of margin: 0px;./*
Add 1 space between class and { tag
Bad is .hero__headline{
*/
.hero__headline {
/*
Add 1 space after :
Bad is display:block;
*/
display: block;
/*
Add ; to the end of row
Bad is margin-bottom: 1em
*/
margin-bottom: 1em;
padding: 15px;
background-color: rgba(0,0,0,.5);
/*
The close } tag should be in a single row
*/
}You should look into _variable.scss to find any global variable like color, font, breakpoints, etc...
The file _typography.scss always include pre-defined typography for Heading, text
The file _button.scss should have pre-defined button styling.
/*
Read /src/scss/ folder
Looking for existing .h1 class from _typography.scss
Looking for existing color $c-blue from _variables.scss
Looking for existing mixin transition from _utils.scss
*/
.hero__headline {
@extend. h1;
@include transition;
color: $c-blue;
}Related property declarations should be grouped together following the order:
Extends and mixins should be add first cause it keep us understand what they override.
Positioning comes second because it can remove an element from the normal flow of the document and override box model related styles. The box model comes next as it dictates a component's dimensions and placement.
Everything else takes place inside the component or without impacting the previous two sections, and thus they come last.
For a complete list of properties and their order, please see Recess.
. {
/* Keep extends and mixins in the top */
@extend .section;
@include transition;
/* Then declarations */
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box-model */
display: flex;
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;
}Place media queries inside each class. Keep mobile-first: define in mobile, then in large screens.
.hero__item {
@extend .headline;
width: 100%;
/*
Keep to use @media inside class in SCSS
Keep mobile first: mobile, then other large screen
*/
@media (min-width: 25em) {
width: 50%;
}
@media (min-width: 30em) {
width: 25%;
}
}You don't need to insert prefix for other web browsers. Our workflow always include the way to add prefix after compiling.
.hero {
display: flex;
/*
Not need add display: -webkit-flex;
*/
}If it extends only one declaration, keep it shorten in same row with class name.
If it extends multiple declarations, add each of them in single row.
/* Multiple declarations, one per line */
.button {
display: inline-block;
padding: 15px 20px;
background-color: black;
}
/*
These below buttons use same class .button, extend only single declaration
*/
.button--red { background-color: red; }
.button--blue { background-color: blue; }
/* But keep multiple lines if it extends more than one declaration */
.button-outline {
@extend .button;
background-color: none;
color: black;
}Strive to limit use of shorthand declarations to instances where you must explicitly set all the available values. Common overused shorthand properties include:
Don't define only 1 value (like 10px) for margin and padding. Using at least two values (like margin: 0 10px;)
marginpaddingfontbackgroundborderborder-radiusIn mobile, you define margin: 0 auto, so in large screen, you need to override margin-top only. Don't use `margin. Use margin-top is better way.
The Mozilla Developer Network has a great article on shorthand properties for those unfamiliar with notation and behavior.
/* Good example */
.element {
/*
Using at least two values for margin and padding
BAD is margin: 10px; (while not need 10px for left and right)
*/
margin: 0 auto;
/*
If not need set padding for left, right and top, don't use padding
BAD is padding: 0 0 10px 0;
*/
padding-bottom: 10px;
/*
Using background-image than background
BAD is background: url('image.jpg');
*/
background-image: url('image.jpg');
/*
If border-radius has 4 values while you define two only, avoid using border-radius
*/
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}Avoid unnecessary nesting. Just because you can nest, doesn't mean you always should. Consider nesting only if you must scope styles to a parent and if there are multiple elements to be nested.
Additional reading:
/*
Keep the code clean with BEM
Avoid nesting if needed until it must be
The BAD example is below
*/
.header__menu {
.menu-item {
a {
color: $c-blue;
&:hover {
color: $c-black;
}
}
}
}
/* Optimization for BETTER code */
.header__menu {}
.header__menu-item {}
.header__menu-link {
color: $c-blue;
&:hover {
color: $c-black;
}
}For improved readability, wrap all math operations in parentheses with a single space between values, variables, and operators.
// Bad example
.element {
margin: 10px 0 $gutter*2 10px;
}
// Good example
.element {
margin: 10px 0 ($gutter * 2) 10px;
}Code is written and maintained by people. Ensure your code is descriptive, well commented, and approachable by others. Great code comments convey context or purpose. Do not simply reiterate a component or class name.
Be sure to write in complete sentences for larger comments and succinct phrases for general notes.
/* Bad example */
/* Modal header */
.modal-header {
...
}
/* Good example */
/* Wrapping element for .modal-title and .modal-close */
.modal-header {
...
}.btn and .btn-danger)..button is useful for button, but .s doesn't mean anything..js-* classes to denote behavior (as opposed to style), but keep these classes out of your CSS.It's also useful to apply many of these same rules when creating Sass and Less variable names.
/* Bad example */
.t { ... }
.red { ... }
.header { ... }
/* Good example */
.tweet { ... }
.important { ... }
.tweet-header { ... }[class^="..."]) on commonly occuring components. Browser performance is known to be impacted by these./* Bad example */
span { ... }
.menu-item a {}
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
.avatar { ... }
/* Good example
Using BEM class
*/
.hero__headline {}
.hero__button {}
.hero__link {}
/* Extends parent class if need override */
.hero__headline {
@extend .h2;
/* If body class contains home */
.home & {
@extend .h2-home;
}
}/* Add from top parent to child */
.hero {
/* Keep other component (like social-links) below if they are under this hero with other style */
.social-links {}
/* BAD is below. Don't nesting because .hero--home can override .hero without adding it inside */
&.hero--home {}
}
/* Keep extend class below, don't add it inside .hero class */
.hero--home {
/* Then add any child element needs override */
.hero__headline {}
.hero__button {}
}
.hero__container {}
.hero__headline {}
.hero__list {}
.hero__button {}Set your editor to the following settings to avoid common code inconsistencies and dirty diffs:
Consider documenting and applying these preferences to your project's .editorconfig file. For an example, see the one in WordPress. Learn more about EditorConfig.