React Styled Components: Give Life To Your Project

Reading Time: 7 minutes

Have you ever wonder how cool it will be to have accessibility to props and to the creation and reusability of components from React in CSS? It would be cool to have clean and compact code, right? Look no further! This introduction to Styled Components will give you your first approach to the library and showcase the power of JS + CSS combined.

 

Something I Want to Share

As an enthusiast of having clean and easy access code for pages, I like to browse through different libraries and dependencies, which can help in achieving this.

In my case, I have worked with preprocessors like sass and built up styles libraries like bootstrap or tailwind. They are awesome if you want to build something good-looking in a quick manner.

But, there is something about StyledComponents and its pure css and javascript that fills my heart with joy 💖.

So, I felt like sharing some of this magic with all of you.

 

Project Set Up

For this project, we will use the basic template react app creation along with the Styled components dependency. So, go ahead and initialize a new app with

npx create-react-app my-app

which will create a basic scaffold like this:

Then, install the requiered packages with:

npm install --save styled-components
or
yarn add styled-components

NOTE:

Just a quick disclimer: for this project we are using react 17.0.2 and styled-components 5.3.5, you can view a more detail photo of or package.json in the next image.

Nice! Now we are all set up to start our journey and code away, so buckle up as this is going to be fun!

 

No Stylesheets Needed

It is not mandatory to do it this way as you can mix and match StyledComponets with normal css stylesheets.

In the end, the way you implement your approach is a matter of feeling, preference, and project needs. But I want to showcase that you can create a beautiful website without using a single class or stylesheet.

So, go ahead and erase from your project all the .css (App.css, Index.css) files and remove the imports in your components as well.

It should look something like this:

 

Basic Structure

Just like we typically would write a class or semantic html to hold a specific set of rules, Styled Components allow us to create centralized styles that would apply only to that particular fraction of markup.

So, instead of having something like:

/src/App.js

function App() {
  return (
    <div className="App">
      <h1>hello world</h1>
    </div>
  );
}

we will have a component that represents a reusable bundle of css rules.


function App() {
  return (
    <Container>
      <h1>hello world</h1>
    </Container>
  );
}

The file structure is a convention mainly used for having some sense of order, but it can be whatever you are conformable with.

For this example we will follow:

Components > styles > ComponentName.styled.js

Inside this file, we need to import the dependency at the top, then we can create our component export. This const needs to have a special syntax. Like, you write styled followed by a dot(.) and then the desired markup container, like a div for example : styled.div.
From there you can write normal css rules like you normally do, just be careful to wrap them around backticks (``)

/src/components/styles/Container.styled.js

import styled from 'styled-components'

export const Container = styled.div`
  background-color: #eeff
  margin: 0 auto;
  max-width: 100%;
  padding: 0 20px;
  width: 1000px;
`

Every time that you create a new StyledComponent remeber to import it at the top of your file to have access in your React Component.

Now, if we go back to our page, the styles will be applied automatically to that specific section.

 

Props and Variables

Because this is a JavaScript file, we can use props and variable calling inside our styles declarations. The procedure of sending props is the same as you would normally do for a React component.


/src/components/styles/Header.style.js

import {HeaderStyled} from "./styles/Header.style";

export default function Header (){
  return (
    <>
      <HeaderStyled bg="aqua">
        NICE HEADER
      </HeaderStyled>
    </>
  )
}

Inside your styled component you can use ${} to interpolate and evaluate a function, in that way you can invoke props and deconstruct them for easy access

 

Themes

Is pretty common in modern websites to have multiple themes, such as Dark and Light, and luckily for us StyledComponents has its own tool to handle that need.

ThemeProvider is a wrapper that can be imported and will allow to bring themes to all the components that are inside of its reach via the context API. Once the render tree is completed the components will have access to the theme provided, no matter how deep the nesting is.

To make this wrapper work, you need to pass in a theme prop that can be an object defined outside your render or another file, with all the special styles layed out in a JSON format.

src/App.js

import { ThemeProvider } from "styled-components";

const theme = {
  colors: {
    header: "aqua"
    body:"#eeff"
  }
}

function App() {
  return (
    <ThemeProvider theme={theme}>
      <>
        <Header/>
        <Container>
          <h1>hello world</h1>
        </Container>
      </>
    </ThemeProvider>
  );
}

Access it directly on our styled components just by calling the theme prop

/src/components/styles/Header.style.js

import styled from 'styled-components'

export const HeaderStyled = styled.header`
  background-color: ${({ theme })=> theme.colors.header };
  padding: 0 40px;
`

 

Interpolation and Extension

When you want to have similar components with generic styling (size, fonts, align…etc ), but specific rules so it can stand out, another option StyledComponents offers you, instead of using props, something like inheritance. This is called Style Extension.

We can accomplish this inheritance by wrapping the Component name in the styled constructor like this

/src/components/styles/Button.styled.js

const Button = styled.button`
  background-color: white;
  border: 2px solid black;
  color: black;
  font-size: 1em;
  padding: 0.25em 1em;
`;

const AlertButton = styled(Button)`
  background-color: #ce4257;
  border-color:#ce4257;
  color: white;
`;

render(
  <div>
    <Button>Sign Up</Button>
    <AlertButton>Delete Account</AlertButton>
  </div>
);

 

Global Styled Component

As far as global components, you can use StyledComponent as well, with something called createGlobalStyle import. This will hold all the variables and shared styles like resets, fonts, initial margins, etc.

/src/components/styles/Global.styled.js

import {createGlobalStyle} from 'styled-components'

export const GlobalStyles = createGlobalStyle`
  @import url('https://fonts.googleapis.com/css2?family=Rubik:wght@300&display=swap');
  * {
    box-sizing: border-box;
  }

  body {
    background-color: white;
    color: black;
    font-family: 'Rubik', sans-serif;
    font-size: 1.2rem;
    margin: 0;
  }
`

Bring it in to your main app like so:

import { GlobalStyles } from "./components/styles/Global.styled";

function App() {
  return (
    <ThemeProvider theme={theme}>
      <>
      <GlobalStyles/>
        <Header/>
        <Container>
          <h1>hello world</h1>
        </Container>
      </>
    </ThemeProvider>
  );
}

So, before I show you the last piece of information, let’s use all the basics that we have learned so far and build something closer to reality in 3..2..1 and poof...

Here is a little sneak peak of the components:

/src/components/Header.js

import { HeaderStyled, Nav, Logo, Image } from "./styles/Header.style";
import { Container, FlexContainer } from "./styles/Container.styled";
import { Button } from "./styles/Button.styled";

export default function Header() {
  return (
    <>
      <HeaderStyled>
        <Container>
          <Nav>
            <Logo src="logoipsum-logo-51.svg" alt="logo"></Logo>
            <Button bg="#5829a7">Sign Up</Button>
          </Nav>
          <FlexContainer>
            <div>
              <h3>City Simulator</h3>
              <p>
                The standard chunk of Lorem Ipsum used since the 1500s is
                reproduced below for those interested. Sections 1.10.32 and
                1.10.33 from "de Finibus Bonorum et Malorum".
              </p>
              <Button bg="#b5179e">Play Now</Button>
            </div>
            <Image src="istockphoto-1279840008-612x612.jpeg" alt="img"></Image>
          </FlexContainer>
        </Container>
      </HeaderStyled>
    </>
  );
}
export const HeaderStyled = styled.header`
    background-color: ${({ theme })=> theme.colors.header };
    font-size: 1.5rem;
    padding: 30px 20px;
`

export const Nav = styled.nav`
  align-items: center;
  display: flex;
  justify-content: space-between;
`

export const Image = styled.img`
width: 350px;
border-radius: 15px 5px 15px 5px;
margin-left: 30px;
`
export const Container = styled.div`
  width: 1000px;
  max-width: 100%;
  padding: 0 20px;
  margin: 0 auto;

  p{
    text-align: ${({align})=>align};
  }
`
export const FlexContainer = styled.div`
  display:flex;
  align-items: center;
  direction: ${({direction})=>direction || 'row'}
`

That's great up until now, so the last little thing that I want to show you is something both important and useful when designing a nice page; and that is responsiveness.

 

Media Queries

Just like any normal style declaration you can define your break points inside the specific block of css that you need.But, StyleComponets offers you a more ordered and easy access way to do it.

So, going back a little bit on what we have learned, you remember themes? Well, as we discussed is a JSON that is accessible throughout the whole render tree, so we can define a new key that will hold our breakpoints like:

const theme = {
  colors: {
    header: '#bbd0ff',
    body: '#f2f7ff'
  },
  mobile: {
    small: '768px'
  }
}
export const Nav = styled.nav`
  align-items: center;
  display: flex;
  flex-direction: row;
  justify-content: space-between;

  @media(max-width: ${({theme})=>theme.mobile.small}) {
    flex-direction: column;
  }
`
export const Image = styled.img`
  border-radius: 15px 5px 15px 5px;
  margin-left: 30px;
  width: 350px;

  @media(max-width: ${({theme})=>theme.mobile.small}) {
    margin: 20px 0  0 30px;
}
`

Pretty cool, right?! So, from here on it is just a matter of imagination and how compact you want your code to be. This was only a showcase of the basics, but this utility library goes deep and complex, so check out the documentation if you want to become a pro!

There is no absolute correct way of doing this, so go crazy and code stunning pages with this new knowledge.

Happy coding, until next time. 🙂

Source:
https://styled-components.com/docs

4 Shares:
You May Also Like
Read More

Classes vs Hooks on React

Reading Time: 4 minutes Previously, in the world of React, we had to use Classes in order to create components. Since version…