styleguide_html.md - HTML Styles and Formatting
styleguide_js.md - JavaScript Styles and Formatting
styleguide_less.md - LESS/CSS Styles and Formatting
styleguide_html.md - HTML Styles and Formatting
styleguide_js.md - JavaScript Styles and Formatting
styleguide_less.md - LESS/CSS Styles and Formatting
The goal of this document is not to give rules that result in perfect code. It is so that with minimal effort the code will:
<br/>
, place blocking elements like <div>
as appropriate<div>
tags for spacing-only, modify the margin of the surrounding <div>
tags<button>
element instead of <input type="button">
<table>
elements when displayng tabular data<div id="myPage">Contents</div>
<!-- Good -->
<div>
<a href="#">Link Here</a>
This is a test
</div>
<!-- Bad -->
<div><a href="#">Link Here</a>This is a test</div>
<body>
tag should have the attribute class="pageName-ns" set<html>
<header>
<title>My Page</title>
<link rel="stylesheet" type="text/css" href="bootstrap3.css" />
<link rel="stylesheet" type="text/css" href="pageName.css" />
</header>
<body class="pageName-ns">
</body>
<footer>
</footer>
<script type="text/javascript" src="jquery-1.10.2.js"> </script>
<script type="text/javascript" src="pageName.js"> </script>
</html>
The goal of this document is not to give rules that result in perfect code. It is so that with minimal effort the code will:
if (! com) { var com = {}; }
if (! com.pageName) { com.pageName= {}; }
// Wrapping new functions and variables within an object as properties
com.pageName = {
variableName: 'variableValue',
functionName: function( param1 ) {
// statements
}
}
// Wrapping functions and variables within a function
// An API is returned from the function as a JS object, the properties are the publicly accessable functions and variables
// See example module-pattern-jquery.html
com.pageName = function() {
var publicFunction = function() {
privateFunction();
}
var privateFunction = function() {
// statements
}
var oPublic = {
publicFunction: publicFunction
};
return oPublic;
}
com.pageName.functionName(param1);
camelCase; // function and var declarations
functionNamesLikeThis;
variableNamesLikeThis;
methodNamesLikeThis;
PascalCase; // constructor function
ConstructorNamesLikeThis;
EnumNamesLikeThis;
SYMBOLIC_CONSTANTS_LIKE_THIS
// Good
var deliveryNote = 1;
// Bad
var delNote = 1;
'dog' is a string
'dogs' is an array
'dogArray' is an array
// jQuery objects should be prefixed with $
var $curTarget = $(event.currentTarget);
// Regular Expressions prefixed with r
var rEmailer = //;
// Private methods are prefixed with _
com.pageName = function() {
var publicFunction = function() {
_privateFunction();
}
var _privateFunction = function () {
// statements
}
var oPublic = {
publicFunction: publicFunction
};
return oPublic;
}
(
function( param1, param2 )
{param1: "Hello", param2: "World"}
// Open braces on same line as the previous statement
// Close braces on the same indent as the original function call
function func() {
return {
"name": "Batman"
};
}
// Readability Examples
while( condition ) {
// statements
}
if( true ) {
// statements
} else {
// statements
}
// Ternery if/else statments allowed
if( value > 100 ) ? alert('Expensive') : alert('Cheap');
// Using only one `var` per scope (function) promotes readability
// and keeps your declaration list free of clutter
var foo = "",
bar = "",
quux;
// Literal notations:
var array = new Array(),
object = new Object();
// var statements should always be in the beginning of their respective scope (function)
function foo() {
var bar = "",
qux;
// statements
}
// Inline
$( "#target" ).click( function() {
// statements
});
// By Reference
$( "#target" ).click( functionName );
// Constructor Declaration
function FooBar( options )
this.options = options;
}
// Usage
var fooBar = new FooBar({ a: "alpha" });
fooBar.options;
// Good
$('.testId[href^="www.any.com"]').show();
// Bad
var word = "word";
Type Checking (Courtesy jQuery Core Style Guidelines)
Actual Types
String: typeof variable === "string"
Number: typeof variable === "number"
Boolean: typeof variable === "boolean"
Object: typeof variable === "object"
Array: Array.isArray( arrayLikeObject )
Node: elem.nodeType === 1
null: variable === null
null or undefined: variable == null
undefined:
Global Variables:
typeof variable === "undefined"
Local Variables:variable === undefined
Properties:
> object.prop === undefined
> object.hasOwnProperty( prop )
> "prop" in object
Coerced Types
Consider the implications of the following...
Given this HTML: html <input type="text" id="foo-input" value="1">
// `foo` has been declared with the value `0` and its type is `number`
var foo = 0;
// typeof foo;
// "number"
// Somewhere later in your code, you need to update `foo`
// with a new value derived from an input element
foo = document.getElementById("foo-input").value;
// If you were to test `typeof foo` now, the result would be `string`
// This means that if you had logic that tested `foo` like:
if ( foo === 1 ) {
importantTask();
}
// `importantTask()` would never be evaluated, even though `foo` has a value of "1"
// You can preempt issues by using smart coercion with unary + or - operators:
foo = +document.getElementById("foo-input").value;
// ^ unary + operator will convert its right side operand to a number
// typeof foo;
// "number"
if ( foo === 1 ) {
importantTask();
}
// `importantTask()` will be called
Here are some common cases along with coercions:
var number = 1,
string = "1",
bool = false;
number;
// 1
number + "";
// "1"
string;
// "1"
+string;
// 1
+string++;
// 1
string;
// 2
bool;
// false
+bool;
// 0
bool + "";
// "false"
string === number;
// false
string === number + "";
// true
+string === number;
// true
bool === number;
// false
+bool === number;
// true
bool === string;
// false
bool === !!string;
// true
// When only evaluating that an array has length,
// instead of this:
if( array.length > 0 ) ...
// ...evaluate truthiness, like this:
if( array.length ) ...
// When only evaluating that an array is empty,
// instead of this:
if( array.length === 0 ) ...
// ...evaluate truthiness, like this:
if( !array.length ) ...
// When only evaluating that a string is not empty,
// instead of this:
if( string !== "" ) ...
// ...evaluate truthiness, like this:
if( string ) ...
// When only evaluating that a string _is_ empty,
// instead of this:
if( string === "" ) ...
// ...evaluate falsy-ness, like this:
if( !string ) ...
// When only evaluating that a reference is true,
// instead of this:
if( foo === true ) ...
// ...evaluate like you mean it, take advantage of built in capabilities:
if( foo ) ...
// When evaluating that a reference is false,
// instead of this:
if( foo === false ) ...
// ...use negation to coerce a true evaluation
if( !foo ) ...
// ...Be careful, this will also match: 0, "", null, undefined, NaN
// If you _MUST_ test for a boolean false, then use
if( foo === false ) ...
// When only evaluating a ref that might be null or undefined, but NOT false, "" or 0,
// instead of this:
if( foo === null || foo === undefined ) ...
// ...take advantage of == type coercion, like this:
if( foo == null ) ...
// Remember, using == will match a `null` to BOTH `null` and `undefined`
// but not `false`, "" or 0
null == undefined
// Type coercion and evaluation notes
// Prefer `===` over `==` (unless the case requires loose type evaluation)
// === does not coerce type, which means that:
"1" === 1;
// false
// == does coerce type, which means that:
"1" == 1;
// true
// Booleans, Truthies & Falsies
// Booleans:
true, false
// Truthy:
"foo", 1
// Falsy:
"", 0, null, undefined, NaN, void 0
// We need an explicit "bar", because later in the code foo is checked.
var foo = "bar";
/*
Four score and seven-pause-minutes ago...
*/
function foo( types, selector, data, fn, /* INTERNAL */ one ) {
// statements
}
/**
* Reverse a string
*
* @param {String} input_string String to reverse
* @return {String} The reversed string
*/
function reverse(input_string) {
// statements
return output_string;
}
Based on a loosely on a work at github.com/rwldrn/idiomatic.js.
The goal of this document is not to give rules that result in perfect code. It is so that with minimal effort the code will:
All classes should be namespaced. In LESS this is relativly straight forward, wrap the entire document with a class that is the same as the pagename.
#pageName-ns {
.class1 {
// styles
}
.class2 {
// styles
}
}
#pageName-ns .class1 {
// styles
}
#pageName-ns .class2 {
// styles
}
<a name="formatting">Formatting</a>
- Do not create a class for only one element; use the element ID instead
- When specifying length values, do not specify units for a zero value, e.g., left: 0px; becomes left: 0;
- Use single quotes instead of double quotes for all strings
- Where equivalent, use the opacity property instead of rgba(0, 0, 0, a)
<a name="selectors">Selectors</a>
- Use the dash-format to name classes
```css
.class-name-dashed {
// styles
}
a::after {
// styles
}
// Good
.raw-button-one,
.raw-button-two,
.raw-button-three {
// styles
}
// Bad
.raw-button-one, .raw-button-two, .raw-button-three {
// styles
}