Approach

Learn about the guiding principles, strategies, and techniques used to build and maintain Docs UI Kit so that you can more easily customize and extend it yourself.

While the getting-started pages provide an introductory tour of the project, this document focuses on why we do the things we do in Docs UI Kit. It explains our philosophy to building on the web so that others can learn from us, contribute to us, and help us improve.

Classes

Aside from our Reboot, a cross-browser normalization stylesheet, all our styles aim to use classes as selectors. It means steering a clear of type selectors (e.g., input[type="text"]) and extraneous parent classes (e.g., .parent .child) that make styles too specific to easily override.

As such components should be built with a base class that houses common, not-to-be overridden property-value pairs. For example, .btn and .btn-primary. We use .btn for all the common styles like display, padding, and border-width. We then use modifiers like .btn-primary to add the color, background-color, border-color and etc.

Modifier classes should only be used when there are multiple properties or values to be changed across multiple variants. Modifiers are not always necessary, so be sure you're actually saving lines of code and preventing unnecessary overrides when creating them. Good examples of modifiers are our theme color classes and size variants.

HTML and CSS over JS

Whenever possible, we prefer to write HTML and CSS over JavaScript. In general, HTML and CSS are more prolific and accessible to more people of all different experience levels. HTML and CSS are also faster in your browser than JavaScript, and your browser generally provides a great deal of functionality for you.

Lastly, our styles build on the fundamental behaviors of common web elements. Whenever possible, we prefer to use what the browser provides. For example, you can put a .btn class on nearly any element, but most elements don't provide any semantic value or browser functionality. So instead, we use <button>s and <a>s.

Utilities

Utility classes are a powerful ally in combatting CSS bloat and poor page performance. A utility class is typically a single, immutable property-value pairing expressed as a class (e.g., .d-block represents display: block;). Their primary appeal is speed of use while writing HTML and limiting the amount of custom CSS you have to write.

Specifically regarding custom CSS, utilities can help combat increasing file size by reducing your most commonly repeated property-value pairs into single classes. This can have a dramatic effect on your projects.


BEM

Introduction

On smaller brochure sites, how you organize your styles isn’t usually a big concern. You get in there, write some CSS, or maybe even some SASS. You compile it all into a single stylesheet with SASS’s production settings, and then you aggregate it to get all the stylesheets from modules into a nice tidy package.

However, when it comes to larger, more complex projects, how you organize your code is the key to efficiency in at least these three ways: it affects how long it takes you to write code, how much of that code you’ll have to write and how much loading your browser will have to do. This becomes especially important when you’re working with teams of themers, and when high performance is essential.

Methodology

The Block, Element, Modifier methodology (commonly referred to as BEM) is a popular naming convention for classes in HTML and CSS. Developed by the team at Yandex, its goal is to help developers better understand the relationship between the HTML and CSS in a given project.

Block

Standalone entity that is meaningful on its own.

Element

A part of a block that has no standalone meaning and is semantically tied to its block.

Modifier

A flag on a block or element. Use them to change appearance or behavior.

Here's an example of what a CSS developer writing in the BEM style might write:

                
                  /* Block component */
                  .btn {}

                  /* Element that depends upon the block */
                  .btn__price {}

                  /* Modifier that changes the style of the block */
                  .btn--success {}
                  .btn--lg {}
                
              

In this CSS methodology a block is a top-level abstraction of a new component, for example a button: .btn { }. This block should be thought of as a parent. Child items, or elements, can be placed inside and these are denoted by two underscores following the name of the block like .btn__price { }. Finally, modifiers can manipulate the block so that we can theme or style that particular component without inflicting changes on a completely unrelated module. This is done by appending two hyphens to the name of the block just like .btn--success.

The markup might then look like this:

                
                  <a class="btn btn--lg btn--success" href="http://htmlstream.com/">
                    <span class="btn__price">$9.99</span>
                    <span class="btn__text">Subscribe</span>
                  </a>
                
              

Why BEM?

  1. If we want to make a new style of a component, we can easily see which modifiers and children already exist. We might even realize we don't need to write any CSS in the first place because there is a pre-existing modifier that does what we need.
  2. If we are reading the markup instead of CSS, we should be able to quickly get an idea of which element depends on another (in the previous example we can see that .btn__price depends on .btn, even if we don't know what that does just yet.)
  3. Designers and developers can consistently name components for easier communication between team members. In other words, BEM gives everyone on a project a declarative syntax that they can share so that they're on the same page.

Benefits

Modularity

Block styles are never dependent on other elements on a page, so you will never experience problems from cascading.

You also get the ability to transfer blocks from your finished projects to new ones.

Reusability

Composing independent blocks in different ways, and reusing them intelligently, reduces the amount of CSS code that you will have to maintain.

With a set of style guidelines in place, you can build a library of blocks, making your CSS super effective.

Structure

BEM methodology gives your CSS code a solid structure that remains simple and easy to understand.