A presentation at CloudTalk - Front-End Talks in in Prague, Czechia by Ondřej Konečný
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
Small projects like personal sites, blog sites etc.
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