Back to Blog

CSS Styling in Component Structures

06
May
2021
Development
Component Structures for CSS Styling

CSS, the language that styles the web, generates debate with its global scope. In traditional CSS stylesheets, styles apply across an entire site or app. Over the years, naming conventions have emerged to help contain that chaos, like BEM or SMACSS. These aspire to create more modular systems and achieve scalable tech out of CSS properties when inherently it's not.

The focus on global style components intensifies as web dev takes firmer steps towards function components and modular design. The original composition separates concerns in HTML, CSS, and JS files. But more recent CSS framework integrations, like the styling React component, couple HTML and JS in duplicate files. This process is achievable by dividing by components and not by languages. As a result, teams can style, let's say, a component in React. Yet, it raises the question: how the style should fit into this structure?

CSS Component Styling Libraries

There are many styling libraries and systems to answer this question. We’ll look at some of the main ones with advantages over traditional CSS.

1. CSS with Sass Modules

One of the most popular CSS extensions is Sass. This extension has a degree of modularity, which allows for dividing stylesheets. As a result, these stylesheets get divided into several smaller ones. Many devs follow common structures to organize projects further. For instance, there is the 7-1 pattern.

At last, these files get combined into one stylesheet. To do so, it uses the @import feature. Further, this avoids risking naming conflicts. Saas made their next big step in 2019, replacing @important with @use and @forward. These new features define relations between files in a project. Not only does this removes conflicts. Also, it clarifies the dependencies' origins. For example, @use gives a namespace to imported features. This naming brings in styles from the buttons file, accessed in the following way:

@use 'buttons';
 $btn-color: buttons.$color;

2. CSS Modules

CSS Modules started in 2015, generating a global stylesheet with unique class names for each component. This build process creates .module.css and .js files for each component. Moreover, these CSS lines of code can use any class name, even repeating those in external CSS files. That’s possible because Modules transform CSS class names into unique ones. This method also avoids naming conflicts. Another bonus is that this unique naming still includes human-readable words. It facilitates finding and maintaining styles for developers. For example, if we have a file called box.css, a CSS selector, once compiled, will turn into something like the following. The result will be a unique selector with the file name, the class name, and a random hash.

.text {
 color: blue;
}
.box_text_j3xk {
 color: blue;
}

3. CSS with CSS-in-JS

CSS-in-JS is, as its name says, CSS written in JavaScript files. This method is mainly known for putting the most emphasis on modularity. Its process takes separated stylesheets out of the equation. In consequence, it allows styles to be set with reusable components. This approach has both strong supporters and detractors. There are various ways to manage this, depending on your system. At its most basic, styles apply straight to DOM elements. Yet, its primary use is to handle styling in a performant way and add different capabilities. The libraries have two main types: Styled Components and Emotion. These allow the creation of components in a CSS-like syntax via template literals. You can now use the <StyledSection> component:

const StyledSection = styled.section`
 text-align: center;
 margin: 0 2em;
`
render(
 <StyledSection>
  <h1>Hello World!</h1>
 </StyledSection>
)

Component libraries, such as Grommet and Rebass, offer prefab components. Accepting system properties often styles these libraries. With Rebass, you can style a box component declared in the JSX in the following way:

<Box
 p={5}
  fontSize={4}
  width={[ 1, 1, 1/2 ]}
  color='white'
  bg='primary'
/>

These libraries are likely to be the most comfortable for CSS purists. They can keep styles in the same file as the component or import them for a more traditional approach. For instance, you can create a folder for a Button component that has both index.js and style.js files. You can specify details such as border radius and font size there. One of the main advantages of CSS-in-JS is its fluid way of theme styles. This is possible by passing them via props and changing them according to their state. In Saas and CSS Modules, the workaround is applying class names with a basis on props. Installing Styled Components, it looks like this:

const Button = styled.button`
 background: ${props => props.primary ? "purple" : "white"};
 color: ${props => props.primary ? "white" : "purple"};
 `
render (
 <Button primary />
)

You can use Xstyled, a Styled Components and Emotion wrapper, for extra clean and organized syntax. If we have a value set for “primary” in our theme.js file, we can write:

import styled from '@xstyled/styled-components'
const Button = styled.button`
 width: 200px;
 height: 100px;
 background-color: primary;
 `
export default Button

What is the Best CSS Styling Choice?

This question still generates a hot debate nowadays. In this context, Saas is a superior technology. What's more, companies are investing vast resources in implementing it. Often, they fail to see the benefit of switching to a new model. With the introduction modules, Saas tackles some of the scoping issues. Before, these had developers considering other solutions.

For JS developers who were never in love with CSS, CSS-in-JS can be seen as a more “cool” tool. But, some truths make Styles Components (or Emotion) clear choices. For instance, Styles Components uses Javascript and compiler magic to achieve the same features that make Sass great. For instance, nesting, variables, etc. Further, it’s more readable than Sass for an average Javascript developer building a high-order component style. Still, it’s readable for UX and Front-End developers without much JS experience and includes automatic vendor prefixing.

There are several other options for CSS styling, like the Babel plugin. But this approach is not just a niche, tho: some big production projects use it! To name some extra build tools: Patreon, Target, Reddit, Autodesk, Atlaskit, Typeform, Vogue, and Coinbase rely on CSS Rule Components.

Conclusion

Styling rules for new technologies are evolving rapidly with the Javascript ecosystem and becoming increasingly modular. Writing CSS custom properties becomes easy with such new technologies and techniques. Yet, it’s clear that the industry is embracing new approaches. We’ll continue to see them grow and make styling even more interesting in the future.