GitHub

build status

Full, scoped and component-friendly CSS support for JSX (rendered on the server or the client).

Code and docs are for v3 which we highly recommend you to try. Looking for styled-jsx v2? Switch to the v2 branch.

Getting started

Firstly, install the package:

npm install --save styled-jsx

Next, add styled-jsx/babel to plugins in your babel configuration:

{
  "plugins": ["styled-jsx/babel"]
}

Now add <style jsx> to your code and fill it with CSS:

export default () => (
  <div>
    <p>only this paragraph will get the style :)</p>
    {/* you can include <Component />s here that include
         other <p>s that don't get unexpected styles! */}
    <style jsx>{`
      p {
        color: red;
      }
    `}</style>
  </div>
)

Configuration options

The following are optional settings for the babel plugin.

optimizeForSpeed

Blazing fast and optimized CSS rules injection system based on the CSSOM APIs.

{
  "plugins": [["styled-jsx/babel", { "optimizeForSpeed": true }]]
}

When in production* this mode is automatically enabled.
Beware that when using this option source maps cannot be generated and styles cannot be edited via the devtools.

* process.env.NODE_ENV === 'production'

sourceMaps

Generates source maps (default: false)

styleModule

Module that the transpiled files should import (default: styled-jsx/style)

vendorPrefixes

Turn on/off automatic vendor prefixing (default: true)

Features

  • Full CSS support, no tradeoffs in power
  • Runtime size of just 3kb (gzipped, from 12kb)
  • Complete isolation: Selectors, animations, keyframes
  • Built-in CSS vendor prefixing
  • Very fast, minimal and efficient transpilation (see below)
  • High-performance runtime-CSS-injection when not server-rendering
  • Future-proof: Equivalent to server-renderable "Shadow CSS"
  • Source maps support
  • Dynamic styles and themes support
  • CSS Preprocessing via Plugins

Using in Next.js

Next.js automatically configures styled-jsx with babel or swc, you don't have to configure it manually.

How It Works

The example above transpiles to the following:

import _JSXStyle from 'styled-jsx/style'
export default () => (
  <div className="jsx-123">
    <p className="jsx-123">only this paragraph will get the style :)</p>
    <_JSXStyle id="123">{`p.jsx-123 {color: red;}`}</_JSXStyle>
  </div>
)

Why It Works Like This

Unique classnames give us style encapsulation and _JSXStyle is heavily optimized for:

  • Injecting styles upon render
  • Only injecting a certain component's style once (even if the component is included multiple times)
  • Removing unused styles
  • Keeping track of styles for server-side rendering

Targeting The Root

Notice that the outer <div> from the example above also gets a jsx-123 classname. We do this so that you can target the "root" element, in the same manner that :host works with Shadow DOM.

If you want to target only the host, we suggest you use a class:

export default () => (
  <div className="root">
    <style jsx>{`
      .root {
        color: green;
      }
    `}</style>
  </div>
)

Global styles

To skip scoping entirely, you can make the global-ness of your styles explicit by adding global.

export default () => (
  <div>
    <style jsx global>{`
      body {
        background: red;
      }
    `}</style>
  </div>
)

The advantage of using this over <style> is twofold: no need to use dangerouslySetInnerHTML to avoid escaping issues with CSS and take advantage of styled-jsx's de-duping system to avoid the global styles being inserted multiple times.

One-off global selectors

Sometimes it's useful to skip selectors scoping. In order to get a one-off global selector we support :global(), inspired by css-modules.

This is very useful in order to, for example, generate a global class that you can pass to 3rd-party components. For example, to style react-select which supports passing a custom class via optionClassName:

"import Select from 'react-select' export default () => (

Read the original on github.com ↗