Session Digital
Frontend Development Guidelines

The aim of this guide is standardise frontend coding practices and styles across all current and future projects, provide a reference as well as allowing develops to easily move between projects.

General Practices

Indentation

For all code languages, we require indentation to be done via soft tabs (using the space character). Hitting Tab in your text editor shall be equivalent to four spaces.

Readability vs Compression

We prefer readability over file-size savings when it comes to maintaining existing files. Plenty of whitespace is encouraged, along with ASCII art, where appropriate. There is no need for any developer to purposefully compress HTML or CSS, nor obfuscate JavaScript.

We will use server-side or build processes to automatically minify and gzip all static client-side files, such as CSS and JavaScript.

HTML

DOCTYPE (Document type declaration)

The line of code which appears at the very top of any HTML document. Essential for the proper rendering of documents in browsers and with the advent of HTML5 the doctype can be declared as simply

<!DOCTYPE html>

Although this is not a standard yet, we recommend using this DOCTYPE as it’s supported in all browsers and throws IE6 & IE7 into standards mode.

More reading

Write Clean and Semantic Markup

The following guidelines are for writing and structuring your HTML. We recommend using HTML tags for their intended purpose and structuring using indentation and whitespace where appropriate. This is the simplest form of SEO.

Although HTML5 accepts various forms of structuring HTML tags, please use XHTML 1.0 standards of writing all tags in lowercase, all attributes must be quoted and all elements must have a closing tag unless they are self-closing (e.g. <img />).

  • Using <p> for paragraphs of text
  • Heading tags such as <h1> for for titles
  • List items structured using <li>, <ol>, <dl>
  • Tables are to be only used for tabular data
  • Make use of <thead>, <th>, <tbody> tags when defining tables
  • Use microformats where appropriate
  • use commenting <!-- --> to break up sections and better describe your code to someone viewing your code for the first time
  • add descriptions to images using the alt="" attribute
  • avoid inline styles like the plague

CSS

Although everyone has their own personal style in coding CSS stylesheets, the following guidelines are based on the collective best practices for coding CSS amongst frontend and backend developers.

General coding practices

  • include styling through external stylesheets and add to the head of the document using the <link> tag
  • use a reset css stylesheet to standardise cross browser behaviour as much as possible (normalize), included already in the HTML5 Boilerplate
  • Use classes instead of id’s unless you’re targeting a single item in the document (e.g. #header, #footer, #sidebar)
  • Write efficient CSS
  • Always end property values with a semi-colon, even if it’s the only one
  • comment your code, not only to describe what’s happening, but also to explain browser specific fixes.

Whitespace and structure

CSS selectors should be written on a single line and properties on separate lines and indented as shown below:

/* PREFERABLY NOT LIKE THIS */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section {
    display: block; padding: 10px 0 0;
}
/* note: i’ve found when copying selectors from firebug, your IDE search tool won’t find it unless you remove everything after the first comma */

/* OR THIS */
article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; padding: 10px 0 0; }

/* LIKE THIS */
article, aside, details, figcaption, figure, footer, header, hgroup, nav, section {
    display: block;
    padding: 10px 0 0;
}

Spacing

When spacing CSS properties, space for readability rather than for file size savings. There shouldn’t be a space between the property and the colon (:), a space should exist between the colon and the value and no space between the property value and the semi-colon.

/* NOT LIKE THIS */
padding :0 10px 5px 5px ;

/* OR THIS */
padding:0 10px 5px 5px;

/* LIKE THIS */
padding: 0 10px 5px 5px;

If you are modifying an existing stylesheet which doesn’t conform to this structure, use a web app such as ProCSSor to pre-format the stylesheet.

Naming Conventions for Selectors

It is always preferable to name something, be it an ID or a class, by the nature of what it is rather than by what it looks like. For instance, a class name of big-blue-text for a special note on a page is quite meaningless if it has been changed to have a small red text color. Using a more intelligent convention such as note-text is better because when the visual style changes it still makes sense.

When defining selectors, if the class or id you have named consists of more than one word, separate the words using hyphens rather than using underscore or camel case.

/* NOT LIKE THIS */
note_text

/* OR THIS */
noteText

/* LIKE THIS */
note-text

CSS Shorthand

In general, CSS shorthand is preferred because of it’s compactness (saves characters) and the ability to later go back and add in values that are already present, such as the case with margin and padding.

Developers should be aware of the TRBL acronym, denoting the order in which the sides of an element are defined, in a clock-wise manner: Top, Right, Bottom, Left. If bottom is undefined, it inherits its value from top. Likewise, if left is undefined, it inherits its value from right. If only the top value is defined, all sides inherit from that one declaration.

/* NOT LIKE THIS */
padding-top: 0px ;
padding-right: 10px;
padding-bottom: 0px;
padding-left: 10px;

/* BETTER */
padding: 0px 10px 0px 10px;

/* BEST */
padding: 0 10px;

Also if a value of a property is 0, there’s no point adding px, em, % values as they are all the same.

No !important

The use of !important automatically brings the property to the top of the hierarchy, overwriting even more specifically written selectors. It’s use should be avoided at all costs, rather a better understanding of CSS selector precedence, and how to better target elements is preferred.

Styling for Internet Explorer < 9

When styling for < IE9 or a specific version of IE, it's recommended not to use hacks in CSS to apply fixes. You can add conditional statements to the body tag, such as:

<!--[if lt IE 7 ]> <body class="ie6"> <![endif]-->
<!--[if IE 7 ]>	<body class="ie7"> <![endif]-->
<!--[if IE 8 ]>	<body class="ie8"> <![endif]-->
<!--[if IE 9 ]>	<body class="ie9"> <![endif]-->
<!--[if !IE]><!--> <body> <!--<![endif]-->

Or through tools such as the HTML5 Boilerplate which adds a class to the html tag depending on what browser the document is viewed in.

<!--[if lt IE 7]> <html class="no-js ie ie6" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie ie7" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if IE 9]> <html class="no-js ie9" lang="en"> <![endif]-->
<!--[if gt IE 9]><!--><!--<![endif]-->

Important When targeting IE or specific versions of IE, always comment with a description of the issue so other developers can understand the problem the styling is trying to fix.

.no-borderradius .collateral-tabs .tab span { /* border-radius for IE */
	behavior: url(/skin/frontend/dreams/default/js/PIE.php);
}

Tools

InstaCSS - Find out about CSS properties, instantly

CSS3

Where appropriate, it is recommended to apply CSS3 styling to take advantage of styling available in modern browsers and future proofing the website. Fallbacks will need to be included to support browsers which don’t support CSS3 properties, not necessarily to exactly replicate the same styling, but at a minimum provide the same functionality.

Below is an example of declaring the background property twice so browsers which don’t support RGBA values use the image background.

/* Background image fallback for browsers which don’t support RGBA */
background: url(../images/background.png);
background: rgba(0,0,0,0.5);

HTML5 Boilerplate provides feature sniffing classes, allowing you to target browsers which don’t support specific CSS3 properties and apply alternative styling.

Vendor prefixes

Some CSS3 properties are not fully supported by browsers and require vendor prefixes (-moz-, -webkit-) to the property. The recommended structure is to add the vendor prefixes first followed by the actual CSS3 property.

-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;

Tools

  • CSS3 Generator - quickly generate CSS3 including vendor prefixes using this web app.
  • Layer Styles - providing a similar interface to Photoshop to generate CSS3 styles
  • -prefix-free - a javascript plugin which adds the browser prefix only when required, allowing you to specify the property without prefixes.
  • CSS3 PIE - allows IE6-9 the capability of rendering several CSS3 properties.

Fonts

More often than not, a custom font (non web-safe font) is required on the site you’re building. Before implementing the custom font, carefully choose a font stack which includes web-safe fonts just in case the custom font doesn’t appear for the customer.

For applying custom fonts to the site, we recommend the use of @font-face which has a wide browser support including Internet Explorer since IE5. The advantages of @font-face is that the font is downloaded by the user without the requirement of flash, javascript or php to render the font. There is a differentiation in appearance between browsers, but this is due to the font rendering of different browsers/OS. Make use you have a properly licenced font before using tools such as Font Squirel to convert your fonts. Other systems which may be an alternative to @font-face inlcude:

Other tried but not recommended font solutions include:

  • sIFR - which was one of the original font replacement systems, uses Flash and Javascript to render customs fonts in the browser. With some devices not supporting Flash it won’t work, it renders on page load and text won’t appear until it loads.
  • cufon - a slightly better system as it uses JS to render fonts, but the text is unselectable and even on their website, they recommend that you use typekit

Font sizing

We recommend using px values for font sizing, at the very least assigning the base font as a pixel value. This is to ensure control and consistency of font sizing across browsers. Ems were recommended due to IE6 not being able to resize px value fonts, but IE7 and up as well as modern browsers are able to resize px value fonts.

Images

  • Always include an alt description to images, for accessibility
  • Repeating background images need to be larger than 1px x 1px
  • Use sprite images where appropriate to reduce http requests
  • Never use spacer images

Javascript

Be consistent

If you're editing code, take a few minutes to look at the code around you and determine its style. It would be pointless and very time consuming to reformat every pre-existing bit of code you come across. If they use spaces around all their arithmetic operators, you should too. The point of having style guidelines is to have a common vocabulary of coding so people can concentrate on what you're saying rather than on how you're saying it.

JS Lint

Run your code through jslint, it'll make it easier to spot errors and keep your code well formatted. It is ok to have some exceptions, as long as you can justify them.

Var

Declarations with var: Always.

When you fail to specify var, the variable gets placed in the global context, potentially clobbering existing values. Also, if there's no declaration, it's hard to tell in what scope a variable lives (e.g., it could be in the Document or Window just as easily as in the local scope).

Spacing

Keep everything tidy with a single space between entities, apart from before the () in a function declaration and at either end of an object or array.

var add = 1 + 2;
var divString = '<div>' + add + '</div>';
var arr = [1, 2, 3];  // No space after [ or before ].
var obj = {a: 1, b: 2, c: 3};  // No space after { or before }.

function checkWorld() {
  if (add === 3) {
    alert('the world makes sense');
  } else {
    alert(‘???’);
  }
}

Semicolons

Always use semicolons. Relying on implicit insertion can cause subtle, hard to debug problems. Don't do it. You're better than that.

Curly Braces

Because of implicit semicolon insertion, always start your curly braces on the same line as whatever they're opening. For example:

if (something) {
  // ...
} else {
  // ...
}

Strings

Prefer ' over "

For consistency single-quotes (') are preferred to double-quotes ("). This is helpful when creating strings that include HTML:

var msg = 'This is some HTML';

Blank lines

Use newlines to group logically related pieces of code. For example:

doSomethingTo(x);
doSomethingElseTo(x);
andThen(x);

nowDoSomethingWith(y);

andNowWith(z);

Array and Object literals

Use Array and Object literals instead of Array and Object constructors. Array constructors are error-prone due to their arguments.

var a = new Array();
var a = [];

Object constructors don't have the same problems, but for readability and consistency object literals should be used.

var o = new Object();
var o = {};

Naming Conventions

In general, use functionNamesLikeThis, variableNamesLikeThis, ClassNamesLikeThis.

Use namespaces for global code

ALWAYS prefix identifiers in the global scope with a unique pseudo namespace related to the project or library. If you are working on "Project Sloth", a reasonable pseudo namespace would be sloth.*.

var sloth = {};

sloth.sleep = function() {
  ...
};

Parentheses

Only where required. Use sparingly and in general only where required by the syntax and semantics.

Never use parentheses for unary operators such as delete, typeof and void or after keywords such as return, throw as well as others (case, in or new).

Array and Object Initializers

Single-line array and object initializers are allowed when they fit on a line:

var arr = [1, 2, 3];  // No space after [ or before ].
var obj = {a: 1, b: 2, c: 3};  // No space after { or before }.

Multiline array initializers and object initializers are indented 2 spaces, just like blocks.

// Object initializer.
var inset = {
  top: 10,
  right: 20,
  bottom: 15,
  left: 12
};

Cacheing

Cache variables from higher up the scope chain. If you use a variable from a parent function, object or the global scope more than once cache it in a local variable.

Browser reflow

Avoid browser reflow where possible. It can have a big impact on performance.

Reduce unnecessary DOM depth. Changes at one level in the DOM tree can cause changes at every level of the tree - all the way up to the root, and all the the way down into the children of the modified node. This leads to more time being spent performing reflow.

If you make complex rendering changes such as animations, do so out of the flow. Use position-absolute or position-fixed to accomplish this.

Don't make multiple inserts for the same function, create an array and insert in one.

/* instead of this */
var letters = ['a', 'b', 'c', 'd', 'e']
for(i = 0; i< letters.length; i++) {
	$('ul#letters').append('<li>' + letters[i] + '</li>');
}

/* do this */
var letters = ['a', 'b', 'c', 'd', 'e'],
	html = [];

for(i = 0; i < letters.length; i++) {
	html[i] = '<li>' + letters[i] + '</li>';
}

$('ul#letters').append(html.join(''));

/* faster still
*  if you wrap your insertion in a single element this imporves performance further
*  note: this method is preferred to creating a string due to ie speed issues
*/

var letters = ['a', 'b', 'c', 'd', 'e'],
    html = ['<ul>'];

for(i = 0; i < letters.length; i++) {
    html[i+1] = '<li>' + letters[i] + '</li>';

    if(i === letters.length) {
         html[i+1] = '</ul>';
    }
}

$('#letters').append(html.join(''));

Avoid adding and removing elements unneccessarily.

/* instead of this */
$('#nav').hover(function() {
	$('#nav').append('<div id="new-div" />');
}, function() {
	$('#new-div').remove();
});

/* do this and hide #new-div with css */
$('#nav').append('<div id="new-div" />');
$('#nav').hover(function() {
	$('#new-div').show();
}, function() {
	$('#new-div').hide();
});

The for-in loop

Only for iterating over keys in an object/map/hash.

for-in loops are often incorrectly used to loop over the elements in an Array. This is however very error prone because it does not loop from 0 to length - 1 but over all the present keys in the object and its prototype chain.

Always use normal for loops when using arrays.

function printArray(arr) {
  var l = arr.length;
  for (var i = 0; i < l; i++) {
    print(arr[i]);
  }
}

jQuery

Setup

Use jQuery.noConflict();

Pass $ as a variable to avoid conflicts.

DOM ready

The following are identical in function.

jQuery(function() {});
jQuery(document).ready(function() {});

For snippets use the following:

jQuery(function($) {
  //use dollar here
  $(‘#selector’).text(‘$ not gonna conflict here’);
});

Plugins

Use this for plugin wrapping etc.

(function($) {
  //pop it in a closure & use dollar
})( jQuery );

Selectors

Use #ids over .classes where possible.

Give it a context where appropriate $('.class', '#id') or $(‘.class’, this)

Use selectors over functions

Selectors are generally quicker than functions, prefer them where appropriate.

/* quick */
var d = $('div:not(#header)');
/* less quick */
var d = $('div').not('#header');

Iteration

$.each() is neat but slow, for loops are much quicker.

Native functions are always faster than any helper counterparts. Plus .each() has an extra function callback for each iteration.

Use cacheing

Cache wherever possible.

var $selector = $('selectors');

Use $ to reference that it is a jQuery reference.

Use chaining & reduce function calls

/* don't do this */
$('.div-class').addClass('fairly-slow');
$('.div-class').attr('slow', 'fairly');
$('.div-class').show();

/* do this */
$('.div-class').addClass('fast').attr('slow', 'nope').show();

/* also don't do this */
$('#div-one').addClass('add-me');
$('#div-two').addClass('add-me');
$('#div-three').addClass('add-me');

/* do this */
$('#div-one, #div-two, #div-three').addClass('add-me');

Use the data attribute

Use .data() to store data needed in the DOM not 'rel' or 'alt'.

Accessibility

Web accessibility principles

The four principles of web accessibility are set out in the Web Content Accessibility Guidelines (WCAG) 2.0 are:

  • Perceivable - Available through sight, hearing, or touch.
  • Operable - Compatible with keyboard or mouse.
  • Understandable - User-friendly, easy to comprehend.
  • Robust - Works across browsers, assistive technologies, mobile devices, old devices/browsers, etc. Follows standards.

Good practice guidelines

The following are the basic guidelines that should be followed as a minimum when building sites, see the full WCAG guidelines for full details on requirements and different levels of compliance.

General

  • properly structure content, appropriate use of headings, lists, tables etc
  • write valid HTML and CSS

Images

  • should have descriptive alt text

Text

  • should be resizable without breaking the site
  • avoid images of text, except for logos
  • avoid font replacement systems

Links

  • link text should be descriptive (not just 'click here')
  • ensure that users can tell when a link has focus by using the hover, active and focus pseudo-classes

Colour

  • make sure there's sufficient colour contrast between body text and the background
  • don't rely on colour alone to convey meaning

Keyboard accessibility

  • users should be able to navigate site using keyboard and access all core functionality (eg, submitting forms)
  • ensure there are no keyboard traps
  • provide skip links to allow keyboard users to skip over long lists of links, such as long navigation menus

Forms

  • input fields should have labels
  • ensure that forms can be completed and submitted using keyboard only
  • ensure that error messages are useful
  • avoid captchas

Audio / Video

  • user should be able to mute/pause
  • when audio / video is key content captions and alternative formats, eg. transcripts, should be provided

Javascript

  • ensure that JavaScript event handlers are device independent (e.g., they do not require the use of a mouse)
  • sites should not rely on JavaScript to function

Useful links