Principles of writing consistent, idiomatic CSS.

Related tags

CSS idiomatic-css
Overview

Principles of writing consistent, idiomatic CSS

The following document outlines a reasonable style guide for CSS development. These guidelines strongly encourage the use of existing, common, sensible patterns. They should be adapted as needed to create your own style guide.

This is a living document and new ideas are always welcome. Please contribute.

Table of contents

  1. General principles
  2. Whitespace
  3. Comments
  4. Format
  5. Practical example

Acknowledgements

License

1. General principles

"Part of being a good steward to a successful project is realizing that writing code for yourself is a Bad Idea™. If thousands of people are using your code, then write your code for maximum clarity, not your personal preference of how to get clever within the spec." - Idan Gazit

  • Don't try to prematurely optimize your code; keep it readable and understandable.
  • All code in any code-base should look like a single person typed it, even when many people are contributing to it.
  • Strictly enforce the agreed-upon style.
  • If in doubt when deciding upon a style use existing, common patterns.

2. Whitespace

Only one style should exist across the entire source of your code-base. Always be consistent in your use of whitespace. Use whitespace to improve readability.

  • Never mix spaces and tabs for indentation.
  • Choose between soft indents (spaces) or real tabs. Stick to your choice without fail. (Preference: spaces)
  • If using spaces, choose the number of characters used per indentation level. (Preference: 4 spaces)

Tip: configure your editor to "show invisibles" or to automatically remove end-of-line whitespace.

Tip: use an EditorConfig file (or equivalent) to help maintain the basic whitespace conventions that have been agreed for your code-base.

3. Comments

Well commented code is extremely important. Take time to describe components, how they work, their limitations, and the way they are constructed. Don't leave others in the team guessing as to the purpose of uncommon or non-obvious code.

Comment style should be simple and consistent within a single code base.

  • Place comments on a new line above their subject.
  • Keep line-length to a sensible maximum, e.g., 80 columns.
  • Make liberal use of comments to break CSS code into discrete sections.
  • Use "sentence case" comments and consistent text indentation.

Tip: configure your editor to provide you with shortcuts to output agreed-upon comment patterns.

Example:

/* ==========================================================================
   Section comment block
   ========================================================================== */

/* Sub-section comment block
   ========================================================================== */

/**
 * Short description using Doxygen-style comment format
 *
 * The first sentence of the long description starts here and continues on this
 * line for a while finally concluding here at the end of this paragraph.
 *
 * The long description is ideal for more detailed explanations and
 * documentation. It can include example HTML, URLs, or any other information
 * that is deemed necessary or useful.
 *
 * @tag This is a tag named 'tag'
 *
 * TODO: This is a todo statement that describes an atomic task to be completed
 *   at a later date. It wraps after 80 characters and following lines are
 *   indented by 2 spaces.
 */

/* Basic comment */

4. Format

The chosen code format must ensure that code is: easy to read; easy to clearly comment; minimizes the chance of accidentally introducing errors; and results in useful diffs and blames.

  • Use one discrete selector per line in multi-selector rulesets.
  • Include a single space before the opening brace of a ruleset.
  • Include one declaration per line in a declaration block.
  • Use one level of indentation for each declaration.
  • Include a single space after the colon of a declaration.
  • Use lowercase and shorthand hex values, e.g., #aaa.
  • Use single or double quotes consistently. Preference is for double quotes, e.g., content: "".
  • Quote attribute values in selectors, e.g., input[type="checkbox"].
  • Where allowed, avoid specifying units for zero-values, e.g., margin: 0.
  • Include a space after each comma in comma-separated property or function values.
  • Include a semi-colon at the end of the last declaration in a declaration block.
  • Place the closing brace of a ruleset in the same column as the first character of the ruleset.
  • Separate each ruleset by a blank line.
.selector-1,
.selector-2,
.selector-3[type="text"] {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    display: block;
    font-family: helvetica, arial, sans-serif;
    color: #333;
    background: #fff;
    background: linear-gradient(#fff, rgba(0, 0, 0, 0.8));
}

.selector-a,
.selector-b {
    padding: 10px;
}

Declaration order

If declarations are to be consistently ordered, it should be in accordance with a single, simple principle.

Smaller teams may prefer to cluster related properties (e.g. positioning and box-model) together.

.selector {
    /* Positioning */
    position: absolute;
    z-index: 10;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;

    /* Display & Box Model */
    display: inline-block;
    overflow: hidden;
    box-sizing: border-box;
    width: 100px;
    height: 100px;
    padding: 10px;
    border: 10px solid #333;
    margin: 10px;

    /* Other */
    background: #000;
    color: #fff;
    font-family: sans-serif;
    font-size: 16px;
    text-align: right;
}

Larger teams may prefer the simplicity and ease-of-maintenance that comes with alphabetical ordering.

Exceptions and slight deviations

Large blocks of single declarations can use a slightly different, single-line format. In this case, a space should be included after the opening brace and before the closing brace.

.selector-1 { width: 10%; }
.selector-2 { width: 20%; }
.selector-3 { width: 30%; }

Long, comma-separated property values - such as collections of gradients or shadows - can be arranged across multiple lines in an effort to improve readability and produce more useful diffs. There are various formats that could be used; one example is shown below.

.selector {
    background-image:
        linear-gradient(#fff, #ccc),
        linear-gradient(#f3c, #4ec);
    box-shadow:
        1px 1px 1px #000,
        2px 2px 1px 1px #ccc inset;
}

Preprocessors: additional format considerations

Different CSS preprocessors have different features, functionality, and syntax. Your conventions should be extended to accommodate the particularities of any preprocessor in use. The following guidelines are in reference to Sass.

  • Limit nesting to 1 level deep. Reassess any nesting more than 2 levels deep. This prevents overly-specific CSS selectors.
  • Avoid large numbers of nested rules. Break them up when readability starts to be affected. Preference to avoid nesting that spreads over more than 20 lines.
  • Always place @extend statements on the first lines of a declaration block.
  • Where possible, group @include statements at the top of a declaration block, after any @extend statements.
  • Consider prefixing custom functions with x- or another namespace. This helps to avoid any potential to confuse your function with a native CSS function, or to clash with functions from libraries.
.selector-1 {
    @extend .other-rule;
    @include clearfix();
    @include box-sizing(border-box);
    width: x-grid-unit(1);
    // other declarations
}

5. Practical example

An example of various conventions.

/* ==========================================================================
   Grid layout
   ========================================================================== */

/**
 * Column layout with horizontal scroll.
 *
 * This creates a single row of full-height, non-wrapping columns that can
 * be browsed horizontally within their parent.
 *
 * Example HTML:
 *
 * <div class="grid">
 *     <div class="cell cell-3"></div>
 *     <div class="cell cell-3"></div>
 *     <div class="cell cell-3"></div>
 * </div>
 */

/**
 * Grid container
 *
 * Must only contain `.cell` children.
 *
 * 1. Remove inter-cell whitespace
 * 2. Prevent inline-block cells wrapping
 */

.grid {
    height: 100%;
    font-size: 0; /* 1 */
    white-space: nowrap; /* 2 */
}

/**
 * Grid cells
 *
 * No explicit width by default. Extend with `.cell-n` classes.
 *
 * 1. Set the inter-cell spacing
 * 2. Reset white-space inherited from `.grid`
 * 3. Reset font-size inherited from `.grid`
 */

.cell {
    position: relative;
    display: inline-block;
    overflow: hidden;
    box-sizing: border-box;
    height: 100%;
    padding: 0 10px; /* 1 */
    border: 2px solid #333;
    vertical-align: top;
    white-space: normal; /* 2 */
    font-size: 16px; /* 3 */
}

/* Cell states */

.cell.is-animating {
    background-color: #fffdec;
}

/* Cell dimensions
   ========================================================================== */

.cell-1 { width: 10%; }
.cell-2 { width: 20%; }
.cell-3 { width: 30%; }
.cell-4 { width: 40%; }
.cell-5 { width: 50%; }

/* Cell modifiers
   ========================================================================== */

.cell--detail,
.cell--important {
    border-width: 4px;
}

Translations

Acknowledgements

Thanks to everyone who has provided translations and to all those who contributed to idiomatic.js. It was a source of inspiration, quotations, and guidelines.

License

Principles of writing consistent, idiomatic CSS by Nicolas Gallagher is licensed under the Creative Commons Attribution 3.0 Unported License. This applies to all documents and translations in this repository.

Based on a work at github.com/necolas/idiomatic-css.

You might also like...

Data-tip.css - Wow, such tooltip, with pure css!

Notice: hint.css has been much better since I complained about it months ago, so try out its new features instead of this one! data-tip.css Wow, such

May 26, 2021

Tiny CSS framework with almost no classes and some pure CSS effects

Tiny CSS framework with almost no classes and some pure CSS effects

no.css INTERACTIVE DEMO I am tired of adding classes to style my HTML. I just want to include a .css file and I expect it to style the HTML for me. no

Dec 10, 2022

The most popular HTML, CSS, and JavaScript framework for developing responsive, mobile first projects on the web.

The most popular HTML, CSS, and JavaScript framework for developing responsive, mobile first projects on the web.

Bootstrap Sleek, intuitive, and powerful front-end framework for faster and easier web development. Explore Bootstrap docs » Report bug · Request feat

Jan 1, 2023

Modern CSS framework based on Flexbox

Modern CSS framework based on Flexbox

Bulma Bulma is a modern CSS framework based on Flexbox. Quick install Bulma is constantly in development! Try it out now: NPM npm install bulma or Yar

Dec 31, 2022

A utility-first CSS framework for rapid UI development.

A utility-first CSS framework for rapidly building custom user interfaces. Documentation For full documentation, visit tailwindcss.com. Community For

Dec 30, 2022

Materialize, a CSS Framework based on Material Design

MaterializeCSS Materialize, a CSS Framework based on material design. -- Browse the docs -- Table of Contents Quickstart Documentation Supported Brows

Jan 2, 2023

Material Design Components in HTML/CSS/JS

Material Design Lite An implementation of Material Design components in vanilla CSS, JS, and HTML. Material Design Lite (MDL) lets you add a Material

Jan 4, 2023

A set of small, responsive CSS modules that you can use in every web project.

A set of small, responsive CSS modules that you can use in every web project.

Pure A set of small, responsive CSS modules that you can use in every web project. http://purecss.io/ This project is looking for maintainers to suppo

Jan 3, 2023

Functional css for humans

TACHYONS Functional CSS for humans. Quickly build and design new UI without writing CSS. Principles Everything should be 100% responsive Everything sh

Jan 4, 2023
Comments
  • Mainly added more examples in the declaration order

    Mainly added more examples in the declaration order

    I mainly added more examples in the declaration order —and edited the example section to be consistent—. Also made many changes in the comments section. Other small changes were performed.

    There could be grammar mistakes, because my English is not really good. And sorry for the large amount of commits, I'm a noob here.

    opened by battaglr 2
  • Added Georgian translation

    Added Georgian translation

    I fully understand that the file has not been updated for a long time, but I believe (and not without reason) that this guide is still relevant today. That is why I decided to translate it into my native language - Georgian.

    I will be very happy if I can make at least a small contribution to this project.

    thanks!

    opened by davidkadaria 1
Owner
Nicolas Gallagher
Working on @reactjs for the web
Nicolas Gallagher
OrganiCSS is a collection of mixins for writing logical CSS in different pre-processors and libraries.

OrganiCSS is a collection of mixins and functions to support writing progressively-enhanced logical CSS in many different flavors. Getting Started To

OrganiCSS 5 Jul 20, 2022
Reseter.css - A Futuristic CSS Reset / CSS Normalizer

Reseter.css A CSS Reset/Normalizer Reseter.css is an awesome CSS reset for a website. It is a great tool for any web designer. Reseter.css resets all

Krish Dev DB 1.1k Jan 2, 2023
Spectre.css - A Lightweight, Responsive and Modern CSS Framework

Spectre.css Spectre.css is a lightweight, responsive and modern CSS framework. Lightweight (~10KB gzipped) starting point for your projects Flexbox-ba

Yan Zhu 11.1k Jan 8, 2023
Low-level CSS Toolkit – the original Functional/Utility/Atomic CSS library

Basscss Low-level CSS toolkit – the original Functional CSS library https://basscss.com Lightning-Fast Modular CSS with No Side Effects Basscss is a l

Basscss 5.8k Dec 31, 2022
Framework-agnostic CSS-in-JS with support for server-side rendering, browser prefixing, and minimum CSS generation

Aphrodite Framework-agnostic CSS-in-JS with support for server-side rendering, browser prefixing, and minimum CSS generation. Support for colocating y

Khan Academy 5.3k Jan 1, 2023
CSS Boilerplate / Starter Kit: Collection of best-practice CSS selectors

Natural Selection Natural Selection is a CSS framework without any styling at all. It is just a collection of selectors that can be used to define glo

FrontAid CMS 104 Dec 8, 2022
Source code for Chrome/Edge/Firefox/Opera extension Magic CSS (Live editor for CSS, Less & Sass)

Live editor for CSS, Less & Sass (Magic CSS) Extension Live editor for CSS, Less & Sass (Magic CSS) for Google Chrome, Microsoft Edge, Mozilla Firefox

null 210 Dec 13, 2022
Easily create css variables without the need for a css file!

Tailwind CSS Variables This plugin allows you to configure CSS variables in the tailwind.config.js Similar to the tailwindcss configurations you are u

Mert Aşan 111 Dec 22, 2022
Cooltipz.css - A highly customisable, minimal, pure CSS tooltip library

Cooltipz.css - Cool tooltips Cool customisable tooltips made from pure CSS Lightweight • Accessible • Customisable • Simple Cooltipz.css is a pure CSS

Jack Domleo 110 Dec 24, 2022
micro-library for CSS Flexbox and CSS Grid

SpeedGrid micro-library for CSS Flexbox and CSS Grid Overview SpeedGrid dynamically generates inline CSS by specifying the class name. Easy maintenanc

Toshihide Miyake 7 Mar 26, 2022