HTML/CSS - Table of contents

HTML

Syntax

  • Use a 4-space tab to indent.
  • 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>).
<!DOCTYPE html>
<html>
    <head>
        <title>Page title</title>
    </head>
    <body>
        <img src="images/company-logo.png" alt="Company">
        <h1 class="hello-world">Hello, world!</h1>
    </body>
</html>

HTML5 doctype

Enforce standards mode and more consistent rendering in every browser possible with this simple doctype at the beginning of every HTML page.

<!DOCTYPE html>
<html>
    <head>
    </head>
</html>

CSS and JavaScript 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.

HTML5 spec links

<!-- External CSS -->
<link rel="stylesheet" href="code-guide.css">

<!-- In-document CSS -->
<style>
  /* ... */
</style>

<!-- JavaScript -->
<script src="code-guide.js"></script>

Reducing markup

Whenever possible, avoid superfluous parent elements when writing HTML. Many times this requires iteration and refactoring, but produces less HTML. Take the following example:

<!-- Not so great -->
<span class="avatar">
	<img src="...">
</span>

<!-- Better -->
<img class="avatar" src="...">

CSS

Syntax

  • Use a 4-space tab to indent.
  • 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 prefix property values or color parameters with a leading zero (e.g., .5 instead of 0.5 and -.5px instead of -0.5px).
  • 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 hex values where available, e.g., #fff instead of #ffffff.
  • 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.
  • Avoid specifying units for zero values, e.g., margin: 0; instead of margin: 0px;.
/* 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'] {
    margin-bottom: 15px;
    padding: 15px;

    background-color: rgba(0,0,0,.5);
    box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}

Don't use @import

Compared to <link>s, @import is slower, adds extra page requests, and can cause other unforeseen problems. Avoid them and instead opt for an alternate approach:

  • Use multiple <link> elements
  • Compile your CSS with a preprocessor like Sass or Less into a single file

For more information, read this article by Steve Souders.

<!-- Use link elements -->
<link rel="stylesheet" href="core.css">

<!-- Avoid @imports -->
<style>
    @import url("more.css");
</style>

Prefixed properties

The preferred method when handling vendor prefix properties, is to use a Sass mixin. (See example)

When using vendor prefixed properties, indent each property such that the declaration's value lines up vertically for easy multi-line editing.

In Textmate, use Text → Edit Each Line in Selection (⌃⌘A). In Sublime Text 2, use Selection → Add Previous Line (⌃⇧↑) and Selection → Add Next Line (⌃⇧↓).

/* Preferred Method */

@mixin boxShadow($str) {
    -webkit-box-shadow: #{$str};
       -moz-box-shadow: #{$str};
        -ms-box-shadow: #{$str};
         -o-box-shadow: #{$str};
            box-shadow: #{$str};
}

.class {
	boxShadow(1px, 1px, 1px, #000);
}


/* Other Method */
.selector {
	-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
    		box-shadow: 0 1px 2px rgba(0,0,0,.15);
}

Nesting in Less and Sass

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.

// Without nesting
.table > thead > tr > th {  }
.table > thead > tr > td {  }

// With nesting
.table > thead > tr {
	> th {  }
	> td {  }
}

Class Names

  • Keep classes lowercase and use dashes (not underscores or camelCase). Dashes serve as natural breaks in related class (e.g., .btn and .btn-danger).
  • Avoid excessive and arbitrary shorthand notation. .btn is useful for 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.
/* Bad example */
.t { ... }
.red { ... }
.header { ... }

/* Good example */
.lk-tweet { ... }
.lk-tweet-header { ... }

Organization

  • Organize sections of code by component.
  • Develop a consistent commenting hierarchy.
  • Use consistent white space to your advantage when separating sections of code for scanning larger documents.
  • When using multiple CSS files, break them down by component instead of page. Pages can be rearranged and components moved.
  • A 5 carriage returns before starting a new section
/*===========================================================================*\
                                    ¡VARIABLES
\*===========================================================================*/
$breakpoints: (
    phone:      450px,
    phone-lg:   650px,
    tablet:     767px,
    tablet-lg:  992px,
    desktop-lg: 1024px,
    desktop-xl: 1400px
);




/*------------------------------------*\
           Helper functions
\*------------------------------------*/
/**
* so we don't always have to 
* type 'map-get' in our stylesheet
*
* e.g. background: color(color-100);
*/
@function breakpoint($key) {
    @if map-has-key($breakpoints, $key) {
        @return map-get($breakpoints, $key);
    }
    @warn "Unknown #{$key} in breakpoints map";
    @return null;
}

Comments and Stylesheet Widths

Because CSS is a more like a declarative language than anything else, and tied directly to its HTML counterparts.

  • Top level comments should be 80 columns long, and all styles should try to stay within that range. This allows for easier reading next to large HTML templates, in the terminal, and on Github pages.

Any stand alone category in the stylesheet should have some sort of marker comment in order to be able to jump to that section code quickly. These sections should be prepended with a ¡ (option + 1) in order to search for them. For example:

/*===========================================================================*\
                                    ¡VARIABLES
\*===========================================================================*/
$breakpoints: (
    phone:      450px,
    phone-lg:   650px,
    tablet:     767px,
    tablet-lg:  992px,
    desktop-lg: 1024px,
    desktop-xl: 1400px
);




/*------------------------------------*\
           Helper functions
\*------------------------------------*/
/**
* so we don't always have to 
* type 'map-get' in our stylesheet
*
* e.g. background: color(color-100);
*/
@function breakpoint($key) {
    @if map-has-key($breakpoints, $key) {
        @return map-get($breakpoints, $key);
    }
    @warn "Unknown #{$key} in breakpoints map";
    @return null;
}

Media Queries

Should be inline with the class or attribute that they apply to. This makes the stylesheet incredibly more modular and manageable.

.product-container {
    margin: 50px 0 0;
    .product {
        @include gridMachine(3, 1%);
        float: left;
        height: auto;
        img {
            width: 100%;
        }
        &:nth-child(2) {
            margin-top: 150px;
        }
    }
}
@media screen and (max-width: breakpoint(tablet)) {
    .product-container {
        text-align: center;
        .product {
            display: inline-block;
            float: none;
            width: 250px;
            &:nth-child(2) {
                margin-top: 0;
            }
        }
    }
}

Sublime Text Help

CSSComb can help with a some of the structure and ordering of the css file. To the right is the user settings file to use to help with getting the correct spaces and stucturing of CSS declarations. To run CSSComb, select the text, right click, and select CSSComb.

{
    // Full list of supported options and acceptable values can be found here:
    // https://github.com/csscomb/csscomb.js/blob/master/doc/options.md
    "config": {

        // Whether to add a semicolon after the last value/mixin.
        "always-semicolon": true,

        // Set indent for code inside blocks, including media queries and nested rules.
        "block-indent": "    ",

        // Unify case of hexadecimal colors.
        "color-case": "lower",

        // Whether to expand hexadecimal colors or use shorthands.
        "color-shorthand": true,

        // Unify case of element selectors.
        "element-case": "lower",

        // Add/remove line break at EOF.
        "eof-newline": true,

        // Add/remove leading zero in dimensions.
        "leading-zero": false,

        // Unify quotes style.
        "quotes": "single",

        // Remove all rulesets that contain nothing but spaces.
        "remove-empty-rulesets": true,

        // Set space after `:` in declarations.
        "space-after-colon": " ",

        // Set space after combinator (for example, in selectors like `p > a`).
        "space-after-combinator": " ",

        // Set space after `{`.
        "space-after-opening-brace": "\n",

        // Set space after selector delimiter.
        "space-after-selector-delimiter": "\n",

        // Set space before `}`.
        "space-before-closing-brace": "\n",

        // Set space before `:` in declarations.
        "space-before-colon": "",

        // Set space before combinator (for example, in selectors like `p > a`).
        "space-before-combinator": " ",

        // Set space before `{`.
        "space-before-opening-brace": false,

        // Set space before selector delimiter.
        "space-before-selector-delimiter": "",

        // Set space between declarations (i.e. `color: tomato`).
        "space-between-declarations": "\n",

        // Whether to trim trailing spaces.
        "strip-spaces": true,

        // Whether to remove units in zero-valued dimensions.
        "unitless-zero": true,

        // Whether to align prefixes in properties and values.
        "vendor-prefix-align": true,

        // Sort properties in particular order.
        "sort-order": [
            [
                "font",
                "font-family",
                "font-size",
                "font-weight",
                "font-style",
                "font-variant",
                "font-size-adjust",
                "font-stretch",
                "font-effect",
                "font-emphasize",
                "font-emphasize-position",
                "font-emphasize-style",
                "font-smooth",
                "line-height"
            ],
            [
                "position",
                "z-index",
                "top",
                "right",
                "bottom",
                "left"
            ],
            [
                "display",
                "visibility",
                "float",
                "clear",
                "overflow",
                "overflow-x",
                "overflow-y",
                "-ms-overflow-x",
                "-ms-overflow-y",
                "clip",
                "zoom",
                "flex-direction",
                "flex-order",
                "flex-pack",
                "flex-align"
            ],
            [
                "-webkit-box-sizing",
                "-moz-box-sizing",
                "box-sizing",
                "width",
                "min-width",
                "max-width",
                "height",
                "min-height",
                "max-height",
                "margin",
                "margin-top",
                "margin-right",
                "margin-bottom",
                "margin-left",
                "padding",
                "padding-top",
                "padding-right",
                "padding-bottom",
                "padding-left"
            ],
            [
                "table-layout",
                "empty-cells",
                "caption-side",
                "border-spacing",
                "border-collapse",
                "list-style",
                "list-style-position",
                "list-style-type",
                "list-style-image"
            ],
            [
                "content",
                "quotes",
                "counter-reset",
                "counter-increment",
                "resize",
                "cursor",
                "-webkit-user-select",
                "-moz-user-select",
                "-ms-user-select",
                "user-select",
                "nav-index",
                "nav-up",
                "nav-right",
                "nav-down",
                "nav-left",
                "-webkit-transition",
                "-moz-transition",
                "-ms-transition",
                "-o-transition",
                "transition",
                "-webkit-transition-delay",
                "-moz-transition-delay",
                "-ms-transition-delay",
                "-o-transition-delay",
                "transition-delay",
                "-webkit-transition-timing-function",
                "-moz-transition-timing-function",
                "-ms-transition-timing-function",
                "-o-transition-timing-function",
                "transition-timing-function",
                "-webkit-transition-duration",
                "-moz-transition-duration",
                "-ms-transition-duration",
                "-o-transition-duration",
                "transition-duration",
                "-webkit-transition-property",
                "-moz-transition-property",
                "-ms-transition-property",
                "-o-transition-property",
                "transition-property",
                "-webkit-transform",
                "-moz-transform",
                "-ms-transform",
                "-o-transform",
                "transform",
                "-webkit-transform-origin",
                "-moz-transform-origin",
                "-ms-transform-origin",
                "-o-transform-origin",
                "transform-origin",
                "-webkit-animation",
                "-moz-animation",
                "-ms-animation",
                "-o-animation",
                "animation",
                "-webkit-animation-name",
                "-moz-animation-name",
                "-ms-animation-name",
                "-o-animation-name",
                "animation-name",
                "-webkit-animation-duration",
                "-moz-animation-duration",
                "-ms-animation-duration",
                "-o-animation-duration",
                "animation-duration",
                "-webkit-animation-play-state",
                "-moz-animation-play-state",
                "-ms-animation-play-state",
                "-o-animation-play-state",
                "animation-play-state",
                "-webkit-animation-timing-function",
                "-moz-animation-timing-function",
                "-ms-animation-timing-function",
                "-o-animation-timing-function",
                "animation-timing-function",
                "-webkit-animation-delay",
                "-moz-animation-delay",
                "-ms-animation-delay",
                "-o-animation-delay",
                "animation-delay",
                "-webkit-animation-iteration-count",
                "-moz-animation-iteration-count",
                "-ms-animation-iteration-count",
                "-o-animation-iteration-count",
                "animation-iteration-count",
                "-webkit-animation-direction",
                "-moz-animation-direction",
                "-ms-animation-direction",
                "-o-animation-direction",
                "animation-direction",
                "text-align",
                "-webkit-text-align-last",
                "-moz-text-align-last",
                "-ms-text-align-last",
                "text-align-last",
                "vertical-align",
                "white-space",
                "text-decoration",
                "text-emphasis",
                "text-emphasis-color",
                "text-emphasis-style",
                "text-emphasis-position",
                "text-indent",
                "-ms-text-justify",
                "text-justify",
                "letter-spacing",
                "word-spacing",
                "-ms-writing-mode",
                "text-outline",
                "text-transform",
                "text-wrap",
                "text-overflow",
                "-ms-text-overflow",
                "text-overflow-ellipsis",
                "text-overflow-mode",
                "-ms-word-wrap",
                "word-wrap",
                "word-break",
                "-ms-word-break",
                "-moz-tab-size",
                "-o-tab-size",
                "tab-size",
                "-webkit-hyphens",
                "-moz-hyphens",
                "hyphens",
                "pointer-events"
            ],
            [
                "opacity",
                "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
                "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
                "-ms-interpolation-mode",
                "color",
                "border",
                "border-width",
                "border-style",
                "border-color",
                "border-top",
                "border-top-width",
                "border-top-style",
                "border-top-color",
                "border-right",
                "border-right-width",
                "border-right-style",
                "border-right-color",
                "border-bottom",
                "border-bottom-width",
                "border-bottom-style",
                "border-bottom-color",
                "border-left",
                "border-left-width",
                "border-left-style",
                "border-left-color",
                "-webkit-border-radius",
                "-moz-border-radius",
                "border-radius",
                "-webkit-border-top-left-radius",
                "-moz-border-radius-topleft",
                "border-top-left-radius",
                "-webkit-border-top-right-radius",
                "-moz-border-radius-topright",
                "border-top-right-radius",
                "-webkit-border-bottom-right-radius",
                "-moz-border-radius-bottomright",
                "border-bottom-right-radius",
                "-webkit-border-bottom-left-radius",
                "-moz-border-radius-bottomleft",
                "border-bottom-left-radius",
                "-webkit-border-image",
                "-moz-border-image",
                "-o-border-image",
                "border-image",
                "-webkit-border-image-source",
                "-moz-border-image-source",
                "-o-border-image-source",
                "border-image-source",
                "-webkit-border-image-slice",
                "-moz-border-image-slice",
                "-o-border-image-slice",
                "border-image-slice",
                "-webkit-border-image-width",
                "-moz-border-image-width",
                "-o-border-image-width",
                "border-image-width",
                "-webkit-border-image-outset",
                "-moz-border-image-outset",
                "-o-border-image-outset",
                "border-image-outset",
                "-webkit-border-image-repeat",
                "-moz-border-image-repeat",
                "-o-border-image-repeat",
                "border-image-repeat",
                "outline",
                "outline-width",
                "outline-style",
                "outline-color",
                "outline-offset",
                "background",
                "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
                "background-color",
                "background-image",
                "background-repeat",
                "background-attachment",
                "background-position",
                "background-position-x",
                "-ms-background-position-x",
                "background-position-y",
                "-ms-background-position-y",
                "-webkit-background-clip",
                "-moz-background-clip",
                "background-clip",
                "background-origin",
                "-webkit-background-size",
                "-moz-background-size",
                "-o-background-size",
                "background-size",
                "box-decoration-break",
                "-webkit-box-shadow",
                "-moz-box-shadow",
                "box-shadow",
                "filter:progid:DXImageTransform.Microsoft.gradient",
                "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
                "text-shadow"
            ]
        ]
    }
}