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
- Configuration options
- Features
- How It Works
- Targeting The Root
- Global styles
- Dynamic styles
- Constants
- Server-Side Rendering
- External CSS and styles outside of the component
- CSS Preprocessing via Plugins
- Rendering in tests
- FAQ
- Syntax Highlighting
- ESLint
- TypeScript
- Credits
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: