Styled components
Tags: react, css, javascript, styledcomponents
Published: 2022-09-20 22:10:20

## What is styled components

When it comes to styling React components, there are a few different approaches that you can take. One popular approach is using styled-components, a CSS-in-JS library that lets you write CSS rules that are scoped to a particular component. This means that your CSS will only affect the specific component that you're working on and not any other parts of your app.

Styled-components makes it easy to reuse React components that have their own styles.They're great for building user interfaces that look consistent and clean, without having to worry about CSS classes and inline styles.

Creating a styled component is easy - just use the `styled` function from the `styled-components` library, and pass in a React component. For example, to style the `<Button>` component:

```jsx
const Button = styled.button`
   background-color: red;
   color: white;
   font-size: 16px;
   padding: 20px;
`;
```

You can then use the styled component like any other React component:

```jsx
<Button>Click me!</Button>
```

Styled components are easy to customize and extend. In the example above, we could add a new style to the `Button` component by using the `extend` method:

```jsx
const ExtendedButton = Button.extend`
  border: 2px solid black;
}
```

We could also add a new style to all buttons by using the `createGlobalStyle` function:

```jsx
const GlobalStyle = createGlobalStyle`
  button {
    border: 2px solid black;
  }
}`;
```

Now all buttons will have a black border, regardless of how they're styled.


## Advantages of Styled-components

1. It makes your code more readable and easier to understand.

2. It solves CSS problem of selector name collisions

2. It can help you keep your code DRY (Don't Repeat Yourself).

3. It makes it easy to change the look and feel of your component without having to change the actual implementation of your component.

4. It comes with a built-in theme provider, so you can easily change the look and feel of your entire application with a single theme.

5. It is easy to unit test because you don't have to worry about the style rules leaking into your tests.

6. It is easy to integrate with other libraries, such as React Router or Redux.

7. It is small and fast, so it won't slow down your application.

8. The library has a great community and support.


## Disadvantages of Styled-components

1. Styled-components creates a lot of extra markup that can bloat your code and make it more difficult to read.
2. The library is relatively new, so there is less community support than for other CSS-in-JS libraries.
3. Styled-components doesn't support server-side rendering out of the box. You need to use a library like styled-components-ssr to handle this.
4. The library can be difficult to debug because of the way it generates CSS classes.


## Responsive Design with styled-components

You can use media queries to style components based on the size of the user's screen. This is especially useful for responsive design.

**CSS @media**

To do this, you first need to create a `media` object:


```jsx
const MyComponent = styled.div`
  color: red;
  @media (min-width: 768px) {
      color: blue;
  }
  @media (min-width: 992px) {
      color: green;
    }
}
```
This will make the text color red by default, blue on tablets, and green on desktop devices.

**_Functions_**
You can also use the `styled-components` media queries helper function to create media objects:

```jsx
import { css } from 'styled-components';

const media = {
tablet: (styles) => css`
  @media (min-width: 768px) {
    ${styles}
   }
  `,
  desktop: (styles) => css`
    @media (min-width: 992px) {
     ${styles}
  }
`,
};
```

Then, you can use the media object in your styled component:

```jsx
const MyComponent = styled.div`
  color: red;
  ${media.tablet(`color: blue;`)}
  ${media.desktop(`color: green;`)}
}
```

This has the same effect as the previous example.

**_`<Media/>` component_**

You can also use the `styled-components` `<Media/>` component to style components based on the size of the user's screen. The `Media` component takes a `query` prop which is a media query, and children which are the styles to apply when the query matches.

For example, this will make the text color red by default, blue on tablets, and green on desktop devices:

```jsx
import { Media } from 'styled-components';

const MyComponent = () => (
<div>
  <Media query="(max-width: 767px)">
    {(matches) => {
     if (matches) {
      return <p>This is a mobile phone</p>;
     } else {
      return null;
     }
   }}
  </Media>

<Media query="(min-width: 768px) and (max-width: 991px)">
{(matches) => {
 if (matches) {
   return <p>This is a tablet</p>;
 } else {
   return null;
 }
}}
</Media>

<Media query="(min-width: 992px)">
  {(matches) => {
    if (matches) {
     return <p>This is a desktop</p>;
    } else {
     return null;
   }
  }}
</Media>
</div>
);
```

**`styled-media` Library.**

Another options to implement responsive styles is `styled-media` library. It provides a simple API for creating media queries in your component styles.

First, install `styled-media`:

```
npm install --save styled-media-query

```

Then, import it in your component:

```jsx
import styled from 'styled-components'
import { breakpoint } from 'styled-media-query'
```

Now you can use media queries in your styles, like this:

```jsx
const Container = styled.div`
  width: 100%;
  ${breakpoint('medium')`
    width: 50%;
 `}
`;
```

This will make the `Container` component have a `width` of `100%` on all screen sizes, and a `width` of `50%` on medium screens and above.

You can also use the `min-width` and `max-width` aliases:

```jsx
const Container = styled.div`
  ${breakpoint('medium', 'max-width')`
    width: 50%;
  `}
`;
```

This will make the `Container` component have a `width` of `50%` on medium screens and below.

You can also use the `orientation` alias to target specific orientations:

```jsx
const Container = styled.div`
  ${breakpoint('medium', 'orientation', 'landscape')`
    width: 50%;
  `}
`;
```

This will make the `Container` component have a `width` of `50%` on screens that are both `medium` and in `landscape` orientation.

## Global Style

Styled-components is a great way to create modular and reusable component designs. However, sometimes you need to create global styles that can be applied to all components on the page. This is where **createGlobalStyle** comes in.

**CreateGlobalStyle** is a function that accepts CSS and returns a component. That component will inject the CSS into the page when rendered.

Here is an example:


```jsx
import React from "react"
import { createGlobalStyle } from "styled-components"
const GlobalStyle = createGlobalStyle`
 body {
   color: ${props => (props.theme === "grey" ? "grey" : "white")};
 }
`
export default function Layout({ children }) {
 return (
   <React.Fragment>
     <GlobalStyle theme="grey" />
     {children}
   </React.Fragment>
 )
}
```

It's important to note that **createGlobalStyle** does not support interpolation like the styled component methods. If you need interpolation, you can use a regular CSS template literal.

**CreateGlobalStyle** is great for setting global variables, such as colors, fonts, or margins. It's also a good way to reset the browser's default styles.

If you're using **createGlobalStyle** in a React project, you'll need to make sure to wrap it in a component so that it only renders once. Otherwise, your styles will be injected every time the component renders.


## Using className with styled-components

As we saw in the previous section, styled-components allow us to style our components using the template literal syntax. We can also use the className property to add class names to our styled components.

For example, let's say we have a styled component like this:

```jsx
const Button = styled.button`
 background-color: blue.;
 border: none;
 border-radius: 3px;
 color: white;
 padding: 10px 15px;
`;
```

If we want to add a class name to this component, we can do so like this:

```jsx
<Button className="button">
 Click me!
</Button>
```

Then we can create our own CSS styles using the class name ".button". The stylesheet used by the end user won't be impacted if your CSS-in-JS style changes.

```css
.button {
 margin: 5rem auto;
 font-size: 1.3rem;
}

```

Now our button will have the class "button" in addition to the styles defined by the styled component. We can use this to apply additional styling to our components if needed.


## Conclusion

So far we've looked at advantages and disadvantages of styled-components, and how to use it to style our React components. We've also seen how to use media queries and other advanced features to make our styles more responsive.

Styled-components library is a great way to style React components. It's easy to use and has a lot of powerful features. It helps to avoid css selectors name collision and helps to separate UI logic from business logic. If you're looking for a way to make styles in your React application more readable and maintainable, definitely check out styled-components!