Hinderling Volkart Frontend Coding Guidelines
Version 1.4 ( 2015-09-18 / sk )
Version 1.5 ( 2016-04-21 / dme ): Adds Best-Practices, updates CSS Formatting rules
Formatting
1. General
- Encoding: UTF-8
- Indentation: Tabs
- We like Spaces and Readability
.i_am_a_selector + p {
color: #fff;
transform: scale(1);
}
function doSomeFancyStuff( param1, param2 ) {
// fancy stuff
if ( param1 < param2 ) {
return false;
}
return true;
}
is better than
.i_am_a_selector+p{
color:#fff;
transform: scale(1);
}
function cmpF(p1,p2){
if (p1<p2) return false;
return true;
}
2. HTML
- Attributes wrapped with double quotes
- Filenames with underscores (e.g. myfancymodule.html.haml)
- the HTML is W3C Valid
- We use semantics where semantics make sense
- Try to avoid too many structural elements like sections, articles, headings
- We'll use level headings (no matter the structural elements):
- h1 for page title
- h2 for main sections
- etc.
2a. HAML / RUBY
- Use single quotes for static string:
part 'components/mymodule'– double quotes are only needed for strings with variables:error :id => "#{input_id}_error" - Do not use randomized strings! Randomizing output makes it extremely difficult to compare with diffs. We have two extensions to satisfy these needs:
uidreturns a unique id as string,uid(:int)returns a unique id as integer- the constant lorem extension gives you the power of lorem with "constant random": just use it like lorem. Also note the
lorem.randfunction that should be used whenever you think you'd like to userand.
- We have a
parthelper that replaces the usualpartialandpartial_wrap:partial 'a', :locals => {:id => uid}is replaced bypart 'a', :id => uidpartial_wrap 'a', :locals => {:id => uid} dois replaced bypart 'a', :id => uid do
- We always work with locals in partials. Define default parameters at the top of your partial:
- id ||= uid
- title ||= 'Default Title'
3. SASS (CSS)
- Use SCSS
- We avoid selecting tag names (to separate styling from semantics)
- We avoid multi level selectors: just select
.mega_list--iteminstead of.mega_list .mega_list--item(after all we have expressive class names, right?) - CSS States are an alternative to Variants. They must be prefixed with
is-orhas-orno-. E.g.is-open,has-menu. States are often set by Javascript. Only style states in combination with a unique class name! (so never do.is-open .mega_list--itembut.mega_list.is-open .mega_list--item!!) - Please consider prefixing all components with a project wide abbreviation: This helps avoiding future collision with third party selectors (e.g. edelweiss:
ew-*) - Avoid using Frameworks
- Don't use CSS Hacks (use Modernizr if necessary)
- Extend with care: only @extend %placeholder_selectors!! We considere it good practice to avoid extending at all in most cases.
- Don't do this:
[class*="some_class-"]Better go with.some-class, .some-class-a, .some-class-b
3.1 Formatting
- Properties indented with tabs
- Selectors in lowercase
- Class names with underscore:
.mega_list - A descendent of a class is denoted with two dashes:
.mega_list--item - A Different variant or version of a class is denoted with one dash:
.mega_list-ultra - SASS: Variables and function names in camelCase
- Put a space before the opening brace
{in rule declarations - In properties, put a space after, but not before, the
:character. - Put closing braces
}of rule declarations on a new line
Bad
.bad{
border:2px solid white; }
.no, .not_good, .bad {
// ...
}
Good
.avatar {
border: 2px solid white;
}
.one,
.selector,
.per-line {
// ...
}
4. JS
- There is no JS that is included without Require.js (beside of Modernizr and IE8 Shims)
- Modernizr must be customized.
- We only do feature detection.
- Variables and function names in camelCase
- Constructors, Singletons and class names in PascalCase
- Constants in UPPERCASE (e.g. ANIMATIONDURATION)
- References to jQuery objects start with $ (e.g.
$container) - Use jshint and JSCS (JavaScript Code Style) with the provided default configs (.jshintrc and .jscsrc) to lint the code and programatically enforce our style guide.
- We avoid selecting css class names that are not 'js' prefixed.
So basically select
.js-list--itemwithin.js-list, notliwithinul.list - The only exception from this rules are states: you may set, unset and (if really necessary) select states, like
is-open,is-activeorhas-menu - Comments (because we use YUI compressor):
/\*!
\* Not stripped when compressed
\*/
/\*
\* Stripped when compressed
\*/
5. Units
- We generally use PX and %
- REM/EM's are only used for Font-Sizes and styles that depend on text.
6. Images
- Optimize all included images (with ImageOptim for example) (unless its included in the middleman build)
- Icons and layout specific images are usually included in standard and retina resolution.
- The naming for retina is "{name}-2x.{ext}", e.g. logo-2x.png – sprites are within folder "{name}2x", e.g. "icons2x".
- Generated sprites are by default optimized with pngquant (if installed)
7. General Best-Practices
- Avoid setting custom classes on base/layout components (like .l-grid), if not really necessary (especially within a component):
Bad
.l-grid
.l-col.l-1of1.not-good
Good
.l-grid
.l-col.l-1of1
.better