DEV Community

Shiva Pandey
Shiva Pandey

Posted on

STYLED COMPONENTS + STYLED SYSTEM = SUPER POWER PART I

This is a multi-part series of articles where I am going to show you how we can leverage the power of styled-components and styled-system to create reusable, efficient components. We are in components age of Frontend. We can relate a component to lego. Similar to legos we can have small reusable components that can be attached to build bigger components which can be further combined with other components to create amazing things. Let’s start with styled-components at first.

Add the styled-components package to your project.

yarn add styled-components
styled-components utilizes tagged template literals to style your components. To get a better understanding Let’s create a simple Text Component.

import styled from 'styled-components';

const Text = styled.p`
  color: orange;
  font-size: 20px;
  font-weight: bold;
  letter-spacing: 0.5px;
`;

Alt Text
In the above example, we are extending the existing p tag from HTML DOM. And giving it more styles. For those of you who don’t know what () means herein styled components. It’s called template literal. Whenever you extend a tag or a component by styled components it returns a React Component. This React Component is exactly like normal components and behaves same. To understand more let’s try to create a button component.

const Button = styled.button`
  background: orange;
  color: white;
  font-size: 15px;
  padding: 10px 30px;
  border: none;
  border-radius: 3px;
  font-weight: 500;
  margin: 20px;
`;

const App = () => props => <Button>Hello World</Button>

Alt Text
From this you can imagine how easy it is to create a reusable component with styled-components. However, there seems to be one problem. React components are customizable their behavior can be controlled by passing props to them. How good is a styled-component if it cannot be easily customizable. In the next phase, we will learn how to make this component accept and behave according to the props.

ACCEPTING PROPS:
Before making a component able to accept props, it’s important to figure out the key styles that define a component. In case of a button those styles can be background and text color (possibly outline, solid states if you want something advanced).

Styled-components allows us access to the prop values component receives. With this, we can modify the key styles based on props. Let’s try to modify the button component so that we can respond to the props and create different variants of a button.

const Button = styled.button`
  background: ${props => (props.bg ? props.bg : "orange")}
  color: white;
  font-size: 15px;
  padding: 10px 30px;
  border: none;
  border-radius: 3px;
  font-weight: 500;
  margin: 20px;
`;

const App = () => (
 <div>
   <Button bg="#FF595E">Danger Button</Button>
   <Button>Default Button</Button>
 </div>
);

Alt Text
We are now not hardcoding the background of the button component instead we have passed a function which checks if a prop called bg exists. if it exists we are going to use it as a background else we are going to go with a default orange. Now we have a button component that accepts a bg (background) prop. We can create a lot of components similarly. If you want to optimize the function we wrote for the background you can simply write this:

background: ${props => props.bg};
The only problem with this syntax is that you always need to pass bg prop whenever you use this component else the background won’t be set. One of the easiest ways to fix this to use default props.

Button.defaultProps = { bg: 'orange' };
This always provides a default bg prop to the component so we don’t have to worry about passing a bg prop each time we use this component. This example seems pretty basics. But in real life projects, some components are very complex. I will show you an example of a component that allows us to modify a lot of key style elements.

import React from "react";
import styled from "styled-components";

const CardWrapper = styled.div`
  background: ${props => props.bg};
  width: 350px;
  margin: auto;
  padding-bottom: 20px;
  border-radius: ${props => props.borderRadius}px;
`;

const Image = styled.img`
  width: 100%;
  height: auto;
  border-radius: ${props =>
    `${props.borderRadius}px ${props.borderRadius}px 0 0`};
`;

const Title = styled.h3`
  color: ${props => props.titleColor}
  margin: 0;
  padding: 15px;
`;

const Description = styled.p`
  color: ${props => props.textColor};
  padding: 0px 15px;
  margin: 0;
`;

const Card = ({
  image,
  title,
  description,
  titleColor,
  textColor,
  borderRadius,
  ...props
}) => (
  <CardWrapper borderRadius={borderRadius} {...props}>
    <Image src={image} borderRadius={borderRadius} alt={title} />
    <Title titleColor={titleColor}>{title}</Title>
    <Description textColor={textColor}>{description}</Description>
  </CardWrapper>
);

Card.defaultProps = {
  bg: "white",
  titleColor: "#1982c4",
  textColor: "#999",
  borderRadius: 5
};

const App = () => (
 <Card
  image="assets/react-image.png"
  title="Card Title"
  description="Lorem ipsum dolor sit amet, consectetur adipiscing"
 />
);

Alt Text
This is just an example to show how we can use multiple styled components to create bigger reusable components. We can add a lot of additional features to this component to make it more customizable. In the next part, I will share you how we can eliminate writing all those mini functions inside styled-components and create a reusable component in a better, faster and efficient way. Part 2

Top comments (2)

Collapse
 
amankumarsingh01 profile image
Aman Kumar Singh

Can you please elaborate about best practice for using styled-components?

Collapse
 
shivashp profile image
Shiva Pandey

Styled components itself is very clear, but just few things you need to consider are:

  • Not every style needs to be customisable some can be hardcoded based on the component
  • Avoid nesting styles as much possible. for e.g don't nest a p tag inside a div within styled component.
  • Styled components works really well if you have a design system. Try to reuse as much possible.