Styled Components and their benefits

the main advantages of using CSS in JavaScript

CSS, the nice guy

CSS is very difficult. If they tell you otherwise, it's because they just want to make you happy

I remember when I saw this phrase in one of Willian Justen's courses. I must have stopped for five minutes while thinking about how real she is.

Do not get me wrong. It's really cool to work with CSS and we're often happy to be able to create our component designs and pages with this technology, but CSS also has a lot of problems.

If we don't worry about minimizing CSS issues and don't do the bad practices prevention work in our code, as the application grows, problems and bad practices grow together.

Maintaining standards is boring, time-consuming and expensive, but only if you do it the wrong way.

It is very difficult for a single programmer to know all the components of an application, especially when they are constantly updated. Now imagine a repository that is maintained by five teams, each team with at least four developers, each developer with different practices and seniority.

Thankfully, there are amazing tools to facilitate code standardization for our projects, such as ESLint, Prettier and EditorConfig. These tools, in line with pre-commit and pre-push routines, greatly facilitate the code standardization and code review process. But that's a topic for another post.

CSS is not ahead of its time

CSS is evolving. We already have some pretty cool features, like the possibility of using variables inside CSS, but even with some new features, we still have some issues.

In the beginning: I'll fix it here, and... ops it broke there..., hummm just fix it here and there... At the end: it feels like I'm at the beginning

Known Issues

Some of the main CSS issues are:

STYLE COLLISION

As CSS is not defined on a per-component or per-page basis, it is loaded onto our website and styling is applied over all visible HTML. When we need to import a library, it can happen that this library has the same classes or has a greater specificity that ends up colliding with our code, generating some problems in the style of our application.

UNUSED CODE

We often write CSS thinking of various ways to represent a component, such as buttons in different shapes. We need to load CSS for all styles, but we don't necessarily need to use all styles in the same page. With that, we ended up loading all the styles of buttons that won't be used there. This brings more problems for the client who ends up spending more bandwidth unnecessarily.

DIFFICULTY IN MAINTENANCE

Many times when we need to update a style, we end up breaking another style in another piece of code that has nothing to do with the first style. This makes maintenance much more costly than it should be and we need to keep "digging" a lot of code so we don't run the risk of breaking something that shouldn't be broken.

Less, Sass, Stylus. How do they live? What do you eat?

The pre-processors are there and they help a lot, especially with the possibility of using variables in CSS (a feature that didn't exist before in css, but now exists) and with the ease of working with style nesting (cascades), but they continued with the classic problems, in addition to making room for bad practices, such as excessive nesting:

/*nested*/
section {
  nav {
    ul {
      li {
        a {
        }
      }
    }
  }
}

/*in line*/
nav ul li a { ... }

Who has never seen an scss code with all this nesting, right?

This nesting is not a good practice, because you end up creating enormous specificity for this component, and therefore if we want to change this style somewhere else, we will need to make this code even more specific, often needing to insert an id or more selector, or even an !important, which isn't cool.

STYLED-COMPONENTS, your little friend

Styled Components is a library that, through a set of practices, solves complex CSS problems.

The main advantages of using styled-components are:

NO BUGS WITH CLASS NAMES

styled-components generates unique class names for each style. Even if elements have the same class, they will not suffer style cohesion. For example:

// button/index.js
  <Button className="primary" />
// public/index.html
  <button class="sc-fznLPX jckqBg primary" />

REMOVAL OF UNUSED CSS

It is the component's responsibility to create or import its style from the styles file. If the component is not used, none of your CSS will be loaded into the page.

Every deleted component of the page will also have its CSS deleted.

DYNAMIC STYLES

It is possible to change the style of the components through the properties and themes received.

Example:

Passing the outlined property to the Button component:

// button/index.js
<Button outlined>Edit profile</Button>

Changing the Button component's style through the passed property:

// button/styles.js
export const Button = styled.button`
  background-color: ${props =>
    props.outlined ? 'transparent' : `${props.theme.colors.primary}`};
`

As we can see, I'm checking if the Button component has the outlined property. If yes, then I apply the background-color as transparent. If not, I apply the value of the colors.primary property, defined in the theme.js file, to the background-color.

I'll still write how to configure a theme using styled-components and put the link here.

VENDOR AUTOMATIC PREFIXING

Properties like -webkit, -moz-, -ms and -o- do not need to be entered anymore, as styled-components does this work automatically.

/* with styled-components */
export const Container = styled.section`
  transition: all 2s linear;
`
/* without styled-components */
.container {
  -moz-transition: all 2s linear;
  -ms-transition: all 2s linear;
  -o-transition: all 2s linear;
  -webkit-transition: all 2s linear;
  transition: all 2s linear;
}

SIMPLIFIED AND PAIN-FREE MAINTENANCE

The style being changed only matches the component that imports it.

Styled Components is awesome, isn't it?

If you want to see this example in practice, you can take a look at the template I created for React projects here:

GitHub logo coderamos / template-reactjs

This project contains the basic structure for React projects. It also includes my settings for babel-plugin-root-import, eslint-plugin-import-helpers, prop-types, react-router-dom, styled-components and more...

Comment there what you think about this use styled-components :)

12