Analysis of common CSS design patterns

oocss

Object Oriented CSS is designed to write high reusable, low coupling, and high scalability CSS code.

OOCSS defines styles in an object-oriented way, separating abstraction (structure) from implementation (style) and separating common code.

When defining a reusable component library, we only create the base structure (HTML) and the base class name. We should not create style rules like border, width, height, background, etc. This makes the component library more flexible and extensible. Component libraries have different styles in different environments. Adding styles to a component library without distinguishing its structure and style will make it a specific component library that is difficult to reuse.

Here is a basic library creation style:

. The metadata {the font - size: 1.2 em; text-align: left; margin: 10px 0; }.metadata{font-size: 1.2em; text-align: left; margin: 10px 0; /* New style on base component */ width: 500px; background-color: #efefef; color: #fff; }Copy the code

This turns the underlying component metadata you created earlier into a specific component, making it harder to reuse in other scenarios.

Separate the container from the content. Separate the container from the content so that the content can be applied to any container.

#sidebar h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: .8em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}
Copy the code

Above, we have defined a style whose ID is H3 in sidebar, but we find that the style of H3 in footer is basically the same, only some are different, so we may write the style like this:

#sidebar h3, #footer h3 { font-family: Arial, Helvetica, sans-serif; font-size: 2em; line-height: 1; color: #777; text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px; } #footer h3 {font-size: 1.5em; text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px; }Copy the code

We might even have written the style in a worse way:

#sidebar h3 { font-family: Arial, Helvetica, sans-serif; font-size: 2em; line-height: 1; color: #777; text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px; } #footer h3 { font-family: Arial, Helvetica, sans-serif; The font - size: 1.5 em. line-height: 1; color: #777; text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px; }Copy the code

We can see an unnecessary duplicating style in the code above. OOCSS encourages us to think about what styles are common to different elements, and then take those common styles out of modules, components, objects, etc., so that they can be reused anywhere, regardless of a particular container.

<div class="header theme"></div>
<div class="footer theme"></div>
.header {
  height: 100px;
  width: 100px;
}

.footer {
  height: 200px;
  width: 100px;
}

.theme {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}
Copy the code

Finally, the separation of structure and style is realized, which improves the reusability of style code

SMACSS

Scalable and Modular Architecture for CSS Scalable and Modular Architecture for CSS Scalable and Modular Architecture for CSS Scalable and Modular Architecture for CSS

  • Base

  • Layout

  • Module

  • State

  • Theme

SMACSS defines a CSS file organization mode. It divides CSS files into functional modules to make them more structured and maintainable.

  1. Base

Base is the default style and is the Base style setting for individual element selectors (including their attribute selectors, pseudo-class selectors, child/sibling selectors), such as HTML, body, input[type=text], A :hover, etc.

html, body {
  margin: 0;
  padding: 0;
}

input[type=text] {
  border: 1px solid #999;
}

a {
  color: #039;
}

a:hover {
  color: #03C;
}
Copy the code

CSS Reset/Normalize is a Base Rule application.

Note: Should not be used in base styles! important

  1. Layout

Style Settings for page layout elements (primary and secondary components of the page architecture), such as header, navigation, footer, sidebar, login-form, etc.


.header, footer {
  margin: 0;
}

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9999;
}

.navs {
  display: inline-block;
  margin: 0 auto;
}
Copy the code
  1. Modules

Settings for common component styles, such as Dropdown, Tabs, Carousels, Dialogs, etc.


.dropdown, .dropdown > ul {
  display: inline-block;
  border: 1px solid #283AE2;
}

.dropdown li:hover {
  background-color: #999;
}

.tabs {
  border: 1px solid #e8e8e8;
}

.tabs > .tab--active {
  border-bottom: none;
  color: #29A288;
}
Copy the code
  1. State

Style modifications to components, modules, elements, etc. that represent behavior or state, such as hide, show, IS-error, etc.


.hide {
  display: none;
}

.show {
  display: block;
}

.is-error {
  color: red;
}
Copy the code
  1. Theme

The setting of the overall layout style of the page is a kind of skin, which can overwrite the default style of base, layout and so on in a specific scene.


.body--theme-sky {
  background: blue url(/static/img/body--theme-sky.png) repeat;
}

.footer--theme-sky {
  background-image: blue url('/static/img/header--theme-sky.png') no-repeat center;
}
Copy the code

BEM

BEM is the foundation of my approach. If you’ve never heard of BEM before, it stands for Block, Element, and Modifier. When you first touch it, it looks so ugly.

.block { /* styles */ } 
.block__element { /* styles */ } 
.block--modifier { /* styles */ }
Copy the code

When I first saw BEM, I hated it and didn’t even give it a chance. I don’t remember what drove me to try BEM, but I now know how powerful it can be. Let me explain fully what BEM is (with my own interpretation, of course).

  1. block

A block is a component. This is a bit abstract, so let’s learn by example.

Suppose you are creating a contact form. In this case, the form can be a block. In BEM, blocks are written like the name of the class, as follows:

.form { /* styles */ }
Copy the code

The reason BEM uses.form instead of

elements is because classes allow unlimited reusability, and even the most basic elements can change style.

Buttons are a good illustration of the different styles of blocks that can be contained. If you set the background color of the

button { 
    background-color: red; 
} 

.something button { 
    background-color: blue;
}
Copy the code

If you have a button of the.button class, you can choose whether to use the.button class on any

.button { 
    background-color: red; 
}

.button--secondary { 
    background-color: blue;
}
Copy the code
  1. The element

An element is a child node of a block. To indicate that something is an element, you need to add __element after the block name. So, if you see a name like that, such as form__row, you will immediately know that the.form block has a row element.

<form class="form" action=""> <div class="form__row"> <! -... --> </div> </form> .form__row { /* styles */ }Copy the code

The BEM element has two advantages:

  • You can keep CSS priorities relatively flat.
  • You immediately know what is a child element.

To explain the above, consider the alternative of using two separate classes (many frameworks do this). You might use something like this:

<form class="form" action=""> <div class="row"> <! -... --> </div> </form> .form .row { /* styles */ }Copy the code

If you use BEM elements, you can use a selector with priority 10 instead of 20 to style.form__row. In addition, you can immediately tell (whether in HTML or CSS) that.form__row is a child node of.form.

  1. The modifier

Modifiers are flags that change the appearance of a block. To use a modifier, add a –modifier to a block.

Continuing from the button example above, the modified button will be named.button–secondary.

In traditional BEM, when you use modifiers, you should add blocks and modifiers to the HTML so that the.button style is not overridden in the new.button–secondary.

<button class="button">Primary button</button> <button class="button button--secondary">Secondary button</button> Button {padding: 0.5em 0.75em; background-color: red; } .button--secondary { background-color: green; }Copy the code

Note why there is no need to redeclare the padding in.button–secondary because it is already declared in.button. This is great because BEM ensures that you write clean CSS without having to do a lot of work.

ITCSS

Modern ways of organizing CSS often fall back on modularity or CSS objects to construct abstract ideas.

The new idea of inverted triangle CSS is a layered approach based on the specificity and importance of CSS attributes. This is a little-known approach compared to SMACSS and OOCSS – although both can be used in conjunction with ITCSS.

Because ITCSS is primarily proprietary, there is no detailed rulebook for its usage. We can only use a specific set of principles. The author talks about them in the video below.

By default, ITCSS uses the same principles as OOCSS but based on more specific separations. So, if you’re already familiar with OOCSS, consider trying out this unique alternative CSS architecture.

Here are the biggest benefits of using ITCSS:

  • Page objects can be split into their own CSS/SCSS files for reusability.
  • It’s easy to copy/paste each object and extend it to other projects.
  • The exact depth is up to you.
  • There is no setup folder structure, and no preprocessing tools are required.
  • You can combine concepts from other methods, such as CSS modules, to create your own hybrid workflow.

The directional flow from the flat top to the tip of the inverted triangle indicates an increase in specificity. The focus on reducing specificity makes it easier to reuse classes multiple times in a site.

Each sub-part of the triangle can be treated as a separate file or group of files, although you don’t have to code that way. It is more meaningful to Sass/Less users because of the import capability. Just think of each section as a way to break up and organize reusable CSS code.

Let’s take a quick look at each part of the inverted triangle from top to bottom.

  • Settings – Preprocessor variables and methods (no actual CSS output)
  • Tools – Mixins and functions (no actual CSS output)
  • General – CSS reset, which may include Eric Meyer’s reset, normalize.css or your own batch of code
  • Element – A single HTML element selector with no classes
  • Object – a page structure class that usually follows the OOCSS approach
  • Component – Aesthetic class that sets the style of any page element and all page elements (usually used in conjunction with the structure of the object class)
  • Trumps – The most important style, used to override anything else in the triangle

Each layer of the inverted triangle can be adjusted to suit your needs. Therefore, if you do not use CSS preprocessors, there is no setup or tooling layer required.

It should be used flexibly in actual projects.

ACSS

ACSS uses a tight library of class names. These class names are often abbreviated and separated from the content they affect. In an ACSS system, you know what class names do; But there is no relationship between class names (at least not the ones used in style sheets) and content types, that is, one class for each style, also known as atomic class CSS.

.bg-a {
  background-color: #a6d5fa;
}
.bg-b {
  background-color: #aedbaf;
}
.bg-c {
  background-color: #ffe8a5;
}
.bg-d {
  background-color: #faaaa4;
}
Copy the code

Second, the use of CSS design pattern in UI library analysis

  1. Element UI

    ITCSS + BEM

  2. Ant Design

    ITCSS + BEM

  3. Bootstrap

    ITCSS + OOCSS

  4. Tailwind CSS

    ACSS

conclusion

  • CSS design patterns are ubiquitous in popular UI libraries
  • We should actively implement our own mix of CSS design patterns in our projects to optimize the CSS architecture of our projects
  • It is recommended to use ITCSS architecture and BEM naming convention to organize ACSS basic style for subsequent use