Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress πŸ’…

  • By styled-components
  • Last update: Jan 4, 2023
  • Comments: 17

Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress πŸ’…

downloads: 600k/month Discord gzip size module formats: umd, cjs, esm Code Coverage

Looking for v5?

The main branch is under development of the upcoming v6 major version of styled-components. For changes targeting v5, please point your PRs at the legacy-v5 branch.


Utilising tagged template literals (a recent addition to JavaScript) and the power of CSS, styled-components allows you to write actual CSS code to style your components. It also removes the mapping between components and styles – using components as a low-level styling construct could not be easier!

const Button = styled.button`
  color: grey;
`;

Alternatively, you may use style objects. This allows for easy porting of CSS from inline styles, while still supporting the more advanced styled-components capabilities like component selectors and media queries.

const Button = styled.button({
  color: 'grey',
});

Equivalent to:

const Button = styled.button`
  color: grey;
`;

styled-components is compatible with both React (for web) and React Native – meaning it's the perfect choice even for truly universal apps! See the documentation about React Native for more information.

Supported by Front End Center. Thank you for making this possible!

Upgrading from v4

  1. npm install styled-components@^5.0.0 react@^16.8 react-dom@^16.8 react-is@^16.8
  2. ??
  3. Profit!

If you use jest-styled-components, make sure you update that too.

Docs

See the documentation at styled-components.com/docs for more information about using styled-components!

Quicklinks to some of the most-visited pages:

Example

import React from 'react';

import styled from 'styled-components';

// Create a <Title> react component that renders an <h1> which is
// centered, palevioletred and sized at 1.5em
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

// Create a <Wrapper> react component that renders a <section> with
// some padding and a papayawhip background
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

// Use them like any other React component – except they're styled!
<Wrapper>
  <Title>Hello World, this is my first styled component!</Title>
</Wrapper>

This is what you'll see in your browser:

Babel Macro

If you're using tooling that has babel-plugin-macros set up, you can switch to the styled-components/macro import path instead to gain the effects of the babel plugin without further setup.

import styled from 'styled-components/macro';

// A static className will be generated for Title (important for SSR)
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

If you wish to provide configuration options to the babel plugin similar to how you would in a .babelrc, see this guide. The config name is "styledComponents".

Built with styled-components

A lot of hard work goes into community libraries, projects, and guides. A lot of them make it easier to get started or help you with your next project! There’s also a whole lot of interesting apps and sites that people have built using styled-components.

Make sure to head over to awesome-styled-components to see them all! And please contribute and add your own work to the list so others can find it.

Contributing

If you want to contribute to styled-components please see our contributing and community guidelines, they'll help you get set up locally and explain the whole process.

Please also note that all repositories under the styled-components organization follow our Code of Conduct, make sure to review and follow it.

Badge

Let everyone know you're using styled-components β†’ style: styled-components

[![style: styled-components](https://img.shields.io/badge/style-%F0%9F%92%85%20styled--components-orange.svg?colorB=daa357&colorA=db748e)](https://github.com/styled-components/styled-components)

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Backers

Thank you to all our backers! πŸ™ [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

License

Licensed under the MIT License, Copyright Β© 2016-present Glen Maddern and Maximilian Stoiber.

See LICENSE for more information.

Acknowledgements

This project builds on a long line of earlier work by clever folks all around the world. We'd like to thank Charlie Somerville, Nik Graf, Sunil Pai, Michael Chan, Andrey Popp, Jed Watson & Andrey Sitnik who contributed ideas, code or inspiration.

Special thanks to @okonet for the fantastic logo.

Github

https://github.com/styled-components/styled-components

Comments(17)

  • 1

    Separate HTML attributes from styling props

    Background

    I am trying to style a 3rd party "masked" input. The styles are applied correctly, however, there are props I pass into the "styled" element that are used within the CSS logic of the styled component that I don't want passed down to the 3rd party input. This logs an error saying there are undesired props being put on the input (this is also an issue with the 3rd party component that isn't properly stripping out what should go on the input).

    I could see it being an enhancement where we specify what props to terminate at the "styled" part. However, this also could just be looked at as the 3rd party component having an issue not removing those props. I'm fine with it being an issue with the 3rd party developer but just wanted to mention the issue and see if this is happening to other people and if it is worth it to build some extra logic in.

    Screenshot

    screen shot 2017-01-31 at 11 31 51 am

  • 2

    v4 beta constructive feedback

    Please provide as much detail as possible when commenting here so we can help! A huge amount of time and thought has been put into the API changes. We know it won't be a "flip a switch" situation, but the ergonomics of the library going forward should be markedly better and more flexible.

  • 3

    Discuss SSR API and methods

    I just want to kick off a discussion to finalise our SSR API.

    So API came from the comments on the #214

    const { css, html } = StyleSheet.collect(() =>
      ReactDOMServer.renderToString(<App />)
    );
    

    Please feel free to suggest what the API will look like, (let the bikeshedding begin!)

    Also if we're already doing de-duping in SSR level, do we even need reset()? (related issue #378) Or would that just be a convenience function since we don't need it anymore?

    cc @mxstbr / @geelen

  • 4

    How do I provide props to styled elements in Typescript?

    I looked at the docs and other than creating a whole empty component purely for providing a definition of props I'm not sure of if it's possible to provide custom props to a styled element other than theme.

    Example

    image

    For the above example I don't know how to make it not error.

  • 5

    Use insertRule in browser

    Premlinary patch for using insertRule api. Seems to help performance quite a bit, but the implementation is kind of hacky. I'm just using a naive regexp to split up rules but I'm looking to use a stylis middleware (@mxstbr has suggested looking into https://github.com/thysultan/stylis.js/issues/59 and https://github.com/threepointone/glam/issues/5 for reference)

    Edit by @philpl: Updated to respect and enforce component order (out of order injection) and to rehydrate into a new SpeedyBrowserTag purely using insertRule. This also removes a couple of APIs from the BrowserTags that are not needed in production.

  • 6

    Deprecate .extend in favour of only styled(Component)

    The FAQ explains the difference between styled() and .extend. However I wonder if it would be possible to take the decision out of the devs hand and have styled check for the handed in Component if its already a styled component. If it is .extend it otherwise create a new class.

    Was this considered at one point?

  • 7

    5.0 Roadmap

    Test it out:

    npm install styled-components@beta react@^16.8 react-dom@^16.8 react-is@^16.8
    

    5.0 milestone

    • [x] ~~rewrite stylesheet + tag classes for the needs of today (#2522)~~
    • [x] ~~move react-is to peer dependencies (https://github.com/styled-components/styled-components/pull/2187)~~
    • [x] ~~use react v16.7+ hooks to simplify the context consumer architecture (#2390)~~
    • [x] ~~babel 7 migration (maybe... there were bundle size regressions before) (#2509)~~
    • [x] ~~internal rewrite to use hooks (#2390)~~
    • [x] ~~bump minimum versions of react, react-native to hooks-compatible versions~~
    • [x] ~~remove code paths deprecated in v4 (https://github.com/styled-components/styled-components/pull/2604)~~
    • [x] ~~fix cGS style clobbering issues (https://github.com/styled-components/styled-components/pull/2824)~~

    5.1 candidate

    • [ ] stylis -> sweetsour (depending on when it's ready for use and testing)
    • [ ] figure out CSP / nonce support (#2363)
    • [ ] solution to drop the prop whitelist (https://github.com/styled-components/styled-components/pull/2093)
    • [ ] source maps for styles (https://github.com/styled-components/styled-components/issues/827)
    • [ ] scoping of styles via StyleSheetManager (https://github.com/styled-components/styled-components/issues/1789)

    didn't do

    • [ ] ~~use React.warn and React.error if 16.9 comes out before v5 (https://github.com/styled-components/styled-components/issues/2584)~~ React removed them

    follow along on the ~canary~ v5 branch

    evolving

  • 8

    v2 prerelease feedback

    If you're using the v2 pre-release, please let us know in a comment below if it works well for you! If you encounter bugs, please submit individual issues for them!

    To try the v2 prerelease, use npm install styled-components@next babel-plugin-styled-components and add the plugin to your Babel configuration like a regular Babel plugin. The plugin is optional as it only provides consistent naming for SSR as well as some pre-processing.

  • 9

    Babel transform

    ~~We need a way (probably babel transform?) to extract and precompile the static styles of our components!~~

    Extracting static styles is actually not what we want, we want to pre-parse the CSS in a build step but leave it in the JS: See this comment

    Has anybody done this before? I know I haven't…

  • 10

    SSR Memory Leak with v5 release candidate 2

    Environment

    Default, Baseline

    ## System:
     - OS: macOS 10.15
     - CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
     - Memory: 3.11 GB / 32.00 GB
     - Shell: 5.6.2 - /usr/local/bin/zsh
    ## Binaries:
     - Node: 10.15.1 - ~/.nvm/versions/node/v10.15.1/bin/node
     - Yarn: 1.19.1 - ~/****/****/applications/site/node_modules/.bin/yarn
     - npm: 6.4.1 - ~/.nvm/versions/node/v10.15.1/bin/npm
    ## npmPackages:
     - babel-plugin-styled-components: ^1.10.0 => 1.10.6
     - styled-components: ^4.0.0 => 4.4.1
    

    After upgrade to RC 2

    ## System:
     - OS: macOS 10.15
     - CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
     - Memory: 3.11 GB / 32.00 GB
     - Shell: 5.6.2 - /usr/local/bin/zsh
    ## Binaries:
     - Node: 10.15.1 - ~/.nvm/versions/node/v10.15.1/bin/node
     - Yarn: 1.19.1 - ~/****/****/applications/site/node_modules/.bin/yarn
     - npm: 6.4.1 - ~/.nvm/versions/node/v10.15.1/bin/npm
    ## npmPackages:
     - babel-plugin-styled-components: ^1.10.0 => 1.10.6
     - styled-components: ^5.0.0-rc.2 => 5.0.0-rc.2
    

    Notes: Both environments use TypeScript, Next.JS and latest versions of react

    Steps to Reproduce

    1. Use the _document.js file found in the with-styled-components example of next.js.
    2. Have styled-components 4.4.1 installed.
    3. Run application using N|Solid from nodesource. Also could probably get this information by attaching chrome inspector to node.
    4. Run npx loadtest -c 5 --rps 10 -k -t 90 http://localhost:8080/
    5. See that memory usage has peaks and valleys, RSS and Heap memory allocation move together. External memory barely moves.
    6. install release candidate 2
    7. repeat the steps above.
    8. See that Heap allocation remains consistent, MORE consistent than in 4.4.1, but RSS and External memory allocation seem to climb indefinitely until the application crashes under load.
    9. Look at memory snapshot and see that ServerStyleSheet is massive, at around 2 gigabytes, and the server is holding onto array buffers and strings that seem to reference styles.

    Memory Timeline In N|Solid on version 4.4.1

    heapsnapshot image

    Memory Timeline in N|Solid on Version 5 RC 2

    heapsnapshot image

    Comparison of Heap snapshots

    image

    RC 2 is on the left. The snapshots were taken as close to the same point as possible (immediately following the load test that was run with the same stats: 5 concurrent threads, keep-alive connections, 10 requests per second for 90 seconds). The only change between the two is upgraded to RC 2.

  • 11

    Server Side Rendering: First paint missing some styles (FOUC)

    Environment

    System:

    • OS: macOS High Sierra 10.13.5
    • CPU: x64 Intel(R) Core(TM) i5-4308U CPU @ 2.80GHz
    • Memory: 82.71 MB / 8.00 GB
    • Shell: 3.2.57 - /bin/bash

    Binaries:

    • Node: 8.9.4 - ~/.nvm/versions/node/v8.9.4/bin/node
    • npm: 6.1.0 - ~/temp/Martin/metrics-dashboard/node_modules/.bin/npm
    • Watchman: 4.7.0 - /usr/local/bin/watchman

    npmPackages:

    • babel-plugin-styled-components: ^1.5.1 => 1.5.1
    • styled-components: ^3.2.6 => 3.2.6

    Reproduction

    The chunk of server side rendering code used:

            const sheet = new ServerStyleSheet()
            let html = ReactDOMServer.renderToString(sheet.collectStyles(
              <Provider store={store}>
                {<RouterContext {...renderProps} />}
              </Provider>
            ))
            const styleTags = sheet.getStyleTags() // or sheet.getStyleElement()
    

    My index template (index.ejs) as such:

    <!DOCTYPE html>
    <html>
    
    <head>
      <%- styleTags %>
    </head>
    <body style="margin: 0; font-family: 'PT Sans', Arial;">
      <div id="root" style="height: 100%;">
        <%- html %>
      </div>
      <script type="text/javascript" charset="utf-8">
        window.__REDUX_STATE__ = '<%= reduxState %>';
      </script>
    
    </body>
    </html>
    

    And just in case some styled-component code, though I don't expect this to be the issue (possibly because of using extend?).

    //   H1.js file
    
    import styled from 'styled-components';
    
    const H1 = styled.h1.attrs({ className: 'h1' })`
        font-size: 4rem;
    `;
    
    export default H1;
    
    //   end of H1.js file
    
    //   WidgetTitle.js file
    import NormalH1 from "components/H1";
    
    const WidgetTitle = NormalH1.extend.attrs({ className: 'widget__title' })``;
    
    export default WidgetTitle;
    
    //   end of WidgetTitle.js file
    

    Steps to reproduce

    1. Server side rendering set up as shown above, following closely the steps here: https://www.styled-components.com/docs/advanced#server-side-rendering.

    Expected Behavior

    For all styles to be applied during first paint (like so below).

    First paint expected

    Actual Behavior

    Only some styles being applied on first paint, while some rules (specifically font-size) seems to be applied only after the JS bundle is parsed and executed.

    first paint missing font size rules

    Remarks

    As you can see in the two screenshots, I get a flash of content where the font-size rule isn't respected. I had this same issue with font-family actually, but dealt with it by putting it as an inline style on my <body> tag. Possibly this is a Flash of Unstyled Text (FOUT), but I'm honestly quite lost as to why these specific rules are being ignored on the first paint.

    I state that the rules seem to be applied only after the main JS bundle is loaded/parsed/executed because of examining the request for app.js closely in the Chrome Network panel. Is this possible a webpack issue where I need to optimize the bundle further?

  • 12

    global styles in next.js 13

    I am using Next.js 13 and followed the official docs to introduce styled-components in my project https://beta.nextjs.org/docs/styling/css-in-js

    this is what my layout.tsx looks like that lives in /app

    import { ToastContainer, toast } from 'react-toastify';
    
    import StyledComponentsRegistry from './lib/registry';
    import GlobalStyles from '../styles/global_style';
    import Layout from '../layouts/App-Layout';
    
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html>
          <body>
            <GlobalStyles />
            <StyledComponentsRegistry>
              <Layout>
                {children}
              </Layout>
            </StyledComponentsRegistry>
          </body>
        </html>
      );
    }
    

    Doing that I get this error:

    Error: React.Children.only expected to receive a single React element child. But everything works perfectly!

    when I remove or when I put above the error disappears but then I see the page without the style for a second and then the global styles kick in after

    if I wrap everything inside

    that is inside the error also disappears but then it took a second to see the style after a refresh

  • 13

    customSyntax for Stylelint v14+

    Hi there πŸ‘‹ First of all, thanks again for all of your work maintaining Styled Components and the ecosystem, really amazing!

    Given the bleak situation with Stylelint v14+ and Styled Components / Emotion (TLDR: stylelint-processor-styled-components is deprecated and archived, @stylelint/postcss-css-in-js will probably be deprecated (second reference, third reference), it seems that one of the next releases will probably mean the end of working Stylelint tooling for Styled Components and Emotion.

    There's a lot of confusing information out there, but the best, least broken config for now is processors: ['stylelint-processor-styled-components'] + customSyntax: 'postcss-scss'.

    I would suggest the following things to avoid tooling breakages:

    1. As a first step towards keeping a healthy ecosystem, I would ask that Styled Components maintainers consider unarchiving the stylelint-processor-styled-components repo - I'm not suggesting to provide any support for this - it can be maintained by selected community members, but @alexander-akait's issue about deprecating the package does not seem valid anymore, now that @stylelint/postcss-css-in-js will be deprecated Screenshot 2022-12-20 at 11 40 15
    2. In a concerted effort with Styled Components, Emotion and Stylelint maintainers, a new customSyntax should be developed for Stylelint v14+ (this is the main point of this issue) - this may be potentially based on postcss-lit, @43081j even started on a customSyntax for Styled Components here
    3. Re-archive the stylelint-processor-styled-components repo once there is a stable customSyntax option that is not @stylelint/postcss-css-in-js

    cc @probablyup @alexandernanberg @SukkaW @mxstbr @agriffis (Styled Components maintainers) @emmatown @Andarist @srmagura (Emotion maintainers) @alexander-akait @ybiquitous @jeddy3 (Stylelint maintainers) @43081j (postcss-lit maintainer)

    Prior art:

    • https://github.com/styled-components/styled-components/issues/3607
    • https://github.com/styled-components/styled-components/discussions/3707
    • https://github.com/stylelint/stylelint-demo/issues/343
    • https://github.com/emotion-js/emotion/issues/2695

    Reproduction

    https://github.com/styled-components/styled-components/issues/3607#issuecomment-1321151513

    Steps to reproduce

    Try to reliably set up Stylelint v14+ with Styled Components or Emotion

    Expected Behavior

    It works reliably and easily with a non-deprecated, non-archived package

    Actual Behavior

    It works partially with deprecated and/or archived packages (but will probably break in the future)

  • 14

    Upgrading react dependency to 18.1

    Hi

    Im currently getting a dependency conflict issue with styled components. there is a small work around however it cause other issues for other dependencies.

    Is there way that the styled component repo can upgrade its react dependent to use react 18.1 and not 16.8?

    Environment

    System:

    • OS: macOS 12.6.1
    • CPU: (10) arm64 Apple M1 Pro
    • Memory: 84.59 MB / 32.00 GB
    • Shell: 5.8.1 - /bin/zsh

    Binaries:

    • Node: 18.9.0 - ~/.nvm/versions/node/v18.9.0/bin/node
    • Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    • npm: 9.1.3 - ~/.nvm/versions/node/v18.9.0/bin/npm
    • Watchman: 2022.12.12.00 - /opt/homebrew/bin/watchman

    Reproduction

    https://codesandbox.io/s/styled-components-base-gc367

    Steps to reproduce

    1. create react native repo using latest react version
    2. npm install styled components
    3. observe behaviour

    Expected Behavior

    Install with no issues

    Actual Behavior

    dependancy issue with react, using '>=16.8.0' in styled components and 18.1.0 in personal repo

    image

    image
  • 15

    css animation doesn't work if use CSSOM API

    Environment

    System:

    • OS: macOS 13.0.1
    • CPU: (8) arm64 Apple M1
    • Memory: 173.33 MB / 16.00 GB
    • Shell: 5.8.1 - /bin/zsh

    Binaries:

    • Node: 19.1.0 - /opt/homebrew/bin/node
    • Yarn: 1.22.17 - ~/Downloads/node_modules/.bin/yarn
    • npm: 8.19.3 - /opt/homebrew/bin/npm

    npmPackages:

    • styled-components: ^6.0.0-beta.6 => 6.0.0-beta.6

    Reproduction

    I pushed my demo to https://github.com/dexbol/test-styled-components-v6-beta .

    Steps to reproduce

    Don't need npm install, just visit index.html by localhost or just file url. Change the global variable SC_DISABLE_SPEEDY to false or true.

    Expected Behavior

    The circle should be rotating regardless of the value of SC_DISABLE_SPEEDY.

    Actual Behavior

    Rotating animation is not running if SC_DISABLE_SPEEDY is false

  • 16

    There is no code prompt at all

    image

    There is no code prompt at all. The normal css files are. It is no good to import style components, and I have also installed the style components plug-in. My vscode

  • 17

    SSR / Styled Components SEO Issues?

    First I wanted to say thanks for creating and managing this library, it's really nice!

    Next, I wanted to see if anyone else had any issues with SEO from Styled Components while using SSR? About 9 months ago we completely lost all our SEO rankings (for daily content) and have been through everything trying to figure it out. We've optimized our site loading times and performance to the 90's in lighthouse but our pages would sometimes get picked up / indexed from google news and then dropped within 24 hours (the google second pass).

    Then, on Wednesday, one of our devs pushed some code that broke SSR loading by accident and the next day we had dozens of page 1 rankings from the day's posts! As soon as we fixed the SSR break, we vanished from google once again. So we broke it again today and are now back on google.

    We've narrowed the issue down to 2 potential culprits - Styled Components and Fresnel. Both of which might be contributing factors, here's why:

    With SSR, styled components works like this: It puts all the CSS in the <head> of the site and on rehydrate, moves it into a separate .css file. This means google receives one set of raw HTML code and then when it renders, it sees something much smaller code wise. UI is the same still but code looks a lot different after it's rendered.

    With SSR Fresnel does the same thing. Sends all the HTML to google and when google renders the page (using mobile) and it rehydrates, all the desktop code is removed from the HTML.

    With those factors, it's highly likely that google is seeing this variance in file size / code as potential cloaking because our pages would go from page 1-2 to 10+ where you can't find it in google w/out using a direct URL match. We never received a manual action or any note from google but it's clear we triggered an automated penalty.

    A little extra context:

    At midnight, dozens of pages are added to our sitemap and then submit to google. Within a few hours, the pages get listed in google. When using CSR, we are ranked the next day. When using SSR, we aren't even in the index with an exact match URL search until 1-2 days later, and if we are indexed, we aren't in the first 10 pages.

    Has anyone that uses this combo experienced anything similar?