Skip to content

Coding guidelines HTML, (S)CSS and JavaScript

Jermaine edited this page May 20, 2019 · 1 revision

Coding guidelines HTML, (S)CSS and JavaScript

Standards for developing flexible, durable, and sustainable HTML and (S)CSS and JavaScript.

Quicklinks

HTML

HTML Markup and syntax

  • Use soft tabs with two spaces, they're the only way to guarantee code renders the same in any environment. Nested elements should be indented once (two spaces). By default, the boilerplate(s) by Kingfisher contain a .editorconfig that handles this when your IDE supports it.

  • Always use double quotes, never single quotes, on attributes.

  • Don't include a trailing slash in self-closing elements - the HTML5 spec says they're optional.

  • Don't omit optional closing tags (e.g. </li> or </body>).

  • Markup should be well-formed, semantically correct and generally valid. This means for example: the markup-elements should be used for what they were meant. <table> for tabular data, <li> should be used for things that are repeating in some way, no <p> inside a <span>, etc.

  • Test markup against the W3C Markup Validation Service to ensure that the markup is well formed. 100% valid code is a goal, and validation certainly helps to debug and write more maintainable websites. If you're not willing to use the W3C Markup Validation Service, try one of the browser extensions below.

    HTML validation tools

Doctype and character encoding

  • After a lengthy experimentation with the XML-based XHTML variant the industry has accepted that HTML is the future of the web. So let's stick with that.
  • A proper Doctype which triggers standards mode in your browser should always be used. Quirks mode should be avoided. For HTML5 just <!DOCTYPE html> is enough.
  • All markup should be delivered as UTF-8, as it's the most friendly for internationalization. It should be designated in both the HTTP header and the head of the document: <meta charset="utf-8">

HTML5 elements

  • Use HTML5 elements instead of divs if possible. Elements like <figure>, <header>, <nav>, <article>, <aside>, <section>, <footer> and many others are here to stay.

Separation of concerns

  • Presentation, content, behaviour. In this case this means no inline styles nor scripts and the following rules when it comes to external CSS and Javascript.

    Details

    • External CSS placed in the <head> section.
    • External JavaScript defined right before the </body> tag.
    • Readability is preferred over file-size savings when it comes to maintaining existing files. Use server-side or build processes to minify and gzip all static client-side files, such as CSS and JavaScript.
    • JavaScript and CSS should progressively enhance the experience. This means without JavaScript and styling the site should still be usable. This is important for SEO, too.

Includes

  • Per HTML5 spec, typically there is no need to specify a type when including CSS and Javascript files as text/css and text/javascript are their respective defaults. Stylesheets should be imported using <link>, not <style>@import, which is slower, adds extra page requests, and can cause other unforeseen problems.

    HTML5 spec

Roles

  • With HTML5, it's becoming more common to use role attributes on an element to indicate its functionality is different from its intended class. For example, to use your regular external link styling on a navigation point, use: <header class="header-main" role="banner">.

Internet Explorer

  • Internet Explorer supports the use of a document compatibility <meta> tag to specify what version of IE the page should be rendered as. Unless circumstances require otherwise, it's most useful to instruct IE to use the latest supported mode with edge mode using <meta http-equiv="X-UA-Compatible" content="IE=Edge">.

    For more information, read this awesome answer on Stack Overflow.

Forms

  • Use label fields to label each form field, the for-attribute should associate itself with the input field (<label for="email">), so users can click the labels. Usage of cursor: pointer; on the label is wise too.
  • Do not use the size-attribute on your input fields. The size-attribute is relative to the font-size of the text inside the input. Instead use a CSS width declaration.

CSS

CSS Markup and syntax

  • Use soft tabs with two spaces, they're the only way to guarantee code renders the same in any environment. Include 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 a semi-colon. 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 (e.g., box-shadow).
  • Don't include spaces after commas within rgb(), rgba(), hsl(), hsla(), or rect() values. This helps differentiate multiple color values (comma, no space) from multiple property values (comma with space).
  • Don't prefix property values or color parameters with a leading zero (e.g., .5em instead of 0.5em).
  • Lowercase all hex values, e.g., #fff. Lowercase letters are much easier to discern when scanning a document as they tend to have more unique shapes.
  • Use shorthand notation when possible: no unit when value is 0, #fff instead of #ffffff etc.
  • Quote attribute values in selectors, e.g., input[type="text"]. They're only optional in some cases, and it's a good practice for consistency.
  • End every declaration with a semicolon (;).
  • Use double quotation marks for variables and values.
  • Every declaration on its own line.
  • Order declarations by type. For example, place positioning declarations like width, height, padding and margin below each other.
  • Do put the opening bracket of a declaration on a new line, this helps with version control.
  • Put a space between the property and its value: font-color: color(black);.
  • Omit the protocol, e.g. background-image: url("//somedomain.com/images/image.gif");.

Declaration order

  • Try to keep related property declarations grouped together following the order:

    • Positioning
    • Box-model
    • Typography
    • Visual

    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.

Shorthand notation

  • Strive to limit use of shorthand declarations to instances where you must explicitly set all the available values. Common overused shorthand properties include:

    • margin
    • padding
    • font
    • background
    • border

    Keep it clean

    Often times we don't need to set all the values a shorthand property represents. For example, HTML headings only set top and bottom margin, so when necessary, only override those two values. Excessive use of shorthand properties often leads to sloppier code with unnecessary overrides and unintended side effects.

    Example
      font: {
        family: font(heading);
        size: 1.5em;
        style: italic;
        weight: bold;
      }

    The Mozilla Developer Network has a great article on shorthand properties for those unfamiliar with notation and behavior.

Note about (not) using !important

  • Using !important overrides all specificity no matter how high it is. We like to avoid using importants for this reason. Most of the time it they're unnecessary, even if you need to override a selector in a stylesheet you don't have access to, there are usually ways to override it without using !important, but avoid using them if possible.

Comments

  • Code is written and maintained - with ♥ - 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.
  • Speaking of comments, you may want to standardize on that. The /* $foo */-syntax in SCSS is pretty nice especially for blocks of comments, so it is easier to comment/uncomment individual lines. Besides that, many well-known IDE's support this way of commenting, even when your comments are multi lined.
  • Comments that refer to selector blocks should be on a separate line immediately before the block to which they refer.
  • Comments that refer to a property should be placed behind the property.

Class names

  • Keep class names lowercase and use dashes (not underscores or camelCase), like you would in real language. Dashes serve as natural breaks in related class (e.g., .button and .is-hidden).
  • Avoid excessive and arbitrary shorthand notation. .button or .btn are useful for a button, but .s doesn't mean anything. Keep classes as short and succinct as possible.
  • Use meaningful names; use structural or purposeful names over presentational.
  • Prefix classes based on the closest parent or base class.
  • Use data-attributes 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 variable names.
  • Avoid using ID's if they're unnecessary/not needed. ID's are (almost) only handy for stuff like JavaScript. Don't mix up classes and ID's; an ID can only be used once and in fact are better avoided. Use ID and class names that are as short as possible but as long as necessary.
  • Use ID and class names in one spoken language, preferably English. Do yourself, and the rest of the team a favor .
  • 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 like bigBlueText 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 noteText is better because when the visual style changes it still makes sense.

Selectors

  • Use classes over generic element tag for optimum rendering performance. Use selectors that are max 3 levels deep. For example, .wrapper-main nav ul li a is way too complex, in this example .wrapper-main li a is enough. See 'Nesting in SASS' below for more info.

  • Avoid 'expensive' CSS selectors. For example, avoid the * wildcard selector and don't qualify ID selectors like div#myid or class selectors like table.results. It's slower to process/render and takes away your freedom.

  • If you specify multiple selectors, it's a good idea to start each on new line. This prevents lines from growing long and improves readability as well as version control workflow.

    Example

      .element,
      .other-element,
      .another-element {
        font: {
          family: font(body);
          weight: bold;
        }
      }
  • Avoid using several attribute selectors (e.g., ="...") on commonly occuring components. Browser performance is known to be impacted by these.

  • CSS selectors should always start with a letter, they won't work with a leading digit.

  • Keep selectors short and strive to limit the number of elements in each selector to three.

  • Scope classes to the closest parent only when necessary (e.g., when not using prefixed classes).

  • Presentation attributes of HTML like <font color="red"> have all been deprecated and style should be contained in stylesheets.

  • Always use title-case for headers and titles, if the customer asks for it. Do not use ALL CAPS or all lowercase titles in markup, instead apply the CSS property text-transform: uppercase; and text-transform: lowercase;.

  • Browsers calculate a selector's specificity to determine which CSS rule should apply. If two selectors apply to the same element, the one with the higher specificity wins. See Keegan's Specificity Calculator to calculate selector specificity.

Pseudo classes

Organization

  • Organize sections of code by component.
  • Develop a consistent commenting hierarchy.
  • Use consistent whitespace to your advantage when separating sections of code for scanning larger documents.

State rules

  • States rules (e.g. .is-hidden, .is-selected) are generally applied to the same element as a layout rule or applied to the same element as a base module class for modification.

Typography

  • Use the px-unit of measurement to define font-size when you declare it in body, because it offers absolute control over text. In the past the em-unit was preferable but now that all browsers support pixel sizing, it can be called 'deprecated'.
  • Additionally, unit-less line-height is preferred because it does not inherit a percentage value of its parent element, but instead is based on a multiplier of the font-size. (ie: font-size: 20px; and line-height: 1.5em; results in lines that are 30px high).
  • Make use of the <strong> and <em> to make text bold or italics, <b> and <i> work as well, but they are invalid. Oh, and they're 'invented' by Microsoft.

Images

  • Do not use 1x1 pixel images for bg-gradients. IE does not like this and it's a performance hit. A useful gradient editor, including SASS output can be found at Colorzilla's website.
  • Also, never use spacer images, transparent pixels or &nbsp;, just fix this with correct margins/paddings.

SCSS

Nesting in SCSS

  • 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.
  • Nest your SCSS according to their main element holders, not exactly like it is on your page. If you want more overview, use indenting or don't nest at all and use better class names.

Operators in SCSS

  • For improved readability, wrap all math operations in parentheses with a single space between values, variables and operators.

Specificity

  • Add all of your colors to configuration in _variables.scss, and if possible/needed, use lighten() and darken() to set their offsets.

Vendor specific prefixes

Mobile-first

  • Since we're living in the era of awesome smartpho... *ahem* awesome smart watches, smartphones and tablets, the stylesheets for all new projects/websites will be written with mobile-first in mind. The principle of mobile first in CSS can be kinda hard in the beginning - just like working in a SCRUM environment - but in the end it's all worth it. A good explanation of mobile first can be found on Brad Frost's website.
  • Writing and using a few human-readable @mixins can make working with the mobile-first principe very easy, as you can see in the example above. Our .classname has some properties like color, height etc and with the @include breakpoint()-mixin we can set properties for every separate device.

JavaScript

  • Writing markup in a Javascript file makes the content harder to find, harder to edit, and less performant. * Avoid it whenever possible. When you're using JavaScript thingies written by others, for example found on open source websites like Github, Codepen, JSBin or Unheap, make sure you make use of the non-minified version of the script. Of course, the minified version is used for production.

JavaScript markup and syntax

  • Avoid global variables. These could be overwritten by other scripts and cause problems. Namespaces are a proper solution for this matter. More information about namespaces can be found here.
  • Declare local variables before hand. This way you have a better overview in which variables are being used. When no yet given a value pass null to these variables as a value.
  • Declare the previously named local variables at the top of your method/function
  • Beware of automatic type conversions. Numbers can accidentally be converted to strings or NaN (not a number). You can use typeof 'string' to find the type of your variable.
  • Use the === operator instead of ==. It is considered best practice to always use the former set when comparing.