A one-page document to help your team establish effective frontend guidelines, so that you can write consistent & cohesive code together.
- What are some general principles your team should follow when writing HTML? (for example, authoring semantic HTML5 markup, accessibility, etc. See these resources for inspiration)
- Sass preprocessor and SCSS syntax for stylesheet files, using
.scss
extension - Nunjucks for templating engine
- Gulp to run a helpful tasks such as: compiling your Sass files to CSS, processing assets files (JS, images,icons), optimizing and building files for production and more
- Fractal for components library and style guide
- Indent yout code using 2 spaces, not tabs
- Use comments carefully defining start and end of a block in a way like:
<!-- BLOCK NAME - Start --> <!-- BLOCK NAME - End -->
- The Single Responsibility Principle, our CSS should be composed of a series of much smaller classes that focus on providing very specific and limited functionality;
- OOCSS, separaing the UIs into structure and skin; recycle common and recurring design patterns without having to necessarily recycle their specific implementation details at the same time.
- Open/Close principle - any additions, new functionality, or features we add to our classes should be added via extension (modifier in BEM)
- DRY - which stands for Don’t Repeat Repeat Yourself; the key isn’t to avoid all repetition, but to normalise and abstract meaningful repetition
We adopt BEM methodology, the strict way.
- We use Sass preprocessor following some Syntax guidelines
- two (2) spaces indents, no tabs;
- 80-characters wide lines;
- one space before the opening brace of declaration blocks for legibility
- Place closing braces of declaration blocks on a new line
- Include one space after
:
for each declaration - Each declaration should appear on its own line for more accurate error reporting
- End all declarations with
;
. The last declaration's is optional, but your code is more error prone without it. - Comma-separated property values should include a space after each comma
- Lowercase all hex values, e.g.,
#fff
- Use shorthand hex values where available, e.g.,
#fff
instead of#ffffff
.
/* 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;
}
Related property declarations should be grouped together following the order:
- Positioning
- Box model
- Typographic
- Visual
- Misc
.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;
}
Positioning comes first 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.
Use PostCSS VSCode Plugin to automatically sorting your code with this configuration. Copy settings in your VSCode settings.json.
When indenting in Sass, stick two(2) spaces and leave a blank line before and after the nested ruleset:
foo {
color: red;
.bar {
color: blue;
}
}
Avoid selector nesting as much as possible. The problme is that it makes code more difficult to read.
- Don't nest more than 3 leves deep, following the Inception Rule
- Use along with BEM naming convention to generate
.block_element
To avoid any potential issue with character encoding, it is highly recommended to force UTF-8 encoding in the main stylesheet using the @charset directive. Make sure it is the very first element of the stylesheet and there is no character of any kind before it.
@charset 'utf-8'
Wrap Sass strings in single quotes.
// Yep
$direction: 'left';
// Nope
$direction: left;
Specific CSS values (identifiers) such as initial or sans-serif require not to be quoted
// Yep
$font-type: sans-serif;
// Nope
$font-type: 'sans-serif';
If a string contains one or several single quotes, one might consider wrapping the string with double quotes (") instead, in order to avoid escaping characters within the string.
// Yep
@warn "You can't do that.";
URLs should be quoted as well, for the same reasons as above:
// Yep
.foo {
background-image: url('/images/kittens.jpg');
}
// Nope
.foo {
background-image: url(/images/kittens.jpg);
}
- Numbers shouldn't display leading zeros before a decimal value less than one.
- When dealing with lengths, a
0
value should never ever have a unit (e.g.,margin: 0;
instead ofmargin: 0px;
) - Don't prefix property values or color parameters with a leading zero (e.g.,
.5
instead of0.5
and-.5px
instead of-0.5px
)
// Yep
.foo {
padding: 2em;
opacity: .5;
margin: 0;
}
// Nope
.foo {
margin: 0em;
padding: 2.0em;
opacity: 0.5;
}
Top-level numeric calculations should always be wrapped in parentheses.
// Yep
.foo {
width: (100% / 3);
}
// Nope
.foo {
width: 100% / 3;
}
Respect the following order of preference for color formats:
- HSL notation;
- RGB notation;
- HEX notation (lowercase and shortened);
// Yep
.foo {
color: hsl(0, 100%, 50%);
}
// Also yep
.foo {
color: rgb(255, 0, 0);
}
// Meh
.foo {
color: #f00;
}
// Nope
.foo {
color: #FF0000;
}
// Nope
.foo {
color: red;
}
When using HSL or RGB notation, always add a single space after a comma (,) and no space between parentheses ((, )) and content.
// Yep
.foo {
color: rgba(0, 0, 0, 0.1);
background: hsl(300, 100%, 100%);
}
// Nope
.foo {
color: rgba(0,0,0,0.1);
background: hsl( 300, 100%, 100% );
}
Store color variables in another variable with a name explaining how it should be used:
$main-theme-color: $sass-pink;
Maps should be written as follows:
- space after the colon (:);
- opening brace (() on the same line as the colon (:);
- quoted keys if they are strings (which represents 99% of the cases);
- each key/value pair on its own new line;
- comma (,) at the end of each key/value;
- trailing comma (,) on last item to make it easier to add, remove or reorder items;
- closing brace ()) on its own new line;
- no space or new line between closing brace ()) and semi-colon (;).
// Yep
$breakpoints: (
'small': 767px,
'medium': 992px,
'large': 1200px,
);
// Nope
$breakpoints: ( small: 767px, medium: 992px, large: 1200px );
Use custom properties to define dynamic values changing in your design due to some conditions.
CSS Property
Use the custom property for a single CSS property. Names should be equivalent.
// Custom property composition
--{component}-{css-property}
// Example
--header-background
--header-color
—-header-background-image
—-header-font-size
—-header-width
—-header-height
CSS Property Category
Use a single custom property for multiple CSS properties
Property categories:
- Size: width, height
- Spacing: margin, padding
—-button-size
-—button-spacing
- What are some general principles your team should follow when writing JavaScript? (See these resources for inspiration)
- Are you using a JavaScript framework (such as jQuery, Ember, Angular, etc)?
- Where is the documentation for those frameworks?
- Are you using any polyfills or shims (such as any of these)?
- What third-party scripts are dependencies for your project (such as scripts for form validation, graphs, animation, etc)?
- Do you test your JavaScript? If so, what tools do you use (such as Jasmine, Karma, Selenium, etc)?
(See these resources for inspiration)
- Spaces or Tabs?
- What does JS commenting look like?
- What patterns are you following? (See these resources)
- How are you handling icons (such as using SVG, icon fonts, etc)?
- How are you handling responsive images (such as using
srcset
&<picture />
)? - Are you using any tools to optimize and serve images?
- How do you load custom fonts?
- Do you use any tools to help implement web fonts (such as Font Squirrel, etc)?
- Do you use a service to manage and serve custom fonts (such as Fonts.com, Typekit, etc)?
- Do you use performance budgets? If so, what metrics are you using to determine budgets? Where are you keeping track of performance budgets?
- How are you measuring your project's speed (such as Pingdom Speed Test or Google PageSpeed)?
- What techniques are you using to decrease file size (such as Gzip, Image Optimization)?
- What performance-related tools are you using in your workflow? (such as WebPagetest, BigRig Speedcurve)?
- Are you following the accessibility recommendations laid out in this checklist?
- What accessibility-related tools are you using in your workflow?
- Are you using a task runner (such as Grunt or Gulp)?
- Are you using a dependency manager (such as Bower or Composer)?
- Are you using any scaffolding tools (such as Yeoman)?
- Are you using any tools to reinforce frontend style (such as Editor Config or linters)?
- Are any other specific pieces of software that are needed to work on this project?
- What version control system are you using for your frontend code (such as Git or Subversion)?
- Where is your version-controlled code hosted (such as Github or Bitbucket)?
- Do you use a version control workflow (such as gitflow, centralized, feature-branch, etc)?
- Who's responsible for managing and governing the version controlled code??
- Where are issues tracked?
It's important to recognize the difference between "support" and "optimization". You should do your best to support as many environments as possible while simultaneously optimizing for the environments that make the most sense for your business and users.
- What browsers are you optimizing for?
- What devices are you optimizing for?
- Are you using a graded browser support system?
- Are there specific components that require more specific grading?
- Is your website served in different languages? If so, what considerations do you need to address when localizing for other languages?
- How is your front-end code integrated into a production environment?
- Are you using a pattern library tool to document your front-end architecture?
- Where does your documentation live? What are the links to the documentation?
- Who's responsible for maintaining and governing the documentation?
- What happens when the guidelines are updated?
Feel free to modify or extend (such as adding specific sections for performance, accessibility, etc) this document for your own organization's needs. For questions, comments, additions, and corrections, please open an issue on Github and/or reach out to @brad_frost on Twitter.