Pagepro Blog

JavaScript

Moving best (S)CSS practices to styled-components – part 1

Posted on .

Moving best (S)CSS practices to styled-components – part 1

Introduction

Styled-components became a really powerful library for creating styles in React applications. But if you are a front-end developer and you know good practices to create styles in a traditional way (with BEM methodology or by using SASS preprocessor for example) you may experience some difficulties at the beginning of your journey with this approach. In this article, I would like to show you how we can move some best styling practices directly to your styled-components.

Every day we build more and more applications from smaller to bigger, finishing on quite complex projects. Usually, we have to figure it out how to create maintainable styles and how to organize them in a folder hierarchy. Over the years, developers have learned how to work more effectively with CSS by using different methodologies and helpful tools like preprocessors, minification plugins or linters. CSS-in-JS approach came with built-in utilities for solving some basic problems with CSS like scoped selectors but also brings new challenges to the world of styles. If we are not careful, we will start to make exactly the same mistakes we have made in the past (or even worse).

Some of the good practices are enforced by default with styled-components. For example, you cannot style your component without creating a unique class for this element. And it is done for you absolutely automatically. But it is possible to create a styled component with many properties and hard to maintain. Despite a large number of advantages, we have to be careful during designing new styles in this library.

Let’s see how we can improve our work with styled-components using proven practices that we already know from CSS and SASS.

In the further part of the article, I will use the latest API version of the library (v4).

1. Using a CSS reset

Every browser comes with default stylesheets for HTML elements. In the past, there was a big problem to achieve consistency in default styles between the browsers (hey Internet Explorer! I’m watching you!). A good practice to unify default styles across the browsers is to use CSS “reset” library. And one of the most popular is Normalize.css. You can use normalize.css with styled-components in two ways:

  • by copying the source of normalize.css and pasting it into the createGlobalStyle function
  • by using a wrapper, specially created for styled-components like styled-normalize

The second option is much easier, cleaner and faster to reach the goal. First of all, we have to install styled-normalize by typing in terminal:

yarn add styled-normalize

Next, we need to import this package and put in somewhere in our code. The best place will be at the top of the main component, like in this example:

import React, { Fragment } from 'react';
import { Normalize } from 'styled-normalize';

const App = () => (
 <Fragment>
   {/* Using this library is as easy as adding a new component */}
   <Normalize />
   <header>Test App</header>
   <main>...</main>
 </Fragment>
);

export default App;

Pretty simple, isn’t it?

2. Extracting often used variables

One of the holy grails while developing a large application is to perform “Don’t repeat yourself” principle (DRY). Usually, in a stylesheet, we repeat colour values, font sizes, margins etc. Can you imagine the scenario when someone decided to redesign your application and you didn’t extract often used values? Hundreds of places to change. It would be a nightmare. In regular CSS we can create variables by using var() function. But if you have to support old browsers you cannot depend only on CSS. You will need preprocessors like SASS or LESS, PostCSS or different solution. Styled-components is a JavaScript library so you can just use normal JS variables to extract particular values. You can split these values into several files, like in the example below:


|-- styles/
       |-- colors.js
       |-- breakpoints.js
       |-- spaces.js
       |-- fonts.js
       |-- mixins.js

Inside them, we can export variables in a standard way as we export a regular JSON object:
- colors.js file:


export default {
 grey1: '#e5e6e6',
 grey2: '#fafafa',
 grey3: '#41464e',
 white: '#fff',
};

Later, you can import these values for styling buttons, paragraphs etc.


import styled from 'styled-components';
import colors from '../../colors';

const StyledButton = styled.button`
 color: ${colors.white};
 text-align: center;
`;

3. Vendor prefixing

This point will be quite short. In a regular CSS, you must remember about vendor prefixes in your CSS rules. It is necessary to manage backward compatibility with these older browsers which implemented new style rules before CSS3 standard was finished. One of the common ways to do that without thinking about different vendors is including in project a tool called autoprefixer.

With styled-components you don’t have to do anything because the library provides automatic vendor prefixing. Sadly, there is no option to change default versions of supported browsers. If you need to support for example Internet Explorer version earlier than 11, you have to find other solutions.

4. Reducing the size of styles

Minification of CSS can be a crucial thing in large codebases. Reducing the size of CSS files is absolutely important in these environments which have a limited Internet connection. In normal CSS we can realise compression of styles by using for example plugin for Webpack or for other module bundlers. In styled-components minification is enabled by default so you don’t have to worry about it. But if there is a need to change this default behaviour you can turn it off with the babel-plugin-styled-components package. This plugin has to be installed manually:

yarn add --dev babel-plugin-styled-components

And included in the .babelrc file or package.json with the false value for “minify” property like in the example below:


"babel": {
 "plugins": [
   ["babel-plugin-styled-components", { "minify": false }]
 ]
}

There is one thing that we have to remember. Styled-components can’t extract CSS styles into a separate file. So, the result of minification (or dead code elimination) will be visible in a proper <style> tag.

5. Adding useful global styles

Styles which are scoped to concrete components are very desirable nowadays. We don’t want to break the rest of the page while working on a particular component. However, sometimes there is a need to add something globally like a declaration of font-faces or resetting box-sizing property for every component. This is pretty easy in a traditional approach because it is the true nature of CSS in being global. Like working with Normalize.css in styled-components, we can achieve that by using the createGlobalStyle function. You can set the box-sizing property for every element on the page like in the example below:


import React, { Fragment } from 'react';
import { createGlobalStyle } from 'styled-components';

const GlobalStyles = createGlobalStyle`
 html {
   box-sizing: border-box;
}

 *,
 *::before,
 *::after {
   box-sizing: inherit;
}
`;

const App = () => (
 <Fragment>
   <GlobalStyles />
   <header>Test app</header>
 </Fragment>
);

export default App;

Conclusion

Styled-components resolves a lot of essential problems which can be problematic in the standard way of creating styles on pages. But even with the best tool, we can produce a pretty big mess when designing new styles in complex applications. Especially if we are not sure of this strategy. Thankfully we already have a pretty big bag of experience from different approaches which we can use in symbiosis with styled-components. Furthermore, the popularity of styled-components is growing very fast and maybe someday we will be able to forget about the dilemmas we now face. I hope so!

In this part, I tried to provide some basic CSS patterns which can be easily adopted in styled-components. Some of them work out of the box, some not. In the next article, I will focus even more on structuring applications and other useful tools which can be used with styled-components.

Paweł Ochota

Paweł Ochota

There are no comments.

View Comments (0) ...
Navigation