CSS: Isolation vs Abstraction

CSS: Isolation vs Abstraction

Total Isolation

This comes as the result of the global nature of CSS where things are leaky and thus component-based UI architectures find it difficult as cascading and global CSS causes leaks in styles across the components. For example:

<!-- Heading1: Component file; applies styles inside itself. -->
<h1>Some heading</h1>
<style>
    h1 {
        font-size: 32px;
        font-weight: bold;
    }
</style>
<!-- 
 The style inside of Heading1.component.js leaks out to global affecting
 all the h1 tags.
-->

Due to the global nature of CSS, h1 which may be inside the Heading1 component has its own style but due to the global scope of CSS, it leaks out to all h1 on the page. The component style is not scoped to the component itself thus giving birth to solutions like BEM, CSS-in-JS, and CSS Modules, which try to solve this problem by applying styles to scoped class names. For example:

<!-- With BEM Naming convention makes sure that styles are scoped -->
<div class="card">
    <div class="card__title">Title</div>
    <div class="card_actions card__actions--hover">actions</div>
</div>
<style>
    .card {
        width: 100%;
        padding: 16px 24px;
        display: flex;
        flex-direction: column;
    }
    .card__title {
        font-size: 16px;
        font-weight: 600;
    }
    .card_actions {
        display: none;
    }
    .card_actions--hover:hover {
        display: flex;
        flex-direction: row;
        justify-content: flex-end;
    }
</style>

Other solutions like CSS-in-JS solve issues by creating a unique class name, you can read more about it here in “Why CSS-in-JS?” With any such solution made for isolation, there are repetitions of rules seen that do add to size but it also ensures that scope styles and prevents unintentional leaking and we should be assured that modern bundlers are smart and will only ship styles required by the page. Be mindful that CSS growth does happen in a total isolation approach.

Total abstraction

This embraces the global nature of CSS by creating generic, global, and reusable classes called utility or atomic classes. The solutions like tailwind focus on using utility classes for styling and has their own build system for mitigating bundling and order issues. Each utility class remains in code forever and the smart bundlers shake off unused utility classes at build time, this makes sure the rise of CSS in the code is slow as their are utility classes covering most of the declarations and making it reusable so the growth of CSS is slow. For example:

<div class="w-full py-4 px-6 flex flex-col">
    <div class="text-base font-semibold">Title</div>
    <div class="hidden hover:flex hover:justify-end">actions</div>
</div>
<style>
    <!-- utility classes -->
    .w-full { width: 100%; }
    .px-6 { padding-left: 24px; padding-right: 24px; }
    .py-4 { padding-top: 16px; padding-bottom: 16px; }
    .flex { display: flex; }
    .flex-col { flex-direction: column; }
    .text-base { font-size: 16px; }
    .font-semibold { font-weight: 600; }
    .hidden { display: none; }
    <!-- hover:flex is written as .hover\:flex -->
    .hover\:flex:hover { display: flex; }
    .hover\:justify-content { justify-content: flex-end; }
</style>

The above example shows how utility classes are small declarations of a rule that can be composed in an infinite number of ways to achieve many different styles without causing repetitions.

Middle ground

The hard truth is that there is no middle ground, these two are on the opposite sides of the same axis and you cannot choose a middle ground for them. Even if you try your best you will not be able to achieve a middle ground; as the team grows there is always some dev there that will break your well-defined architecture and cause a leak or your CSS will grow or specificity wars will.

We should be hopeful though as efforts are being made to have a middle ground, one such effort is by stylex a Facebook which they presented in React conf and I’m waiting for it to be made open-source to enjoy best of the both worlds.

Did you find this article valuable?

Support Aniket Jha by becoming a sponsor. Any amount is appreciated!