:book: Opinionated CSS styleguide for scalable applications

Overview

css

Opinionated CSS styleguide for scalable applications

This guide was heavily inspired by experiments, awesome people like @fat and @necolas and awesome projects made by Google, Airbnb and Medium.

Table of Contents

  1. Terminology 1. Rule Declaration 1. Selectors 1. Properties
  2. [Formatting] (#formatting) 1. [Spacing] (#spacing) 1. [Nesting] (#nesting) 1. [Quotes] (#quotes) 1. [Comments] (#comments)
  3. [Syntax] (#syntax) 1. [Components] (#components) 1. [Descendants] (#descendants) 1. [Modifiers] (#modifiers) 1. [States] (#states)

Terminology

The following are some terms used throughout this styleguide.

Rule declaration

A “rule declaration” is the name given to a selector (or a group of selectors) with an accompanying group of properties. Here's an example:

.avatar {
  font-size: 18px;
  line-height: 1.2;
}

Selectors

In a rule declaration, “selectors” are the bits that determine which elements in the DOM tree will be styled by the defined properties. Selectors can match HTML elements, as well as an element's class, ID, or any of its attributes. Here are some examples of selectors:

.avatar {
  font-size: 20px;
}

#id {
  font-size: 20px;
}

Properties

Finally, properties are what give the selected elements of a rule declaration their style. Properties are key-value pairs, and a rule declaration can contain one or more property declarations. Property declarations look like this:

.avatar {
  background: rgb(255,255,255);
  color: rgb(33,33,33);
}

Formatting

The following are some high level page formatting style rules.

Spacing

CSS rules should be comma separated and leave on a new line:

/* wrong */
.avatar, .tweet {

}
/* right */
.avatar, 
.tweet {

}

Properties should use a space after : but not before:

/* wrong */
.avatar {
  font-size : 12px;
}

.tweet {
  font-size:12px;
}
/* right */
.avatar {
  font-size: 12px;
}

Rule declarations should have one property per line:

/* wrong */
.avatar {
  font-size: 12px; letter-spacing: 2px;
}
/* right */
.avatar {
  font-size: 12px; 
  letter-spacing: 2px;
}

Declaration should be separated by two new lines:

/* wrong */
.avatar {
  font-size: 12px;
}
.tweet {
  letter-spacing: 2px;
}
/* right */
.avatar {
  font-size: 12px;
}

.tweet {
  letter-spacing: 2px;
}

Nesting

Do not nest elements. Keep nesting to pseudo-classes and direct interactions with the parent element. Although nesting is a powerful feature provided by several preprocessors and plugins, it can easily get out of control and generate a terrible css ouput with high specificity or spoil the code legibility.

/* wrong */
.avatar {
  font-size: 12px;
  
  &:hover {
    font-size: 11px;
  }
  
  &__link {
    color: rgb(210,210,22);
  }

  &__photo {
    height: 20px;
  }
}
/* right */
.avatar {
  font-size: 12px;
  
  &:hover {
    font-size: 11px;
  }
}

.avatar__link {
  color: rgb(210,22,221);
}

.avatar__photo {
  height: 20px;
}

Nesting can also be used to when an element is dependent of a parent's modifier. This helps to keep all code related to an element on the same block.

.avatar {
  font-size: 12px;
}

.avatar__photo {
  height: 20px;
  
  .avatar--big & {
    height: 40px;
  }
}

Quotes

Quotes are optional in CSS. You should use single quotes as it is visually clearer that the string is not a selector or a style property.

/* wrong */
.avatar {
  background-image: url(/img/you.jpg);
  font-family: Helvetica Neue Light, Helvetica Neue, Helvetica, Arial;
}
/* right */
.avatar {
  background-image: url('/img/you.jpg');
  font-family: 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial;
}

Comments

Avoid comments as hard as you can. Comments are not easily mantainable and are usually used to supress application design mistakes. Leave comments only to things that are really not straightforward such as browser-specific hacks. Put comments on their own lines to describe content below them.

/* wrong */
.avatar {
  height: 200px; /* this is the height of the container*/
  background-color: rgb(221,33,21); /* brand color */
}
/* right */
.avatar {
  height: 20px;
  
  /* this is a hack to fix click behavior on Safari 6.0 */
  pointer-events: none;
}

Syntax

Syntax: <component-name>[--modifier-name|__descendant-name]

Component driven development offers several benefits when reading and writing HTML and CSS:

  • It helps to distinguish between the classes for the root of the component, descendant elements, and modifications.
  • It keeps the specificity of selectors low.
  • It helps to decouple presentation semantics from document semantics.

You can think of components as custom elements that enclose specific semantics, styling, and behaviour.

Components

Syntax: component-name

The component's name must be written in kebab case.

.my-component {
  font-size: 20px;
}
<article class="my-component"></article>

Descendants

Syntax: component-name__descendant-name

A component descendant is a class that is attached to a descendant node of a component. It's responsible for applying presentation directly to the descendant on behalf of a particular component. Descendant names must be written in kebab case.

<article class="tweet">
  <header class="tweet__header">
    <img class="tweet__avatar" src="{$src}" alt="{$alt}"></header>
  <div class="tweet__body"></div>
</article>

Modifiers

Syntax: component-name--modifier-name

A component modifier is a class that modifies the presentation of the base component in some form. Modifier names must be written in kebab case and be separated from the component name by two hyphens. The class should be included in the HTML in addition to the base component class.

.btn {
  padding: 20px 10px;
}

.btn--primary { 
  background: rgb(148,146,231);
}
<button class="btn btn--primary"></button>

States

Syntax: component-name.is-state-of-component

Use is-stateName for state-based modifications of components. The state name must be kebab case. Never style these classes directly; they should always be used as an adjoining class.

JS can add/remove these classes. This means that the same state names can be used in multiple contexts, but every component must define its own styles for the state (as they are scoped to the component).

.tweet { 
  height: 90px;
}

.tweet.is-expanded { 
  height: 200px;
}
<article class="tweet is-expanded"></article>

License

MIT © 2016

You might also like...

Cooltipz.css - A highly customisable, minimal, pure CSS tooltip library

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

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

Mar 26, 2022

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

Fluent UI web represents a collection of utilities, React components, and web components for building web applications.

Fluent UI Web 🎉 🎉 🎉 Version 8 of @fluentui/react is now available on npm! 🎉 🎉 🎉 See the release notes for more info, and please file an issue if

Jan 4, 2023

A package of small but beautiful React components from the planet, Pluto. 🔵 Get minimal components for your React based applications 😍

A package of small but beautiful React components from the planet, Pluto. 🔵 Get minimal components for your React based applications 😍

React Pluto Component Design System + UI Kit A package of small but beautiful React components from the planet Pluto. To install the latest version, r

Aug 8, 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
Comments
  • Quotes

    Quotes

    Quotes

    Quotes are optional in CSS. You should use single quotes as it is visually clearer that the string is not a selector or a style property.

    /* wrong / .avatar { background-image: url('/img/you.jpg'); font-family: 'Helvetica Neue Light', Helvetica Neue, Helvetica, Arial; } / right */ .avatar { background-image: url(/img/you.jpg); font-family: Helvetica Neue Light, Helvetica Neue, Helvetica, Arial; }

    The "right" answer and "wrong" answer are switched based off of "You should use single quotes..."

    opened by openkey 1
  • What about the ancestors (or ascendants) of a component? How would it be?

    What about the ancestors (or ascendants) of a component? How would it be?

    Hello man!

    First of all, great compilation, congratulations for your efforts. I also really like styleguides, rules, like yours.

    I was thinking of a case today which it may be interesting of debating it with you. What about a case where my component is like, a ribbon. You know, in the corner of an element. I was thinking in some markup like this:

    <div class="ribbon-container">
        <div class="ribbon">New</div>
        <h1>Etc...</h1>
        <p>Lorem ipsum dolor sit amet.</p>
    </div>
    

    In this case, the ribbon-container is an ancestor/ascendant of the component, and not a descendant. How would you suggest it to be marked up? ribbon-container? ribbon__container? I never read too much about BEM and this kind of suggestions so if you know something about it, it would be interesting listening to you.

    Happy to contribute somehow. My best wishes. Regards, Gio. Oh, by the way, I'm also a brazilian, so if you'd prefer to discuss it in portuguese, feel free to do that.

    opened by giovannipds 2
Owner
Guilherme Coelho
:shipit: Shipping a great company at @pagarme
Guilherme Coelho
Styleguide generator is a handy little tool that helps you generate good looking styleguides from stylesheets using KSS notation

SC5 style guide generator Looking for a maintainer If you would like to maintain the project, create an issue and tell a few words about yourself. Sty

SC5 1.3k Sep 26, 2022
Collected dispatches from The Quest for Scalable CSS

A Scalable CSS Reading List A list of things to read or watch that address these two questions: What is scalable CSS? and How do we create scalable CS

David Clark 1.5k Dec 23, 2022
Extensible, scalable, Sass-based, OOCSS framework for large and long-lasting UI projects.

Extensible, scalable, Sass-based, OOCSS framework for large and long-lasting UI projects. inuitcss is a framework in its truest sense: it does not pro

inuitcss 1.8k Dec 30, 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