Skip to content

Instantly share code, notes, and snippets.

@jacobparis
Last active March 24, 2022 21:48
Show Gist options
  • Save jacobparis/4cc548459d0c5d293ab1be4566438f47 to your computer and use it in GitHub Desktop.
Save jacobparis/4cc548459d0c5d293ab1be4566438f47 to your computer and use it in GitHub Desktop.

Simply and easily with Styled components npm install styled-components

Thats all you need to do. Really! That’s why I love it! No Babel, no Webpack, no CSS pre or post processing. Only JavaScript and nothing else.

CSS in JS

“You mean CSS in JS? Man, that’s weird. I would never do that!” Don’t panic. Just let me show you few examples why this is a great idea. But let’s write some Styled component first:

import styled from 'styled-components;
const Title = styled.h1`
  font-size: 18px;
`;

The styled variable contains many functions representing all known HTML elements. The strange h1`` syntax is a tagged template literal. And it’s nothing else then a call of this function: h1('') Usage is the same like in case of any React component:

<Title>I'm styled and I know it!</Title>

Be aware that Styled components works only with React.

Props

“Wait a moment… And what about props?” It’s the powerful part. Here we go:

const Button = styled.button`
  background: ${props => props.primary ? 'green' : 'gray'};
`;
<Button primary>Click me!</Button>

All the arrow functions used inside the template string provides the props variable. So you can pass any value into resulting stylesheet. In other words, it’s not only intended to pass the values of CSS properties. It may be also handy to do the stuff like this:

import styled, { css } from 'styled-components;

const Position = styled.div`
  position: absolute;
  ${({ side, value }) => css`
    ${side}: ${value};
  `}
`;

<Position side="right" value="50%">
  I'm positioned!
</Position>

Snippets

“What is the css variable above?” It’s a helper for creating CSS snippets. It’s useful when you need to return some piece of CSS code. Or when you repeat some CSS over and over again. In that case just do this:

const underlineOnHover = css`
  text-decoration: none;
  :hover {
    text-decoration: underline;
  }
`;

Then use it in any component you need:

const Link = styled.a`
  color: green;
  ${underlineOnHover};
`;

(No) classes

“But… how the hack you add classname attributes? I want to be able to change styles of the component nested in another component” Forget about classes! You don’t need them anymore. Just target the component like this:

const Button = styled.button`
  ${Icon} {
    width: 20px;
  }
`;

You can do this under one of these conditions: Icon is also Styled component or Icon is not Styled but passes classname prop to it’s inner element. Like Link component from react-router for example. Classes are unnecessary step between HTML and CSS. You don’t need to conditionally apply multiple classes to components according to props. You just conditionally compose the CSS directly based on props. Don’t take me wrong. In the code rendered in a browser the classes are still used of course. But those are generated on the fly and you don’t need to care about them. It looks like this:

.cAqXJf {
  padding: 10px;
}

Debugging

“Common, that’s horrible! How do you debug the CSS in browser? You don’t know which component this gibberish class belongs to!” Well, you are right. You don’t know. Remember I mentioned that you don’t have to setup Babel with Styled components? Here is one exception. There is babel-plugin-styled-components. When setup, you’ll see readable class names in browser like this:

<div class="ProductList-cAqXJf">...</div>

Supported CSS features

“That starts to be interesting. But I bet I’ll find something that’s not possible with Styled components. How do you handle pseudo-selectors and pseudo-elements, huh?” Well, the similar way like in plain CSS:

const Link = styled.a`
  :hover {
    color: orange;
  }
  :before {
    content: 'styled components are awesome'
  }
`;

To sum it up, everything you can do in CSS can be done in Styled components. Media queries, animation keyframes, gradients, transformations… everything works out of the box.

Global styles

“I got it! Global styles! I knew I’ll find something! You can’t do that! You can’t make or elements as Styled!” Well, you can’t make as Styled, but creators of Styled components didn’t forget about this. Don’t worry. You can also use custom fonts easily if you want. As is shown in official docs:

import { injectGlobal } from 'styled-components';
injectGlobal`
  @font-face {
    font-family: "Operator Mono";
    src: url("../fonts/Operator-Mono.ttf");
  }

  body {
    margin: 0;
  }
`;

SSR and performance

“You got me. And what about server-side rendering?” It’s also well supported. So don’t worry that user will see unstyled page before everything is loaded. And the advantage is, that the CSS is part of the JS component. So from performance perspective: You load everything in single bundle. You load only styles of those components you really need.

React native

“But I’m developing mainly mobile apps in React Native, so it’s not for me anyway…” Surprise, surprise! Styled components works in React Native too. No worries.

import styled from 'styled-components'
const View = styled.View`
  display: flex;
`;

You can event create set of platform-independent Styled components. And then use them on the web, iOS, Android, etc. I will show you how to do this in one of my upcoming articles! Theming “Wow, it sounds great! Maybe I will consider Styled components for my next project.” I will give you one reason to definitely try it. This is my favourite part. Styled components supports theming out-of-the box:

import styled, { ThemeProvider } from 'styled-components';
const theme = {
  colors: {
    primary: '#4e812b',
    secondary: '#ee921a'
  }
}
const App = props => (
  <ThemeProvider theme={theme}>
    {props.children}
  </ThemeProvider>
);

Now you have theme prop available in any nested components of your app.

const Button = styled.button`
  background: ${({ theme, primary }) => (
    primary ? theme.color.primary : theme.color.secondary
  )};
`;
<Button primary>Click me!</Button>

Changing primary or secondary colour (or whatever you pass through) is now very simple. Across your whole app. #Extending styles Another super-useful feature is possibility to extend the styles of any component easily.

import styled from 'styled-components';
import Button from './Button';
const DisabledButton = styled(Button)`
  background: gray;
  cursor: not-allowed;
`;

This will merge the styles of original component with your new styles.

And more…

There are much more possibilities what you can do with Styled components. Just check the official documentation.

Caveats

There are few things which can surprise you in Styled components.

Nested elements

One of them is that you can’t create single Styled component returning more then one HTML element as children. Styled component = single HTML element (or native element in case of React Native). But solution is simple, if you need component with more complicated structure. Just create normal React component composed of multiple Styled components.

const Wrapper = styled.div`
  display: flex;
`;
const Left = styled.div`
  flex-grow: 1;
`;
const Right = styled.div`
  flex-grow: 2
`;
const Layout = props => (
  <Wrapper>
    <Left>Left column</Left>
    <Right>Right column</Right>
  </Wrapper>
);

#Less readable HTML

I already mentioned this above. The rendered HTML contains randomly generated class names by default. But the babel-plugin-styled-components is quite easy to setup and solves this issue.

Syntax support in editors

Some IDEs and source code editors might be confused about the template literals syntax. But there are usually some plugins for that. Some editor supports the CSS highlighting and suggestions by default.

React only

Styled components support only React. You have to find another way if you use different JS framework.

Summary

There are many ways, how to approach CSS in web (and mobile) apps. One of them is CSS-in-JS. In my opinion Styled components are one of the most simple and powerful CSS tools for component based React apps. Styled components removes classes as unnecessary step between HTML and CSS. Why adding multiple classes conditionally based on props? You can just conditionally compose CSS directly, based on props. It supports all the CSS features out of the box. Also React Native is well supported. That’s why Styled components are ideal for creating library of platform-independent components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment