12
Styled Components and their benefits
the main advantages of using CSS in JavaScript
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
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 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:
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