While the component-driven approach has ushered in a new frontier in the way we build web applications, it isn’t without its imperfections — one being its usability and scalability with CSS. This has given birth to a new way to construct and manage our styles in a component-specific manner, otherwise knows as CSS-in-JS.

Styled components are a CSS-in-JS tool that bridges the gap between components and styling, offering numerous features to get you up and running in styling components in a functional and reusable way. In this article, you’ll learn the basics of styled components and how to properly apply them to your React applications. You should have worked on React previously before going through this tutorial.

At the core of CSS is the capability to target any HTML element — globally — no matter its position in the DOM tree. This can be a hindrance when used with components, because components demand, to a reasonable extent, colocation (i.e. keeping assets such as states and styling) closer to where they’re used (known as localization).

In React’s own words, styled components are “visual primitives for components”, and their goal is to give us a flexible way to style components. The result is a tight coupling between components and their styles.

Note: Styled components are available both for React and React Native, and while you should definitely check out the React Native guide, our focus here will be on styled components for React.

Why Styled Components?

Apart from helping you to scope styles, styled components include the following features:

  • Automatic vendor prefixing
  • You can use standard CSS properties, and styled components will add vendor prefixes should they be needed.
  • Unique class names
  • Styled components are independent of each other, and you do not have to worry about their names because the library handles that for you.
  • Elimination of dead styles
  • Styled components remove unused styles, even if they’re declared in your code.
  • and many more.

Installation

Installing styled components is easy. You can do it through a CDN or with a package manager such as Yarn…

yarn add styled-components

… or npm:

npm i styled-components

Our demo uses create-react-app.

Starting Out

Perhaps the first thing you’ll notice about styled components is their syntax, which can be daunting if you don’t understand the magic behind styled components. To put it briefly, styled components use JavaScript’s template literals to bridge the gap between components and styles. So, when you create a styled component, what you’re actually creating is a React component with styles. It looks like this:

import styled from "styled-components";

// Styled component named StyledButton
const StyledButton = styled.button`
  background-color: black;
  font-size: 32px;
  color: white;
`;

function Component() {
  // Use it like any other component.
  return <StyledButton> Login </StyledButton>;
}

Here, StyledButton is the styled component, and it will be rendered as an HTML button with the contained styles. styled is an internal utility method that transforms the styling from JavaScript into actual CSS.

In raw HTML and CSS, we would have this:

button {
  background-color: black;
  font-size: 32px;
  color: white;
}

<button> Login </button>

If styled components are React components, can we use props? Yes, we can.

Adapting Based on Props

Styled components are functional, so we can easily style elements dynamically. Let’s assume we have two types of buttons on our page, one with a black background, and the other blue. We do not have to create two styled components for them; we can adapt their styling based on their props.

import styled from "styled-components";

const StyledButton = styled.button`
  min-width: 200px;
  border: none;
  font-size: 18px;
  padding: 7px 10px;
  /* The resulting background color will be based on the bg props. */
  background-color: ${props => props.bg === "black" ? "black" : "blue";
`;

function Profile() {
  return (
    <div>
      <StyledButton bg="black">Button A</StyledButton>
      <StyledButton bg="blue">Button B</StyledButton>
    </div>
  )
}

Because StyledButton is a React component that accepts props, we can assign a different background color based on the existence or value of the bg prop.

You’ll notice, though, that we haven’t given our button a type. Let’s do that:

function Profile() {
  return (
    <>
      <StyledButton bg="black" type="button">
        Button A
      </StyledButton>
      <StyledButton bg="blue" type="submit" onClick={() => alert("clicked")}>
        Button B
      </StyledButton>
    </>
  );
}

Styled components can differentiate between the types of props they receive. They know that type is an HTML attribute, so they actually render <button type="button">Button A</button>, while using the bg prop in their own processing. Notice how we attached an event handler, too?

Speaking of attributes, an extended syntax lets us manage props using the [attrs](https://styled-components.com/docs/api#attrs) constructor. Check this out:

const StyledContainer = styled.section.attrs((props) => ({
  width: props.width || "100%",
  hasPadding: props.hasPadding || false,
}))`
  --container-padding: 20px;
  width: ${(props) => props.width}; // Falls back to 100%
  padding: ${(props) =>
    (props.hasPadding && "var(--container-padding)") || "none"};
`;

Notice how we don’t need a ternary when setting the width? That’s because we’ve already set a default for it with width: props.width || "100%",. Also, we used CSS custom properties because we can!

Note: If styled components are React components, and we can pass props, then can we also use states? The library’s GitHub account has an issue addressing this very matter.

Extending Styles

Let’s say you’re working on a landing page, and you’ve set your container to a certain max-width to keep things centered. You have a StyledContainer for that:

const StyledContainer = styled.section`
  max-width: 1024px;
  padding: 0 20px;
  margin: 0 auto;
`;

Then, you discover that you need a smaller container, with padding of 10 pixels on both sides, instead of 20 pixels. Your first thought might be to create another styled component, and you’d be right, but it wouldn’t take any time before you realize that you are duplicating styles.

const StyledContainer = styled.section`
  max-width: 1024px;
  padding: 0 20px;
  margin: 0 auto;
`;

const StyledSmallContainer = styled.section`
  max-width: 1024px;
  padding: 0 10px;
  margin: 0 auto;
`;

Before you go ahead and create StyledSmallContainer, like in the snippet above, let’s learn the way to reuse and inherit styles. It’s more or less like how the spread operator works:

const StyledContainer = styled.section`
  max-width: 1024px;
  padding: 0 20px;
  margin: 0 auto;
`;

// Inherit StyledContainer in StyledSmallConatiner
const StyledSmallContainer = styled(StyledContainer)`
  padding: 0 10px;
`;

function Home() {
  return (
    <StyledContainer>
      <h1>The secret is to be happy</h1>
    </StyledContainer>
  );
}

function Contact() {
  return (
    <StyledSmallContainer>
      <h1>The road goes on and on</h1>
    </StyledSmallContainer>
  );
}

In your StyledSmallContainer, you’ll get all of the styles from StyledContainer, but the padding will be overridden. Keep in mind that, ordinarily, you’ll get a section element rendered for StyledSmallContainer, because that’s what StyledContainer renders. But that doesn’t mean it’s carved in stone or unchangeable.

#react #css #developer #javascript

How To Use Styled-Components In React
1.70 GEEK