Styled-components with Emotion

Featured on Hashnode

Introduction

When it comes to setting up React applications, we all know everyone has a way of configuring their project to get the best out of the project. Styling is one part where everyone does it differently the most. There are many options on this subject in the ecosystem. Most go for the traditional way of styling, which is creating a style.css file. For example, if we are to style a header, we do this.

h1{
  font-size: 2rem;
  color: #000;
}

But then as we create larger applications that need to scale over time, it is important to remember the importance of modularity when it comes to structuring your code.

How Emotion works

Styled-components is the principle on which Emotion is built on. Basically, styled component is writing CSS in JavaScript, which gives you a separation of concern for each component and modularize your styling to just that particular component. I know a lot of people cringe at the thought of this at first like... why would anyone do that?? But then as we go we will see the advantage of writing CSS-in-JS. Emotion is a library designed for writing css styles with JavaScript, it gives you features such as source maps, labels, and testing utilities. Although Emotion as a lot of packages, the only package we will talk about in this article is @emotion/styled

Working with Emotion

To demonstrate, let's create a button using Emotion css. First of all we have to install two packages through the terminal:

yarn add @emotion/react @emotion/styled

After installation, we create a file called Button.js and write the following:

  • First, we create the Button component:
import React from "react";
import styled from "@emotion/styled";


export default function App() {
  return (

    <Button>Click me!</Button>

  );
}
  • We then style with styled as a regular HTML element:
import React from "react";
import styled from "@emotion/styled";


const Button = styled.button`
  border: none;
  padding: 1rem 3rem;
  text-transform: uppercase;
  background: #0A122A;
  color:   white;
  border-radius: 5px;
  cursor: pointer;
`;

export default function App() {
  return (

    <Button>Click me</Button>

  );
}

When we run this, we get this as result:

Screenshot 2021-04-29 at 11.44.02.png

We can see how simple it is to write CSS in JavaScript and how much it makes out code simpler and neat.

Dynamic styling

A lot of components have different variations and styles in different situations on a web page. For example, we always have a primary button and a secondary button, which by definition has different styles even though in principle, they have the same structure as buttons. We want to have the flexibility to have control of how a particular component should look. With Emotion, we can achieve this with props being passed through the component. Any interpolations or arguments that are functions in styled are called with props, this allows you to change the styles of a component based on the props. Let's see how we could do this in the code.

Suppose we want to make the same button flexible and give it the ability to change in different situations; to become a primary and secondary button, this is a simple way to do it, we first refactor the code:

 background: ${props => (props.secondary ? '#f8f9fa' : '#0A122A')};
 color: ${props => (props.secondary ? 'black' : 'white')};

In our Button component, we pass in the secondary props:

<Button secondary>Click me</Button>

And it gives us this as a result:

Screenshot 2021-04-29 at 16.07.37.png

What the styling code is doing is check if the props to see if it has a property of secondary and check if this is true, using ternary operator. If this is true, it changes the background to f8f9fa, else, it just leaves it as #0A122A.

Styling other Emotion components

Emotion also offers a way style other components conveniently. Suppose we chose not to make the buttons dynamic as such, we could just create a separate secondary button and style with a template button.

  • First we create a template button:
const ButtonTemplate = styled.button`
  border: none;
  padding: 1rem 3rem;
  text-transform: uppercase;
  border-radius: 5px;
  cursor: pointer;
`
  • We then create a primary button component and wrap the ButtonTemplate in it, then we can style it as we choose:
const Button = styled(ButtonTemplate)`
  background: #0A122A;
  color: white;
`;

const SecondaryButton = styled(ButtonTemplate)`
  background: #f8f9fa;
  color: black;
`
  • Finally we put our button components in our return statement:
const ButtonTemplate = styled.button`
  border: none;
  padding: 1rem 3rem;
  text-transform: uppercase;
  border-radius: 5px;
  cursor: pointer;
`
const Button = styled(ButtonTemplate)`
  background: #0A122A;
  color: white;
`;

const SecondaryButton = styled(ButtonTemplate)`
  background: #f8f9fa;
  color: black;
`

export default function App() {
  return (

    <Button >Click me!</Button>
    <SecondaryButton>Click me!</SecondaryButton>

  );
}

Our result should look like so:

Screenshot 2021-04-29 at 16.35.37.png

If you are wondering how you could use it in other components, all you have to do is export the component like so:

export const Button = styled(ButtonTemplate)`
  background: #0A122A;
  color: white;
`;

Then this makes it available for usage anywhere in your application by importing it.

Conclusion

We could see how useful this library is in terms of flexibility for our styling. There are tons of things you could still do with this library which I haven't mentioned, if you want to know more, you could just do some reading of the docs. Thanks for reading.

Saquib Hussain's photo

These styles are amazing! And I have to say, very well documented.

arinzejustinng's photo

I read it more than once

Kieran Roberts's photo

That was a nice introduction to Emotion. Well done Michael Gates!

Michael Gates's photo

Thank you Roberts.

Umoh Tobby's photo

Nice article big chief