Modular CSS

Modular CSS. It sounds like a dream, but the truth is, part of the work has already been done, and it seems we are on the right track to achieve it. Today’s article tells the story of CSS from the perspective of the pursuit of creating modular components.

Modułowy css

From this article you will learn:

  • What is encapsulation?
  • How did CSS methodologies aim to fix CSS problems?
  • What is JSSS, and what impact did it have on the development of CSS-in-JS?
  • What is Interoperable CSS?
  • How do CSS modules work?

Work with styles looks the same usually. At the beginning we have a lot of idea, motivations and declarations how to make them great. Previous projects gave us much experience, but css styles finally weren't best. Why? Because time for the project was limited. Because requirements changed. Because client changed the concept. Because bussiness realized that project is already overestimated and time for improvements and quality should be cutted. So now we start from the scratch, we create new files and this rollercoaster takes us to new adventure - sadly same track. To be more specific, project probably was ok, but our satisfaction from code quality weren't so. And it always wouldn't be...

The problem with CSS is that it’s too flexible. It allows us to organize our code as we want, without any architectural restrictions. All we need is a few basic rules, and we can start coding (sometimes even without them). Of course, the programming world is looking for solutions that could transform CSS into something more predictable and less prone to errors. And yes, we’ve even found the answer: modules.

I’ve already written about the concept of modules. On my blog, there is an article about modules in JS. According to the most common definition, a module is an independent unit of an application with a specific task to accomplish. Modules do not have direct and uncontrolled impact on other modules, nor do they interfere with the functioning of others. Of course, a module can be dependent, but this dependency usually arises because the module is waiting for data from other modules. One of the key features of modules is their encapsulation.

Encapsulation is a term most commonly associated with object-oriented programming. In short, it means that a specific block of code is protected from external interference. In other words, external modules cannot accidentally or intentionally alter the behavior of the encapsulated module. A more visual way to describe this would be to imagine placing our code inside a “capsule” that shields it from the outside world.

So, if the key to “fixing” CSS is the concept of modules — why isn’t it that simple? It all comes down to the fact that styles in CSS apply globally across the entire web application. There are no built-in mechanisms that encapsulate our code or its parts by default. But are we really sure about that? To paraphrase a classic: hold my beer. Let’s take a look into the past.

BEM, OOCSS and Other Methodologies

Some members of the IT community have come to realize that CSS-in-JS still isn’t the perfect solution. Writing styles as JavaScript objects strips us of many default features that come with plain CSS. Sometimes, it even leads to bad practices—like using the !important declaration to override inline styles (since some CSS-in-JS approaches inject styles directly as inline styles into the HTML document).

For many years, the JavaScript world has been moving toward building applications based on component architecture. From the perspective of JavaScript code, creating and connecting multiple components is not a big challenge. CSS, although it tried to follow that direction, couldn’t quite keep up—mainly due to the lack of native language support. The solutions that began to emerge were mostly based on conventions—like BEM—rather than features built into the language specification.

In 2015, work began on ICSS (Interoperable CSS) — an extension of the CSS specification. Its main goal was to allow scoping styles to the component level, while still enabling access to global CSS selectors. Essentially, ICSS introduced two CSS pseudo-selectors: :import and :export. Their main purpose was to allow styles to be exported and then imported in a way that makes them available as an object, with local aliases used as its properties. A local alias is simply a name consisting of letters and numbers.

These approaches aimed to solve the problem of CSS code encapsulation. They brought a lot of satisfaction to developers, even despite the community’s complaints about long and complex CSS class names.

A Look Back

In 1996, Netscape proposed an alternative for styling websites – instead of using CSS, they introduced JSSS (JavaScript Style Sheets). The concept of JSSS was based on the idea that styles would be created using JavaScript objects. In 1997, it was officially implemented. Netscape promoted this approach as more efficient, claiming that it allowed full utilization of JavaScript’s capabilities as a programming language for calculations and style conditionality. However, JSSS lacked access to complex CSS selectors. If this concept had survived, it’s possible that the issue of CSS modules would have been resolved by integrating modules into JS. Unfortunately, that didn’t happen – no browser (besides Netscape Navigator) adopted JSSS into their codebase.

Można by powiedzieć, że koncepcja umarła śmiercią naturalną i już nikt do niej nie wróci, ale tak się nie stało. Pomysły wykorzystania JS jako sposobu na pisanie styli wracały jak bumerang. Tak też narodziła się koncepcja CSS-in-JS. CSS-in-JS to zbiór założeń, które mają na celu pomóc pisać kod styli, tak aby unikać złożonych selektorów czy rozwiązać problemy: braku modułów, niejawnych zależności, wszechmocnych selektorów czy tak zwanych zombie-classes (martwego kodu, nieużywanego nigdzie, który trudno zlokalizować i usunąć). Przez dłuższy czas CSS-in-JS uchodziło za podejście bliskie idealnemu, na jego bazie powstało wiele nowoczesnych bibliotek, takich jak emotion, styled-components czy rozwiązania JSS.

CSS-in-JS bazuje przede wszystkim na obiektach JavaScriptowych. Enkapsulacja osiągana jest za pomocą hashowania styli. Do każdego utworzonego bloku kodu generowana jest unikalna klasa css, która powiązana jest ze stylami przypisanymi do danego komponentu. W kodzie HTML powstaje nowy element <style> zawierający informacje o tym fragmencie kodu. Poniżej napisałem jak mogłaby wyglądać bardzo prosta implementacja takiego podejścia.

Share this article:

Comments (0)

    No one has posted anything yet, but that means.... you may be the first.

You may be interested in

If this article interested you, check out other materials related to it thematically. Below you will find articles and podcast episodes authored by me, as well as books I recommend that expand on this topic.

Nowoczesny CSS by Mateusz Jabłoński
Podcast
01 April 2023

Nowoczesny CSS

W dzisiejszym odcinku rozmawiamy o CSSie: jego przeszłości, teraźniejszości i przyszłości. Staramy się połączyć nasze wspomnienia z początków naszej kariery z tym, jak style pisze się dziś.

Posłuchaj
Font Families by mediaphotos
Article
2023-03-08

Font Families

They are everywhere. We surround ourselves with them from every side - there are so many of them that we often stop noticing how different they are. Today we will talk about typography, fonts, and type.

Read more
Magia Pixel Perfect by kudou
Article
2022-08-11

The Magic of Pixel Perfect

In the days when we dialed into the Internet, an approach was born that defined web development for many years. Today it is not quite as popular, but in my opinion it is still worth knowing and understanding. Let's talk about the magic of pixels.

Read more

Zapisz się do newslettera

Bądź na bieżąco z nowymi materiałami, ćwiczeniami i ciekawostkami ze świata IT. Dołącz do mnie.