loading...
Cover image for Styled Components: A Quick Start Guide

Styled Components: A Quick Start Guide

scalablecss profile image Tom Ray Originally published at scalablecss.com ・7 min read

This is a quick start guide to learning Styled Components, the component-driven CSS methodology.

If you want to start practicing and applying Styled Components to your projects, this guide will help you get started.

Ready? Let's dive in:


Bonus: Download a free cheat sheet that will show you how to quickly get started with styled-components.


Contents:

Styled Components Overview

Styled Components is a library for React & React Native to write and manage your CSS.

It's a "CSS-in-JS" solution, meaning you write your CSS in Javascript files (specifically within your components, which are Javascript files).

It's an extremely popular solution for managing CSS in React, with around 8 million npm downloads/month and 30k stars in Github.

A familiarity and understanding of React is recommended before diving into Styled Components.

A few benefits of the styled-components library are:

  • It's plain CSS. Yes, you're writing the CSS in a JS file, but the CSS syntax is unchanged.
  • Vendor prefixes are automatically added when using Styled Components, improving performance across browsers.
  • All unused CSS and styling gets removed automatically
  • You don't write any class names, whatsoever. Class names are generated automatically, so there's no need to manage a CSS class naming methodology like BEM. (This'll make more sense as you go through the article)

Installing styled-components

To get started with styled-components, you first need to install it into your project:

npm install styled-components

And on every file that you use styled-components, you'll need to add this import:

import styled from 'styled-components';

And that's it! You're ready to start working with styled-components.

Building your first styled component

Open up an existing React project you're working on (or quickly whip up a new project with create-react-app), and open up one of your existing components.

Here, you can add your first Styled Component.

Now that you have styled imported, here's how you get started:

// App.js
import React from 'react';
import styled from 'styled-components';

// Button component that'll render an <a> tag with some styles
const Button = styled.a`
  background-colour: teal;
  color: white;
  padding: 1rem 2rem;
`

const App = () => {
  return (
    <Button>I am a button</Button>
  )
}

export default App;

Let's break this code down:

  • Just like writing a React functional component, declare the name of the component with const Button
  • styled is what we imported above, and gives us the Styled Components functionality
  • Notice the a after styled? This represents the anchor HTML element: <a>. When declaring a Styled Component, you can use any HTML element here (e.g. <div>, <h1>, <section> etc.)

Make sense?

The <Button> returned inside the App component looks like a normal React component. And that's because it is a React component!

In our previous example, we created a Styled Component inside an existing component.

But you can also create a Styled Component in its own file.

For example, create a new component file called Button.js, and add a Styled Component:

// Button.js
import styled from 'styled-components';

const Button = styled.a`
  background-colour: teal;
  color: white;
  padding: 1rem 2rem;
`

export default Button;

Button now works like any other React component. For example, we can now import this component into other components files:

// App.js
import React from 'react';
import styled from 'styled-components';
// import the styled component:
import Button from './Button';

const App = () => {
  return (
    <Container>
      <Button>I am a button</Button>
    </Container>
  )
}

export default App;

And there you have it!

Congratulations, you just built your first Styled Component!

Using props to customize Styled Components

Imagine you have a <Button /> component, and you need to style different variants of that button (primary, secondary, danger, etc).

Styled Components have an elegant solution for this, where you leverage props to make your component styles dynamic.

Let's dive right into an example to show you what I mean.

Here we are rendering two Button components, one with a primary prop:

// App.js
import React from 'react';
import styled from 'styled-components';
import Button from './Button';

const App = () => {
  return (
    <>
      <Button>I am a button</Button>
      <Button primary>I am a primary button</Button>
    </>
  )
}

export default App;

And now, inside our <Button /> component, we can add the dynamic styles:

// Button.js
import styled from 'styled-components';

const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  border: 2px solid white;
  background: ${props => props.primary ? 'white' : 'palevioletred' }
  color: ${props => props.primary ? 'palevioletred' : 'white' }
`

export default Button;

What's happening here is you're interpolating a function that is returning a CSS value (using a ternary operator) based on the props.

That was quite a mouthful.

To put it more simply, background: ${props => props.primary ? 'white' : 'palevioletred' } essentially means:

If the prop primary is true, then the background should be white, else the background should be palevioletred.

Handling props like this works in some use-cases, but it can get messy if you have multiple props (e.g. primary, secondary, danger, etc.) as well as multiple lines of CSS.

Often, it makes more sense to import { css } from styled-components like this:

// Button.js
import styled, { css } from 'styled-components';

const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  ${props => props.primary && css`
    background: white;
    color: palevioletred;
  `}
`

export default Button;

This keeps your dynamic styles separate for different props.

For example, adding styles for a danger prop would look like this:

// Button.js
import styled, { css } from 'styled-components';

const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  ${props => props.primary && css`
    background: white;
    color: palevioletred;
  `}

  ${props => props.danger && css`
    background: red;
    color: white;
  `}
`

export default Button;

Nice! We're making some good progress.

How about making this <Button /> a little more responsive, eh?


Bonus: Download a free cheat sheet that will show you how to quickly get started with BEM.


Using media-queries to make your styled-components responsive

Thankfully, making your Styled Components responsive is super simple.

Add media queries inside your template literal, like this:

// Button.js
import styled from 'styled-components';

const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 9rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  @media (min-width: 768px) { 
    padding: 1rem 2rem;
    width: 11rem;
  }

  @media (min-width: 1024px) { 
    padding: 1.5rem 2.5rem;
    width: 13rem;
  }
`

export default Button;

If you're looking for a more involved example with multiple different device sizes, I recommend checking out this Javascript Ramblings article.

Handling hover states and other pseudo-selectors with Styled Components

Similarly to adding media queries to your Styled Components, adding pseudo selectors is pretty straightforward.

For example, adding a hover state to our <Button /> component would look like this:

// Button.js
import styled from 'styled-components';

const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 9rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  :hover {
    border-color: green;
  }
`

export default Button;

Creating global styles

One of the main mental models of React is how you treat everything as components.

You essentially break an interface down into tiny chunks and piece it all together in a scalable way.

This approach comes with many advantages, but does however surface a challenge:

How to style parts of your design that are consistent across multiple components?

Or put another way:

How can you set global styles?

For example, you might want to:

  • Set a font-family for all your typography
  • Set the background color on every page
  • Override some browser default styling

Styled Components has a solution for global styles using the createGlobalStyle function.

First, navigate to the component which is at the top of your React tree.

For example, if you're working in a create-react-app project, that'll be your App.js file.

Here, you'll need to import createGlobalStyle into your project, and set some styles to a GlobalStyle component (you can name this component how you like):

// App.js
import React from 'react';
import styled, { createGlobalStyle } from 'styled-components';
import { Container, Nav, Content } from '../components';

const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
    padding: 0;
    background: teal;
    font-family: Open-Sans, Helvetica, Sans-Serif;
  }
`;

const App = () => {
  return (
    <Container>
      <Nav />
      <Content />
    </Container>
  )
}

export default App;

This isn't going to apply the styles to the project yet.

Now we need to use the GlobalStyle component to apply the global styles to the application.

You do this by placing the GlobalStyle component at the top of your React tree:

// App.js
import React from 'react';
import styled, { createGlobalStyle } from 'styled-components';
import { Container, Nav, Content } from '../components';

const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
    padding: 0;
    background: teal;
    font-family: Open-Sans, Helvetica, Sans-Serif;
  }
`;

const App = () => {
  return (
    <>
      <GlobalStyle />
      <Container>
        <Nav />
        <Content />
      </Container>
    </>
  )
}

export default App;

Notice the use of fragments short syntax?

This is required as you're placing the <GlobalStyle /> component as a sibling at the top of the tree.

And that's it!

Global styling is now all set up with Styled Components.

Conclusion

Nice job if you've made it all the way to the end.

We covered a lot! Specifically:

  • What Styled Components are and why you should consider using them
  • How to install styled-components
  • Building your first styled component
  • Making your Styled Components dynamic with props
  • Using media queries to make your Styled Components responsive
  • How to handle pseudo selectors with Styled Components
  • Setting global styles

Those are the fundamentals to get you off and running with Styled Components.

Like learning anything new, practicing is key. Give Styled Components a shot in your next project and see where it takes you!


Download Free Styled Components Cheat Sheet

Want to start practicing styled-components and looking for a no-nonsense, quick start action guide?

Download a free cheat sheet covering styled-components basics so you can dive in and start practicing today.


Posted on by:

scalablecss profile

Tom Ray

@scalablecss

I spend way too much time thinking about CSS 👀

Discussion

pic
Editor guide