How to structure, scale and maintain CSS Methodologies that helps with styling applications 11. 03. 2022

A little bit of history

Space Jam

How we style web sites

Layout

Tables for everything

Today, we have layout properties ➔ Float (before flexbox come into game) ➔ Flexbox ➔ Grid ➔ Subgird ➔ etc.

So, CSS is improving every day

Writing good CSS is hard “CSS: the only language that is both so easy it’s not worth learning but also so hard that it’s not worth learning.”

So why is CSS so hard to maintain? Why? ➔ Deep nesting of selectors and high specificity ➔ Nesting Hell ➔ Cascade ➔ Inheritance ➔ Misunderstanding of how CSS works

Let’s take a quick simplest example https://codepen.io/ondrejko/pen/xxpKRyo

That means that order in the resulting file matters! ≠

Can you check for e.g. selector order in the resulting CSS file?

Because there is thousands of lines Current Dashboard CSS file with 8200 line of code:

Deep nesting of selectors and high specificity HTML: CSS:

The link color has not changed What is in CSS and what blocks me?

What are the options? Selector overload (or refactor code or use !important) Such a selector can be really hard to modified

Nesting Hell

You would say, that is not so bad, but.. Output in style.css:

“Nesting selectors” is a good friend but a bad lord It is alway good approach to stay simple as possible

Takeaway: Avoid nesting as much as possible If you need to nest selectors in the third level, something is wrong with design/usage of the component and we call it “Design smell”.

Cascade

We often end up like this

Our current Dashboard

What we can do? Use some good approaches

ITCSS

ITCSS

ITCSS Settings — Space for preprocessors with variables such as colors, design tokens, typography, grid. Tools — Layer with mixins, functions, media queries. Generic — Here we insert styles for third party libraries such as normalize, reset or any others Elements — Selectors for bare HTML elements such as h1, p, article, a Objects — Class definitions for layout, grid, indentation - reusable non-decorative styles. Components — Specific components across the project - accordion, buttons, breadcrumbs, tooltip. Utilities — Class utilities that are designed to affect one particular CSS property and are in most cases written with the utmost importance. Utilities and helper classes with ability to override anything which goes before in the triangle.

ITCSS structure is great for any project and it is easy to use

BEM

What is important to realize? “The more experienced developer you are, the more you prefer code readability to efficiency”

Why BEM? ➔ Find and write CSS rules in a large project is easy. ➔ Organize rules for media queries and reusable libraries. ➔ Reduce the complexity and nesting of your CSS selectors. ➔ Have a consistent approach to positioning elements on the page. ➔ Have a consistent approach to changing the look of HTML. ➔ Have a consistent approach to composing larger components from smaller components. ➔ A unified approach that is easy to explain to newcomers ➔ It keeps the world of CSS safe from mess and clutter.

BEM is G. R. E. A. T

G. R. E. A. T G for Global BEM is one of the most recognized naming conventions out there. So if you are introducing a new team member to your BEM project, there’s a good chance they already know the convention, which reduces initial friction and allows them to be productive since day 1.

G. R. E. A. T R for Readable Thanks to descriptive class names given to basically every element, the stylesheet is easy to read on its own. Not only selectors look better, they also work faster than deeply nested ones.

G. R. E. A. T E for Expandable As the specificity of CSS selectors is minimal, adding another variation is very simple. Single modifier class should be enough — no more ‘at least equal selector weight’ toil.

G. R. E. A. T A for Adaptable Sharing the philosophy of modularity, BEM naturally works fine with frameworks. Also, styling is independent of elements type and nesting, making it less prone to break when tackling with document structure.

G. R. E. A. T T for Tough There are only two hard things in Computer Science: cache invalidation and naming things. When you start following BEM (fully and honestly), you’ll probably find yourself struggling with it constantly. Paradoxically, it’s a good thing: ➔ finding proper block names makes the code clean and legible to others (your future self included) ➔ ➔ reusing existing blocks avoiding multi-level nesting makes you rethink document structure

Tailwind, and why I would consider not using it

Tailwind is good for

Quickly prototyping

Safety - there is nothing in design that is not in config

Small projects like personal sites, blog sites etc.

Tailwind is (IMHO) not good for large scaled projects - Styling and HTML are Mixed

It Takes Time to Learn (not necessarily a disadvantage)

Lack of Important Components (not so much components)

Components aren’t provided by default

Unreadable class names

It’s Inconsistent (items-: align or justify? content-: align or justify?)

It’s Difficult to Read

Really hard to do code reviews

You Can’t Chain Selectors

Tailwind Locks You Into the Utility CSS Paradigm

Tailwind Is an Unnecessary Abstraction

Tailwind, Dev Tools, and Developer Experience (Imposible create variants)

It’s Inconsistent items-: align or justify? content-: align or justify? justify-: content or items? align-: content or items?

It’s hard to read

<div class=”w-16 h-16 md:w-32 md:h-32 lg:w-48 lg:h-48”></div> <div class=”w-16 h-16 rounded text-white bg-black py-1 px-2 m-1 text-sm md:w-32 md:h-32 md:rounded-md md:text-base lg:w-48 lg:h-48 lg:rounded-lg lg:text-lg” > Yikes. </div>

It’s hard to read

More pleasure for eyes

You Can’t Chain Selectors

It’s Harder to Tweak CSS in Dev Tools ➔ It is hard to simulate styling in DevTools ➔ It’s Harder to Find Components in Dev Tools ➔ Recompiling HTML Is Slower Than Recompiling CSS

Tailwind Is Still Missing Some Key Features of CSS What will be in CSS specification soon? What is in working drafts? ➔ Container Queries ➔ :has() selector ➔ @when/@else rules ➔ Cascade Layers ➔ Subgrid ➔ Nesting