CSS: styling in component-based structures

technology

css styling component structures css styling component structures

Mandy Trilck

Mandy Trilck

The language that styles the web, CSS, has a feature that always generates debate: its global scope. In traditional stylesheets, styles apply across an entire site or app. Over the years , naming conventions emerge to help contain that global scope chaos, like BEM or SMACSS. Theses systems aspire to create a more modular and scalable technology out of CSS, when inherently it’s not.

As web dev takes firmer steps towards components and modualar design, the focus on global scope is intensifying. The original composition puts separations of concerns in HTML, CSS, and JS files. But more recent frameworks, like React and Vue.js, couple HTML and JS in the same files. This is achievable by dividing by components, and not by languages.

Yet, it raises the question: how style should fit into this structure?

New school of CSS

A lot of styling libraries and systems, and build processes, apparently answer this question. We’ll take a loot at some of the main ones, with their advantages over traditional CSS.

CSS styling component

Modular styling sheets

Sass Modules

Sass, most popular CSS’ extension, has a degree of modularity, allowing to divide stylesheet into several smaller ones. Many developers follow a common structure, like the 7-1 pattern, to further organize their project.

But, at last, separated files are combined into one stylesheet with the @import feature, risking naming conflicts. Saas makes their next big step in 2019, replacing @important with @use, and @forward. These new features define relations between files in a project, removing conflicts and clarifying dependencies’ origins.

For example, @use gives a namespace to imported features:

@use 'buttons'; 

This brings in styles from the buttons file, which can then be accessed in the following way:

$btn-color: buttons.$color;

CSS Modules

CSS modules starts in 2015, generating a global stylesheet, but with unique class names for each component. This build process creates .module.css and .js files for each component.

The CSS can use any class names, even repeating those in other files. That’s possible because CSS Modules transforms class names into unique ones, avoiding naming conflicts.

Another bonus is that this unique naming still include human readable words. This facilitates finding and maintaining styles for developers.

For example, if we have a file called box.css, a selector like this:

.text {
  color: blue;
}

once compiled, will turn into something like this:

.box_text_j3xk {
  color: blue;
} 

A unique selector with the file name, the class name and a random hash.

css styling component structures css styling component structures

CSS-in-JS

CSS-in-JS is, like its name says, CSS written in JavaScript files. This method is known for putting the most emphasis on modularity. It takes separated stylesheets out of the equation, allowing styles to be put with components. It’s an approach that has both strong supporters as detractors.

There are various ways to manage this, depending on the system you use. At its most basic, styles applies straight to DOM elements. But, more commonly, its main 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 you to create custom components in a CSS-like syntax, via template literals.

const StyledSection = styled.section`
  text-align: center;
  margin: 0 2em;
`

In the JSX, you can now employ the <StyledSection> component:

render(
  <StyledSection>
    <h1>Hello World!</h1>
  <StyledSection>
)

Component libraries, such as Grommet and Rebass, offer pre-fab components, styled principally by accepting system properties. 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'
/>

This libraries are likely to be the most comfortable for CSS purists. They can keep styles in the same file as the componen, or import it for a more traditional approach. For instance, you can create a folder for a Button component, that have both index.js and style.js files.

One of the main advantages of CSS-in-JS is its fluid way to theming styles. This is possible by passing them via props, and changing them according to its state. In Saas and CSS Modules, the workaround ir applying class names with basis on props. In 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 syntax. If we hace a value set for “primary” in out 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

Best styling choices for modern JS frameworks

This question still generates a hot debate nowadays. Saas is an excellent technology, and companies are investing a huge amount of 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 that have developers considering other solutions.

JS developers who were never in love with CSS, CSS-in-JS can be seen as a much more “cool” tool. On the other hand, there are some truths that make Styles Components (or Emotion) persuasive choices. For instance, Styles Components:

  • Use Javascript and compiler magic to achieve the same features that make Sass great, like nesting, variables, etc.
  • Are more readable than Sass for an average Javascript developer building components. Still, they’re readable for UX-developers without much JS experience.
  • Include automatic vendor prefixing.

They’re not just a niche, tho: some big production projects are using Styled Components. To name some: Patreon, Target, Reddit, Autodesk, Atlaskit, Typeform, Vogue, and Coinbase.

Conclusion

Styling technologies are evolving rapidly with the Javascript ecosystem and becoming increasingly modular. With such an amount of new technologies and techniques, it can be easy to write some ones off.

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.

Know your types of headless CMS

The business risks of overlooking software documentation

The value of a startup idea