Styled Components - Beginners Tutorial
Styled Components - Beginners Tutorial

In this post you will learn what are styled components and why it is a really good solution to write CSS inside React.

What is it?

What is Styled Components at all? This is a library to write CSS but inside Javascript. And we don't do it just inside Javascript, we write our CSS like React 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;
`

This is an example how it looks like. We create here an a tag and provide these styles inside.

But now you for sure what to ask if it makes any sense to write CSS inside Javascript. And actually no as plain CSS will be faster and better.

When we write CSS inside Javascript we have several benefits:

  • It will load only CSS that is needed for our components on current page.
  • Secondly, it is really easy to cut out all CSS which is not used inside our components.
  • It is much easier to do vendor prefixes inside CSS
  • Most importantly, we can mix CSS and JS

For example if you have some state inside Javascript normally you can just change CSS only through classes. When we write CSS in Javascript we can simply change our CSS based on Javascript state.

Real Example

But enough talking, let's check how it works on the real example.

import styled from "styled-components";
import Register from "./Register";

const Title = styled.h1`
  font-size: 16px;
  text-align: center;
  color: green;
`;

const App = () => {
  return <Title>Hello Monsterlessons</Title>;
};

Here we created a Title component which contains h1 tag by calling styled.h1. After this we can directly use it inside our App.

Title

As you can see we rendered nicely styled component. In DOM you can see that we got a unique class with styles attached in the head.

Styled components isolate the styles and they are not global anymore.

Secondly we can reuse not just styles but we reuse the whole component. This is extremely efficient because we can combine our CSS and component logic together and just reuse it as a React component.

Now let's say that we want some wrapper.

const Wrapper = styled.div`
  padding: 10px;
`;

const App = () => {
  return (
    <Wrapper>
      <Title>Hello Monsterlessons</Title>
    </Wrapper>
  )
};

Here we added a wrapper component to apply some padding for other components.

Now across the whole application we can reuse Title and Wrapper components.

Props inside component

The next thing that we typically need to do is we want to pass some props inside our component. For example we have a button and we want to configure it with color or a background.

const Button = styled.button`
  color: ${(props) => (props.danger ? "white" : "#CA0B00")};
  background: ${(props) => (props.danger ? "#CA0B00" : "white")};
  font-size: 14px;
  padding: 4px;
  border: 2px solid #ca0b00;
  border-radius: 3px;
`;

const App = () => {
  return (
    <Wrapper>
      <Title>Hello Monsterlessons</Title>
      <Button>Normal</Button>
      <Button danger>Normal</Button>
    </Wrapper>
  )
};

Here we used a function notation inside color and background. As an argument we get access to props what we pass to component.

Buttons

As you can see passing a prop allows us to change styles of the component.

Extend

Another feature that you will for sure use is called extend. For example we can extend our Button component to reuse all styles from it and make our own adjustments.

const CommentButton = styled(Button)`
  color: white;
  background: blue;
  border: 2px solid transparent;
`;

const App = () => {
  return (
    <Wrapper>
      <Title>Hello Monsterlessons</Title>
      <Button>Normal</Button>
      <Button danger>Normal</Button>
      <CommentButton>Add comment</CommentButton>
    </Wrapper>
  )
};

Here we create a CommentButton but instead of using styled.div or some other element we provided our own component inside. So we made CommentButton based on our Button component. It allows us to reuse all it's styles and apply more styles that we need.

Comment button

As you can see we got all styles from the button but now it's blue with white color.

Custom components

Another important technique which might be a little bit more advanced is creating custom components. Let's first create completely normal component without styled-components.

const Link = ({ route, name, className }) => (
  <a href={route} className={className}>
    {name}
  </a>
);

This is a link component where we can define a route and a name. It doesn't have anything with styled-components but we also get className from the props and put them inside.

<Link route="/" name="Some link"/>

But by adding this className we have a possibility to style this component.

const StyledLink = styled(Link)`
  color: white;
  background: purple;
  &:hover {
    color: red;
  }
`;

<StyledLink route="/" name="Some link"/>

We create a StyledLink here where we used Link as a base and added some styles to it. Then we can use it exactly like other component.

Styled link

As you can see we have the same link but now it is styled.

Also as you saw here we wrote hover effect. It is completely possible to do that inside styled-components and we write in exactly like in SASS or LESS.

Real register form

Now you for sure want to see a real example how you can use styled components in real project. Here I prepared for us a register form without any styles.

const Register = () => {
  return (
    <div>
      <div>
        <label>Name</label>
        <input type="text" name="name" />
      </div>
      <div>
        <label>Email</label>
        <input type="text" name="email" />
      </div>
      <div>
        <label>Password</label>
        <input type="password" name="password" />
      </div>
      <button>Register</button>
    </div>
  );
};
export default Register;

Form without styles

Now let's create several styled components to improve our form.

const Form = styled.div`
  width: 100%;
  background: #fff;
  padding: 30px;
  max-width: 450px;
  border-radius: 10px;
  box-shadow: rgba(3, 3, 3, 0.1) 10px 0px 50px;
`;

Here is our container with correct size background and body.

const Field = styled.div`
  margin-bottom: 30px;
`;

Every group of label and input is a field. We just need some margin here

const Label = styled.div`
  margin-bottom: 10px;
  font-size: 15px;
  fort-weight: 600;
  color: #777;
`;

Here is our label component for every label.

const Input = styled.input`
  width: 100%;
  padding: 25px 15px;
  border: 0;
  background: #f0f0f0;
  border-radius: 5px;
  font-size: 18px;
  color: #555;
  font-weight: 600;
`;

Now we added input styling.

const Button = styled.button`
  background: #037ef3;
  color: #fff;
  font-weight: 600;
  width: 100%;
  border-radius: 5px;
  cursor: pointer;
  padding: 25px 15px;
  border: 0;
  font-size: 18px;
  &:hover {
    background: #0271da;
  }
`;

And last but not least is our submit button.

Now we just need to use this components in our markup.

const Register = () => {
  return (
    <Form>
      <Field>
        <Label>Name</Label>
        <Input type="text" name="name" />
      </Field>
      <Field>
        <Label>Email</Label>
        <Input type="text" name="email" />
      </Field>
      <Field>
        <Label>Password</Label>
        <Input type="password" name="password" />
      </Field>
      <Button>Register</Button>
    </Form>
  );
};

As you can see instead of markup elements we used just components here. Also it is much easier to read this markup when we have custom naming of every components and not just div, div, div.

Finished form

As you can see in browser our form is fully styled and finished.

And actually if you are interested to learn everything that you need to know for Javascript interview check out my JavaScript Interview Questions - Coding Interview with 56 real world questions.

📚 Source code of what we've done