Skip to content

What is Modular CSS?

Modular CSS - Cover

Depending on the complexity of your application, the stylesheets can be hellish to keep track of and update. Thankfully a collection of principles called modular CSS exist, which helps us write more maintainable and readable code. Modular CSS is just a way to break the styles up into component parts and avoid writing special CSS that is used only in one spot.

We can reuse those individual parts in different contexts, which helps us standardize our code. Additionally, by having our code standardized we are making sure that the CSS does not behave unexpectedly. In modular CSS (especially when using a library or framework that breaks up the page into different components) we can reuse and combine our smaller modules in any way we want to create a more compound application. Modularity as a concept isn’t new in software engineering, but just recently, as modern pages have gotten larger and more complicated it found its use in CSS.

We can use CSS selectors to target different elements in order to encapsulate them.

Encapsulation is used to hide the values or state of a structured data object inside a class, preventing direct access to them by clients in a way that could expose hidden implementation details or violate state invariance maintained by the methods.

Wikipedia

Basically – encapsulation is a mechanism which groups data together in order to create an object with a common theme or structure. That object is then invisible to the outside world.

Base Styles in Modular CSS

Base (or global) styles are the styles at the beginning of a stylesheet that set useful defaults for basic HTML elements like <a> tags, headings, etc. or apply opinionated resets like the popular box-sizing reset.

Tailwinds

Generally, we always should define a set of global rules that should apply to the whole page.

Base styles define the default styling for a certain element (or a page) in all basic occurrences. Base styles lay our groundwork for the modular styles that we will create later on.

@import url("https://fonts.googleapis.com/css2?family=Squada+One&display=swap");

:root {
  box-sizing: border-box;
}

body {
  font-family: "Squada One", cursive;
}

Our base styles usually include heading sizes,default font and link styles, default margins and paddings, and basic colors. Base styles should be generic, and should consist only of styles that should be applied on most or all of the pages. They provide the global look but they are easy enough to override if neccessary later on.

Because base styles are stable enough on their own we will rarely change them.

A simple module

We can create a simple button.

  <button class="button">
    Basic
  </button>
.button {
  width: 280px;
  height: 70px;
  font-size: 22px;
  font-weight: bold;
  color: white;
  border: none;
  background-color: #28a74a;
  border-radius: 10px;
  border: 1px solid #386944;
}

.button:hover {
  background-color: #386944;
}

Nothing special going on here. We simply created some default styling for a regular button, which we will turn into a module. The first thing that we did is that we gave it a unique name – in our case button. We can use this module on any page in which we need a basic button. Additionally, we can now reuse these styles to give users some feedback regarding the page or the form they are currently on

We will reuse this button everywhere where we would need it, providing a clear, consistent UI for the users, having visual consistency, but also making the coding process easier for the developers by having less repetition.

So we have created a consistent experience, but we also opened the door for possible changes to our elements by adding variations to our module.

Module variations

We might want to change our button styles under different circumstances. We can, depending on the context of use create buttons that distinguish a successful or unsuccessful action, or buttons that are more important than others (which are visually bigger), and we can do this by defining and creating modifiers.

Modifiers can be created by creating a new class name that begins with the module’s original name. For instance, an error modifier for the button module might be button--error. By indicating first the module name, we make sure that this class belongs to the button module (again, making the stuff easier for the developers).

.button--success {
  background-color: #28a745;
  color: white;
}

.button--warning {
  background-color: #ffc107;
  color: white;
}

.button--error {
  background-color: #dc3545;
  color: white;
}
Modular CSS – Basic Modules

Modifier styles are not redefining the entire module, they only override the parts they need to change. For the cases above they change the color of the text and the border.

To use a modifier we add both the main module class and the modifier class as shown next, which will apply the modules default styles and then allows the modifier to override where needed.

  <button class="button button--success">
    Success
  </button>
  <button class="button button--warning">
    Warning
  </button>
  <button class="button button--error">
    Error
  </button>

Additional Module Variants

We can also create large and small buttons.

Now we have modifiers to choose from in order to change the size of the button based on its importance or even to add color. We can even combine different modular variations to create hybrid elements.

 <button class="button button--small">
    Small
  </button>
  <button class="button button--large">
    Large
  </button>
  <button class="button button--large button--success">
    Large Success
  </button>
.button--small {
  width: 200px;
  height: 50px;
  font-size: 20px;
}

.button--large {
  width: 300px;
  height: 90px;
  font-size: 30px;
}
CSS Modules - Some More Variations
CSS Modules – Some More Variations

Some more tips

Modules should only be responsible for one thing only. For example, our button module is only responsible for creating a button. We can have component-related, style-related, or layout-related modules.

When creating a module always ask yourself what is the responsibility of the module? The module should have only one responsibility. If we use ‘and’ when describing our module then we might have more than one responsibility.

Often we use some preprocessor like Sass or ESS to separate CSS files, which lets us better organize our styles. If we used any preprocess we would extract our button module and put it in its own appropriate file. Later when using this module we would @import our module by writing @import 'buttons';.

Final Words

In the past couple of years, some really popular modular frameworks emerged that help us implement the concept of modularity in our pages. For example, OOCSS proposes that CSS objects are reusable visual patterns, BEM (Block, Element, Modifier) tries to break web interfaces into components and SMACSS tries to categorize CSS rules and generate patterns from those rules.

I highly advise you to check these modular methodologies for gain more insight into modular CSS.

Here is our our codepen for this article:

See the Pen Modular CSS by Mehmed (@brachika) on CodePen.

Please check other blog posts on thedukh.com. For more CSS articles click on one of the links below: