A A A A
← Back

Manuel Morandi

Componentization with Object-Oriented CSS

April 30, 2025

Styling, with its unpredictable nature and difficulty in scaling or changing, can often be a source of frustration. However, several CSS architectures have emerged over time, offering relief by making styling more manageable and less painful.

One of them is Object-Oriented CSS (OOCSS). This approach attempts to make code more reusable by making all style classes available to different components. The core idea is to divide each element on the page into two distinct parts: skin and structure.

The skin is the outermost layer of our body. It serves an aesthetic purpose, defining the general visual style for its children. In the context of OOCSS, the skin is the part of a component that deals with its appearance, including colors, borders, and other visual attributes. The structure, on the other hand, refers to what is inside the skin. It sets the specific shape and characteristics of the component. In OOCSS, the structure is the part of the component that deals with its layout and positioning, such as flexbox properties or grid settings. This separation allows us to build reusable styling templates in the skin layer. Just like character skins in a video game, we can change the appearance of a component without affecting its content or functionality.

Now, as we enter the component’s structure, we should make another division, differentiating the container from its content. The container will set the layout or distribution of its contents. We use it to set the padding, margin, size, and other styling options for the information and interactive parts displayed to the user. It will be the parent component of several smaller areas. These smaller, more specific sections can be basic elements, like paragraphs, images, or input, or more complex components that might have their own skin and structure division, making their implementation somewhat recursive.

Let’s take a look at an example:

And here’s the corresponding CSS:

This component, with its clear separation of skin, container, and content, makes it easy for you to make changes. Whether it's a change in color, layout, or content, you can focus on just one area, leaving the rest unchanged. This level of granularity provides a clear separation of concerns, making the component easy to work with and reason about.

If we want to make this component green, with straight corners and a drop shadow, we’ll simply use a different skin, leaving the structure unchanged. For instance, we could create a 'green-rectangular' skin class with a green background color, no border radius, and a drop shadow. If we want to display the content in a column instead of a row, just a small class change in the container will do the trick. We could create a 'column-layout' container class with a flex-direction property set to column. Similarly, the content, which might change, can do so freely, since it will be agnostic to its parent components that define higher-level options.

As a general rule, if your component needs 12 nested divs to look right, maybe it’s not a component, it’s a cry for help. That’s your codebase praying to be refactored. Make sure to structure your styles intentionally and avoid unnecessary nesting in your markup. Don’t stack elements like you’re playing a game of frontend Tetris; take the time to organize things properly.

By treating your components as a mix of layout (structure) and appearance (skin), and nesting reusable content inside well-scoped containers, you can tame component complexity before it becomes a problem. This approach helps manage abstraction levels across components, encourages reuse, and leads to a clearer, more maintainable design system.

ABOUT Manuel Morandi

Software Engineer @ Silver River Software,
also a Heavy Metal fan and wears great t-shirts.