Go to blog

CSS encapsulation for component development

of reading
Massimo Artizzu
thumbnail

We have chosen to talk about CSS encapsulation because, every day, we increasingly come across the need to program in a scalable, modular way. Therefore we need structural practices to allow all types of projects to be developed following clear paths that can be adapted to all needs

For over 20 years, CSS language has been a fundamental point for the development of websites and mobile web/hybrid applications, defining the presentation aspect of the interface, which together with the contents (delegated to HTML) and interactivity (JavaScript) constitute the fundamental parts of the front-end of an application or website.

CSS has always been a declarative language, simple to use and with immediately visible results. But just because it is simple, it doesn’t mean that it is also easy. In particular, the development of the CSS part very quickly presents scalability and code maintainability problems, which risk bringing the project to a stop in the absence of rules and guidelines to follow.

Surviving with CSS

Over the years, a series of basic principles have become established for the development of CSS style sheets, that all aim to solve the main problems that web developers have highlighted over the years. The most established principles include OOCSSSMACSS and the more well-known BEM.

Concentrating on this latter convention, we are naturally led to develop our applications in components (“blocks” of initials), i.e. independent interactive elements within the interface. If we wanted to create a date-picker, the related style sheet would look like this:

.date-picker { ... }
.date-picker__date-head { ... }
.date-picker__day { ... }
.date-picker__day--current { ... }
...

And it would be used with an HTML structure of this kind:

<table class="date-picker">
  <thead><tr>
    <th class="date-picker__date--head">Lun</th>
    ...
  </tr></thead>
  <tbody>
    <tr><td class="date-picker__day">28</td>...</tr>
    ...
  </tbody>
</table>

The exclusive use of classes in the style declarations, with names that are often very long and therefore not very legible, is to be noted. There is a pledge to be paid for maintaining the CSS code, which is reusable and has effects limited to the component to be styled. In fact, the aim is to create a naming convention of CSS classes that are possibly unique among all those defined within the page.

Web component approach

However, over recent years, there has been an effort to solve the age-old problem of the “globality” of the CSS style rules. The decisive push came from the conception of Web Components, a set of APIs that allow “custom”HTML elements to be created, with their own internal functionality, an actual “life cycle” and, above all, their own style sheet, whose influence remains isolated (“encapsulated”, in technical jargon) within the defined element and will not have any effect on the rest of the application.

Based on this development philosophy, the objective will no longer be to create a global style sheet for the application, constructing it piece by piece and taking care not to have overlapping parts, but to create many styles limited to their own component and that only when put together provide a complete representation for the application.

The result will be small and modular style sheets, as we were used to with BEM, but with a much lighter naming convention. This derives from the fact that we do not need to create classes with a long and (hopefully) unique name, as the declarations of our module will only have an influence for our component.

So, to look again at the previous example, the resulting style sheet could be reduced to this:

table { ... }
th { ... }
td { ... }
.current { ... }

And the HTML structure would also be much lighter:

<table>
  <thead><tr>
    <th>Lun</th>
    ...
  </tr></thead>
  <tbody>
    <tr><td>28</td>...</tr>
    <tr>...<td class="current">4</td>...</tr>
    ...
  </tbody>
</table>

So, what was considered a taboo until a short time ago, such as creating composite selectors from just a tag name, or using short and generic class names, has become possible again due to the encapsulation of the styles within the component. Also practices such as using IDs in the selectors or the !important modifier now make sense.

The fact is that development in components allows us to concentrate on limiting our attention to just the component that we are developing, and the encapsulation of styles is the last piece of the puzzle in this development method.  So, we will no longer have a logical and physical separation between template, functionality and presentation, but all these aspects will be considered as a single entity, i.e. the component.

Local style and global theme

What can be a bit disorientating with this type of development is that developing a look and feel that is consistent with the application does not appear immediate. But the fact is that it is best to get used to adopting interface development with minimal intrusion of styles from the application into the components.

However, even if the need to style the components is minimal, it does not completely disappear. But what must be clear is that it is the component that controls what may or may not be styled from the outside. That is to say that the component must offer a parametric interface to be styled within the application, e.g., by showing a parameter to decide the background colour, but not to determine the spacing of the text.

This interface can be shown through simple component attributes, or through the CSS custom properties. Other solutions are still being considered by the CSS standard governance bodies.

Components and framework

The Polymer framework that explicitly takes advantage of the web components, proposes this approach, allowing the aforementioned parts to be defined in a single file (with the caveat by which, from version 3, importing custom components will change the use of HTML imports to ES2015 modules).

Likewise, although not natively based on web components, Vue.js also makes this possible. The Angular guidelines, on the other hand, suggest a consistent naming convention among the files that define a component and recommend dedicating one folder to each of them.

The other “maximum weight” between front-end development libraries, i.e. React, is essentially “not opinionated” in relation to adopting styles, therefore the developers are free to use what they want. This has led to the proliferation of packages for styling components, such as Styled ComponentsCSS Modules and so on, but all based on the concept of the encapsulation of styles.

What to expect

According to the web development community, the encapsulated style approach is a step in the right direction, and relieves programmers from the task of emulating this methodology with BEM or other conventions. Fewer rules to follow also means less possibility to make mistakes.

In conclusion, the future road is clear but will reserve other new features for the development of web applications (or based on web technologies) that are increasingly complex.

Massimo Artizzu
Written by
Massimo Artizzu

Educated in Mathematics, but professionally adopted into programming, a passion I had since I was little. Puzzle and origami lover, rugby player for fun.