UNPKG

29.6 kBMarkdownView Raw
1# styled-jsx
2
3[![Build Status](https://travis-ci.org/zeit/styled-jsx.svg?branch=master)](https://travis-ci.org/zeit/styled-jsx)
4
5Need help?<br>
6[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/styled-jsx)
7
8Full, scoped and component-friendly CSS support for JSX (rendered on the server or the client).
9
10Code and docs are for v3 which we highly recommend you to try. Looking for styled-jsx v2? Switch to the [v2 branch](https://github.com/zeit/styled-jsx/tree/v2).
11
12- [Getting started](#getting-started)
13- [Configuration options](#configuration-options)
14 * [`optimizeForSpeed`](#optimizeforspeed)
15 * [`sourceMaps`](#sourcemaps)
16 * [`vendorPrefixes`](#vendorprefixes)
17- [Features](#features)
18- [How It Works](#how-it-works)
19 * [Why It Works Like This](#why-it-works-like-this)
20- [Targeting The Root](#targeting-the-root)
21- [Global styles](#global-styles)
22 * [One-off global selectors](#one-off-global-selectors)
23- [Dynamic styles](#dynamic-styles)
24 * [Via interpolated dynamic props](#via-interpolated-dynamic-props)
25 * [Via `className` toggling](#via-classname-toggling)
26 * [Via inline `style`](#via-inline-style)
27- [Constants](#constants)
28- [Server-Side Rendering](#server-side-rendering)
29 * [`styled-jsx/server`](#styled-jsxserver)
30- [External CSS and styles outside of the component](#external-css-and-styles-outside-of-the-component)
31 * [External styles](#external-styles)
32 * [Styles outside of components](#styles-outside-of-components)
33 * [The `resolve` tag](#the-resolve-tag)
34 * [Styles in regular CSS files](#styles-in-regular-css-files)
35- [CSS Preprocessing via Plugins](#css-preprocessing-via-plugins)
36 * [Plugin options](#plugin-options)
37 * [Example plugins](#example-plugins)
38- [Rendering in tests](#rendering-in-tests)
39- [FAQ](#faq)
40 * [Warning: unknown `jsx` prop on &lt;style&gt; tag](#warning-unknown-jsx-prop-on-style-tag)
41 * [Can I return an array of components when using React 16?](#can-i-return-an-array-of-components-when-using-react-16)
42 * [Styling third parties / child components from the parent](#styling-third-parties--child-components-from-the-parent)
43 * [Some styles are missing in production](https://github.com/zeit/styled-jsx/issues/319#issuecomment-349239326)
44 * [Build a component library with styled-jsx](#build-a-component-library-with-styled-jsx)
45- [Syntax Highlighting](#syntax-highlighting)
46
47## Getting started
48
49Firstly, install the package:
50
51```bash
52npm install --save styled-jsx
53```
54
55Next, add `styled-jsx/babel` to `plugins` in your babel configuration:
56
57```json
58{
59 "plugins": [
60 "styled-jsx/babel"
61 ]
62}
63```
64
65Now add `<style jsx>` to your code and fill it with CSS:
66
67```jsx
68export default () => (
69 <div>
70 <p>only this paragraph will get the style :)</p>
71
72 { /* you can include <Component />s here that include
73 other <p>s that don't get unexpected styles! */ }
74
75 <style jsx>{`
76 p {
77 color: red;
78 }
79 `}</style>
80 </div>
81)
82```
83
84## Configuration options
85
86The following are optional settings for the babel plugin.
87
88#### `optimizeForSpeed`
89
90Blazing fast and optimized CSS rules injection system based on the CSSOM APIs.
91
92```json
93{
94 "plugins": [
95 ["styled-jsx/babel", { "optimizeForSpeed": true }]
96 ]
97}
98```
99When in production\* this mode is automatically enabled.<br>
100Beware that when using this option source maps cannot be generated and styles cannot be edited via the devtools.
101
102\* `process.env.NODE_ENV === 'production'`
103
104
105#### `sourceMaps`
106
107Generates source maps (default: `false`)
108
109#### `vendorPrefixes`
110
111Turn on/off automatic vendor prefixing (default: `true`)
112
113## Features
114
115- Full CSS support, no tradeoffs in power
116- Runtime size of just **3kb** (gzipped, from 12kb)
117- Complete isolation: Selectors, animations, keyframes
118- Built-in CSS vendor prefixing
119- Very fast, minimal and efficient transpilation (see below)
120- High-performance runtime-CSS-injection when not server-rendering
121- Future-proof: Equivalent to server-renderable "Shadow CSS"
122- Source maps support
123- Dynamic styles and themes support
124- CSS Preprocessing via Plugins
125
126## How It Works
127
128The example above transpiles to the following:
129
130```jsx
131import _JSXStyle from 'styled-jsx/style'
132
133export default () => (
134 <div className="jsx-123">
135 <p className="jsx-123">only this paragraph will get the style :)</p>
136 <_JSXStyle id="123">{`p.jsx-123 {color: red;}`}</_JSXStyle>
137 </div>
138)
139```
140
141### Why It Works Like This
142
143Unique classnames give us style encapsulation and `_JSXStyle` is heavily optimized for:
144
145- Injecting styles upon render
146- Only injecting a certain component's style once (even if the component is included multiple times)
147- Removing unused styles
148- Keeping track of styles for server-side rendering
149
150### Targeting The Root
151
152Notice that the outer `<div>` from the example above also gets a `jsx-123` classname. We do this so that
153you can target the "root" element, in the same manner that
154[`:host`](https://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/#toc-style-host) works with Shadow DOM.
155
156If you want to target _only_ the host, we suggest you use a class:
157
158```jsx
159export default () => (
160 <div className="root">
161 <style jsx>{`
162 .root {
163 color: green;
164 }
165 `}</style>
166 </div>
167)
168```
169
170### Global styles
171
172To skip scoping entirely, you can make the global-ness of your styles
173explicit by adding _global_.
174
175```jsx
176export default () => (
177 <div>
178 <style jsx global>{`
179 body {
180 background: red
181 }
182 `}</style>
183 </div>
184)
185```
186
187The advantage of using this over `<style>` is twofold: no need
188to use `dangerouslySetInnerHTML` to avoid escaping issues with CSS
189and take advantage of `styled-jsx`'s de-duping system to avoid
190the global styles being inserted multiple times.
191
192### One-off global selectors
193
194Sometimes it's useful to skip selectors scoping. In order to get a one-off global selector we support `:global()`, inspired by [css-modules](https://github.com/css-modules/css-modules).
195
196This is very useful in order to, for example, generate a *global class* that
197you can pass to 3rd-party components. For example, to style
198`react-select` which supports passing a custom class via `optionClassName`:
199
200```jsx
201import Select from 'react-select'
202export default () => (
203 <div>
204 <Select optionClassName="react-select" />
205
206 <style jsx>{`
207 /* "div" will be prefixed, but ".react-select" won't */
208
209 div :global(.react-select) {
210 color: red
211 }
212 `}</style>
213 </div>
214)
215```
216
217### Dynamic styles
218
219To make a component's visual representation customizable from the outside world there are three options.
220
221#### Via interpolated dynamic props
222
223Any value that comes from the component's `render` method scope is treated as dynamic. This makes it possible to use `props` and `state` for example.
224
225```jsx
226const Button = (props) => (
227 <button>
228 { props.children }
229 <style jsx>{`
230 button {
231 padding: ${ 'large' in props ? '50' : '20' }px;
232 background: ${props.theme.background};
233 color: #999;
234 display: inline-block;
235 font-size: 1em;
236 }
237 `}</style>
238 </button>
239)
240```
241
242New styles' injection is optimized to perform well at runtime.
243
244That said when your CSS is mostly static we recommend to split it up in static and dynamic styles and use two separate `style` tags so that, when changing, only the dynamic parts are recomputed/rendered.
245
246```jsx
247const Button = (props) => (
248 <button>
249 { props.children }
250 <style jsx>{`
251 button {
252 color: #999;
253 display: inline-block;
254 font-size: 2em;
255 }
256 `}</style>
257 <style jsx>{`
258 button {
259 padding: ${ 'large' in props ? '50' : '20' }px;
260 background: ${props.theme.background};
261 }
262 `}</style>
263 </button>
264)
265```
266
267#### Via `className` toggling
268
269The second option is to pass properties that toggle class names.
270
271```jsx
272const Button = (props) => (
273 <button className={ 'large' in props && 'large' }>
274 { props.children }
275 <style jsx>{`
276 button {
277 padding: 20px;
278 background: #eee;
279 color: #999
280 }
281 .large {
282 padding: 50px
283 }
284 `}</style>
285 </button>
286)
287```
288
289Then you would use this component as either `<Button>Hi</Button>` or `<Button large>Big</Button>`.
290
291#### Via inline `style`
292
293\***best for animations**
294
295Imagine that you wanted to make the padding in the button above completely customizable. You can override the CSS you configure via inline-styles:
296
297```jsx
298const Button = ({ padding, children }) => (
299 <button style={{ padding }}>
300 { children }
301 <style jsx>{`
302 button {
303 padding: 20px;
304 background: #eee;
305 color: #999
306 }
307 `}</style>
308 </button>
309)
310```
311
312In this example, the padding defaults to the one set in `<style>` (`20`), but the user can pass a custom one via `<Button padding={30}>`.
313
314### Constants
315
316It is possible to use constants like so:
317
318```jsx
319import { colors, spacing } from '../theme'
320import { invertColor } from '../theme/utils'
321
322const Button = ({ children }) => (
323 <button>
324 { children }
325 <style jsx>{`
326 button {
327 padding: ${ spacing.medium };
328 background: ${ colors.primary };
329 color: ${ invertColor(colors.primary) };
330 }
331 `}</style>
332 </button>
333)
334```
335
336Please keep in mind that constants defined outside of the component scope are treated as static styles.
337
338## Server-Side Rendering
339
340### `styled-jsx/server`
341
342The main export flushes your styles to an array of `React.Element`:
343
344```jsx
345import React from 'react'
346import ReactDOM from 'react-dom/server'
347import flush from 'styled-jsx/server'
348import App from './app'
349
350export default (req, res) => {
351 const app = ReactDOM.renderToString(<App />)
352 const styles = flush()
353 const html = ReactDOM.renderToStaticMarkup(<html>
354 <head>{ styles }</head>
355 <body>
356 <div id="root" dangerouslySetInnerHTML={{__html: app}} />
357 </body>
358 </html>)
359 res.end('<!doctype html>' + html)
360}
361```
362
363We also expose `flushToHTML` to return generated HTML:
364
365```jsx
366import React from 'react'
367import ReactDOM from 'react-dom/server'
368import { flushToHTML } from 'styled-jsx/server'
369import App from './app'
370
371export default (req, res) => {
372 const app = ReactDOM.renderToString(<App />)
373 const styles = flushToHTML()
374 const html = `<!doctype html>
375 <html>
376 <head>${styles}</head>
377 <body>
378 <div id="root">${app}</div>
379 </body>
380 </html>`
381 res.end(html)
382}
383```
384
385It's **paramount** that you use one of these two functions so that
386the generated styles can be diffed when the client loads and
387duplicate styles are avoided.
388
389### Content Security Policy
390
391Strict [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) is supported.
392
393You should generate a nonce **per request**.
394```js
395import nanoid from 'nanoid'
396
397const nonce = Buffer.from(nanoid()).toString('base64') //ex: N2M0MDhkN2EtMmRkYi00MTExLWFhM2YtNDhkNTc4NGJhMjA3
398```
399
400You must then pass a nonce to either `flushToReact({ nonce })` or `flushToHTML({ nonce })` **and** set a `<meta property="csp-nonce" content={nonce} />` tag.
401
402Your CSP policy must share the same nonce as well (the header nonce needs to match the html nonce and remain unpredictable).
403`Content-Security-Policy: default-src 'self'; style-src 'self' 'nonce-N2M0MDhkN2EtMmRkYi00MTExLWFhM2YtNDhkNTc4NGJhMjA3';`
404
405### External CSS and styles outside of the component
406
407In styled-jsx styles can be defined outside of the component's render method or in separate JavaScript modules using the `styled-jsx/css` library. `styled-jsx/css` exports three tags that can be used to tag your styles:
408
409* `css`, the default export, to define scoped styles.
410* `css.global` to define global styles.
411* `css.resolve` to define scoped styles that resolve to the scoped `className` and a `styles` element.
412
413#### External styles
414
415In an external file:
416
417```js
418/* styles.js */
419import css from 'styled-jsx/css'
420
421// Scoped styles
422export const button = css`button { color: hotpink; }`
423
424// Global styles
425export const body = css.global`body { margin: 0; }`
426
427// Resolved styles
428export const link = css.resolve`a { color: green; }`
429// link.className -> scoped className to apply to `a` elements e.g. jsx-123
430// link.styles -> styles element to render inside of your component
431
432// Works also with default exports
433export default css`div { color: green; }`
434```
435
436You can then import and use those styles:
437
438```jsx
439import styles, { button, body } from './styles'
440
441export default () => (
442 <div>
443 <button>styled-jsx</button>
444 <style jsx>{styles}</style>
445 <style jsx>{button}</style>
446 <style jsx global>{body}</style>
447 </div>
448)
449```
450
451N.B. All the tags except for [`resolve`](#the-resolve-tag) don't support dynamic styles.
452
453`resolve` and `global` can also be imported individually:
454
455```js
456import { resolve } from 'styled-jsx/css'
457import { global } from 'styled-jsx/css'
458```
459
460If you use Prettier we recommend you to use the default `css` export syntax since the tool doesn't support named imports.
461
462#### Styles outside of components
463
464The `css` tag from `styled-jsx/css` can be also used to define styles in your components files but outside of the component itself. This might help with keeping `render` methods smaller.
465
466```jsx
467import css from 'styled-jsx/css'
468
469export default () => (
470 <div>
471 <button>styled-jsx</button>
472 <style jsx>{button}</style>
473 </div>
474)
475
476const button = css`button { color: hotpink; }`
477```
478
479Like in externals styles `css` doesn't work with dynamic styles. If you have dynamic parts you might want to place them inline inside of your component using a regular `<style jsx>` element.
480
481#### The `resolve` tag
482
483The `resolve` tag from `styled-jsx/css` can be used when you need to scope some CSS and want back the generated scoped `className` and `styles`. This is usually the case when you want to style nested components from the parent.
484
485```jsx
486import React from 'react'
487import Link from 'some-library'
488
489import css from 'styled-jsx/css'
490
491const { className, styles } = css.resolve`
492 a { color: green }
493`
494
495export default () => (
496 <div>
497 {/* use the className */}
498 <Link className={className}>About</Link>
499 {/* render the styles for it */}
500 {styles}
501 <style jsx>{`div { border: 5px solid green }`}</style>
502 </div>
503)
504```
505
506The `resolve` tag also supports dynamic styles:
507
508```jsx
509import React from 'react'
510import css from 'styled-jsx/css'
511
512function getLinkStyles(color) {
513 return css.resolve`
514 a { color: ${color} }
515 `
516}
517
518export default (props) => {
519 const { className, styles } = getLinkStyles(props.theme.color)
520
521 return (
522 <div>
523 <Link className={className}>About</Link>
524 {styles}
525 </div>
526 )
527}
528```
529
530#### Using `resolve` as a babel macro
531
532The `resolve` tag can be used as a Babel macro thanks to the [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) system.
533
534```bash
535npm i --save styled-jsx
536npm i --save-dev babel-plugin-macros
537```
538
539Next add `babel-plugin-macros` to your babel configuration:
540
541```json
542{
543 "plugins": [
544 "babel-plugin-macros"
545 ]
546}
547```
548
549You can then start to use `resolve` by importing it from `styled-jsx/macro`.
550
551```jsx
552import css, { resolve } from 'styled-jsx/macro'
553
554const stylesInfo = css.resolve`a { color: green; }`
555const stylesInfo2 = resolve`a { color: green; }`
556```
557
558**Create React App** comes with `babel-plugin-macros` pre-installed so you just need to install `styled-jsx` and you can start to use `resolve` right away.
559
560
561#### Styles in regular CSS files
562
563styled-jsx v3 comes with a webpack loader that lets you write styles in regular `css` files and consume them in React.
564
565```js
566import styles from '../components/button/styles.css'
567
568export default () => (
569 <div>
570 <button>styled-jsx</button>
571 <style jsx>{styles}</style>
572 </div>
573)
574```
575
576To consume the styles in your component you can import them from your CSS file and render them using a `<style jsx>` tag. Remember to add the `global` prop if you want your styles to be global.
577
578To use this feature you need to register the loader in your webpack config file, before `babel-loader` which will then transpile the styles via `styled-jsx/babel`
579
580```js
581config: {
582 module: {
583 rules: [
584 test: /\.css$/,
585 use: [{
586 loader: require('styled-jsx/webpack').loader,
587 options: {
588 type: 'scoped'
589 }
590 }]
591 ]
592 }
593}
594```
595
596The plugin accepts a `type` option to configure whether the styles should be `scoped`, `global` or `resolve` (see above). By default its values is set to `scoped`. `type` can also be a `function` which takes the `fileName` and the `fileNameQuery` that is being transpiled and must return a valid type.
597
598```js
599type validTypes = 'scoped' | 'global' | 'resolve'
600type fileName = string
601type Options = {|
602 type: validTypes | (fileName, options) => validTypes
603|}
604```
605```js
606import styles from './styles.css?type=global'
607
608// webpack
609config: {
610 module: {
611 rules: [
612 test: /\.css$/,
613 use: [{
614 loader: require('styled-jsx/webpack').loader,
615 options: {
616 type: (fileName, options) => options.query.type || 'scoped'
617 }
618 }]
619 ]
620 }
621}
622```
623
624The type can also be set per individual CSS file via CSS comment:
625
626```css
627/* @styled-jsx=scoped */
628
629button { color: red }
630```
631
632The CSS comment option will override the one in the webpack configuration only for this specific file.
633
634##### Next.js
635
636Example of `next.config.js` to integrate `styled-jsx/webpack`:
637
638```js
639module.exports = {
640 webpack: (config, { defaultLoaders }) => {
641 config.module.rules.push({
642 test: /\.css$/,
643 use: [
644 defaultLoaders.babel,
645 {
646 loader: require('styled-jsx/webpack').loader,
647 options: {
648 type: 'scoped'
649 }
650 }
651 ]
652 })
653
654 return config
655 }
656}
657```
658
659## CSS Preprocessing via Plugins
660
661Styles can be preprocessed via plugins.
662
663Plugins are regular JavaScript modules that export a simple function with the following signature:
664
665```js
666(css: string, options: Object) => string
667```
668
669Basically they accept a CSS string in input, optionally modify it and finally return it.
670
671Plugins make it possible to use popular preprocessors like SASS, Less, Stylus, PostCSS or apply custom transformations to the styles at **compile time**.
672
673To register a plugin add an option `plugins` for `styled-jsx/babel` to your `.babelrc`. `plugins` must be an array of module names or *full* paths for local plugins.
674
675```json
676{
677 "plugins": [
678 [
679 "styled-jsx/babel",
680 { "plugins": ["my-styled-jsx-plugin-package", "/full/path/to/local/plugin"] }
681 ]
682 ]
683}
684```
685
686<details>
687 <summary>Instructions to integrate with Next.js</summary>
688 In order to register styled-jsx plugins in a Next.js app you need to create a custom .babelrc file:
689
690 ```json
691 {
692 "presets": [
693 [
694 "next/babel",
695 {
696 "styled-jsx": {
697 "plugins": [
698 "styled-jsx-plugin-postcss"
699 ]
700 }
701 }
702 ]
703 ]
704 }
705 ```
706
707 This is a fairly new feature so make sure that you using a version of Next.js that supports passing options to `styled-jsx`.
708</details>
709<br>
710
711Plugins are applied in definition order left to right before styles are scoped.
712
713In order to resolve local plugins paths you can use NodeJS' [require.resolve](https://nodejs.org/api/globals.html#globals_require_resolve).
714
715N.B. when applying the plugins styled-jsx replaces template literals expressions with placeholders because otherwise CSS parsers would get invalid CSS E.g.
716
717```css
718/* `ExprNumber` is a number */
719%%styled-jsx-placeholder-ExprNumber%%
720```
721
722**Plugins won't transform expressions** (eg. dynamic styles).
723
724When publishing a plugin you may want to add the keywords: `styled-jsx` and `styled-jsx-plugin`.
725We also encourage you to use the following naming convention for your plugins:
726
727```
728styled-jsx-plugin-<your-plugin-name>
729```
730
731#### Plugin options
732
733Users can set plugin options by registering a plugin as an array that contains
734the plugin path and an options object.
735
736```json
737{
738 "plugins": [
739 [
740 "styled-jsx/babel",
741 {
742 "plugins": [
743 ["my-styled-jsx-plugin-package", { "exampleOption": true }]
744 ],
745 "sourceMaps": true
746 }
747 ]
748 ]
749}
750```
751
752Each plugin receives a `options` object as second argument which contains
753the babel and user options:
754
755```js
756(css, options) => { /* ... */ }
757```
758
759The `options` object has the following shape:
760
761```js
762{
763 // user options go here
764 // eg. exampleOption: true
765
766 // babel options
767 babel: {
768 sourceMaps: boolean,
769 vendorPrefixes: boolean,
770 isGlobal: boolean,
771 filename: ?string, // defined only when the filename option is passed to Babel, such as when using Babel CLI or Webpack
772 location: { // the original location of the CSS block in the JavaScript file
773 start: {
774 line: number,
775 column: number,
776 },
777 end: {
778 line: number,
779 column: number,
780 }
781 }
782 }
783}
784```
785
786#### Example plugins
787
788The following plugins are proof of concepts/sample:
789
790* [styled-jsx-plugin-sass](https://github.com/giuseppeg/styled-jsx-plugin-sass)
791* [styled-jsx-plugin-postcss](https://github.com/giuseppeg/styled-jsx-plugin-postcss)
792* [styled-jsx-plugin-stylelint](https://github.com/giuseppeg/styled-jsx-plugin-stylelint)
793* [styled-jsx-plugin-less](https://github.com/erasmo-marin/styled-jsx-plugin-less)
794* [styled-jsx-plugin-stylus](https://github.com/omardelarosa/styled-jsx-plugin-stylus)
795
796
797## Rendering in tests
798
799If you're using a tool such as Enzyme, you might want to avoid compiling your styles in test renders. In general, styled-jsx artifacts like `jsx-123` classnames and vendor prefixing are not direct concerns of your component, and they generate a lot of snapshot noise.
800
801One option is to exclude the `styled-jsx/babel` plugin from the `test` environment using `env` in your Babel config (see [Config Merging options](https://babeljs.io/docs/en/options#config-merging-options)).
802
803But this can cause noise in your terminal output when rendering:
804
805```
806 console.error node_modules/react-dom/cjs/react-dom.development.js:527
807 Warning: Received `true` for a non-boolean attribute `jsx`.
808```
809
810The `styled-jsx/babel-test` solves this problem. It simply strips `jsx` attributes from all `<style>` tags. Be sure to target each environment with the appropriate plugin:
811
812```json
813{
814 "env": {
815 "production": {
816 "plugins": ["styled-jsx/babel"]
817 },
818 "development": {
819 "plugins": ["styled-jsx/babel"]
820 },
821 "test": {
822 "plugins": ["styled-jsx/babel-test"]
823 }
824 }
825}
826```
827
828#### styled-jsx/css in tests
829
830When using `styled-jsx/babel-test`, `styled-jsx/css` throws the following error:
831
832```
833styled-jsx/css: if you are getting this error it means that your `css` tagged template literals were not transpiled.
834```
835
836to solve this issue you need to mock `styled-jsx/css`. You can find a guide at the following link https://kevinjalbert.com/jest-snapshots-reducing-styled-jsx-noise/
837
838## FAQ
839
840### Warning: unknown `jsx` prop on &lt;style&gt; tag
841
842If you get this warning it means that your styles were not compiled by styled-jsx.
843
844Please take a look at your setup and make sure that everything is correct and that the styled-jsx transformation is ran by Babel.
845
846### Can I return an array of components when using React 16?
847
848No, this feature is not supported. However we support React Fragments, which are available in React `16.2.0` and above.
849
850```jsx
851const StyledImage = ({ src, alt = '' }) => (
852 <React.Fragment>
853 <img src={src} alt={alt} />
854 <style jsx>{`img { max-width: 100% }`}</style>
855 </React.Fragment>
856)
857```
858
859### Styling third parties / child components from the parent
860
861When the component accepts a `className` (or ad-hoc) prop as a way to allow customizations then you can use [the `resolve` tag from `styled-jsx/css`](#the-resolve-tag).
862
863When the component doesn't accept any `className` or doesn't expose any API to customize the component, then your only option is to use `:global()` styles:
864
865```jsx
866export default () => (
867 <div>
868 <ExternalComponent />
869
870 <style jsx>{`
871 /* "div" will be prefixed, but ".nested-element" won't */
872
873 div > :global(.nested-element) {
874 color: red
875 }
876 `}</style>
877 </div>
878)
879```
880
881Please keep in mind that `:global()` styles will affect the entire subtree, so in many cases you may want to be careful and use the children (direct descendant) selector `>`.
882
883### Build a component library with styled-jsx
884
885There's an [article](https://medium.com/@tomaszmularczyk89/guide-to-building-a-react-components-library-with-rollup-and-styled-jsx-694ec66bd2) explaining how to bundle React components with Rollup and styled-jsx as an external dependency.
886
887## Syntax Highlighting
888
889When working with template literals a common drawback is missing syntax highlighting. The following editors currently have support for highlighting CSS inside `<style jsx>` elements.
890
891 _If you have a solution for an editor not on the list_ __please [open a PR](https://github.com/zeit/styled-jsx/pull/new/master)__ _and let us now._
892
893### Atom
894
895The [`language-babel`](https://github.com/gandm/language-babel) package for the [Atom editor](https://atom.io/) has an option to [extend the grammar for JavaScript tagged template literals](https://github.com/gandm/language-babel#javascript-tagged-template-literal-grammar-extensions).
896
897After [installing the package](https://github.com/gandm/language-babel#installation) add the code below to the appropriate settings entry. In a few moments you should be blessed with proper CSS syntax highlighting. ([source](https://github.com/gandm/language-babel/issues/324))
898
899```
900"(?<=<style jsx>{)|(?<=<style jsx global>{)|(?<=css)":source.css.styled
901```
902
903![babel-language settings entry](https://cloud.githubusercontent.com/assets/2313237/22627258/6c97cb68-ebb7-11e6-82e1-60205f8b31e7.png)
904
905### Webstorm/Idea
906
907The IDE let you inject any language in place with _Inject language or reference_ in an _Intention Actions_ (default _alt+enter_).
908Simply perform the action in the string template and select CSS.
909You get full CSS highlighting and autocompletion and it will last until you close the IDE.
910
911Additionally you can use language injection comments to enable all the IDE language features indefinitely using the language comment style:
912
913```jsx
914import { colors, spacing } from '../theme'
915import { invertColor } from '../theme/utils'
916
917const Button = ({ children }) => (
918 <button>
919 { children }
920
921 { /*language=CSS*/ }
922 <style jsx>{`
923 button {
924 padding: ${ spacing.medium };
925 background: ${ colors.primary };
926 color: ${ invertColor(colors.primary) };
927 }
928 `}</style>
929 </button>
930)
931```
932
933### Emmet
934
935 If you're using Emmet you can add the following snippet to `~/emmet/snippets-styledjsx.json` This will allow you to expand `style-jsx` to a styled-jsx block.
936
937 ```json
938 {
939 "html": {
940 "snippets": {
941 "style-jsx": "<style jsx>{`\n\t$1\n`}</style>"
942 }
943 }
944}
945```
946
947### Syntax Highlighting [Visual Studio Code Extension](https://marketplace.visualstudio.com/items?itemName=blanu.vscode-styled-jsx)
948Launch VS Code Quick Open (⌘+P), paste the following command, and press enter.
949```
950ext install vscode-styled-jsx
951```
952
953If you use Stylus instead of plain CSS, install [vscode-styled-jsx-stylus](https://marketplace.visualstudio.com/items?itemName=samuelroy.vscode-styled-jsx-stylus) or paste the command below.
954```
955ext install vscode-styled-jsx-stylus
956```
957
958### Autocomplete [Visual Studio Code Extension](https://marketplace.visualstudio.com/items?itemName=AndrewRazumovsky.vscode-styled-jsx-languageserver)
959Launch VS Code Quick Open (⌘+P), paste the following command, and press enter.
960```
961ext install vscode-styled-jsx-languageserver
962```
963
964### Vim
965
966Install [vim-styled-jsx](https://github.com/alampros/vim-styled-jsx) with your plugin manager of choice.
967
968## ESLint
969If you're using `eslint-plugin-import`, the `css` import will generate errors, being that it's a "magic" import (not listed in package.json). To avoid these, simply add the following line to your eslint configuration:
970
971```
972"settings": {"import/core-modules": ["styled-jsx/css"] }
973```
974
975## Credits
976
977- **Pedram Emrouznejad** ([rijs](https://github.com/rijs/fullstack)) suggested attribute selectors over my initial class prefixing idea.
978- **Sunil Pai** ([glamor](https://github.com/threepointone/glamor)) inspired the use of `murmurhash2` (minimal and fast hashing) and an efficient style injection logic.
979- **Sultan Tarimo** built [stylis.js](https://github.com/thysultan), a super fast and tiny CSS parser and compiler.
980- **Max Stoiber** ([styled-components](https://github.com/styled-components)) proved the value of retaining the familiarity of CSS syntax and pointed me to the very efficient [stylis](https://github.com/thysultan/stylis.js) compiler (which we forked to very efficiently append attribute selectors to the user's css)
981- **Yehuda Katz** ([ember](https://github.com/emberjs)) convinced me on Twitter to transpile CSS as an alternative to CSS-in-JS.
982- **Evan You** ([vuejs](https://github.com/vuejs)) discussed his Vue.js CSS transformation with me.
983- **Henry Zhu** ([babel](https://github.com/babel)) helpfully pointed me to some important areas of the babel plugin API.
984
985## Authors
986
987- Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) - [▲ZEIT](https://zeit.co)
988- Naoyuki Kanezawa ([@nkzawa](https://twitter.com/nkzawa)) - [▲ZEIT](https://zeit.co)
989- Giuseppe Gurgone ([@giuseppegurgone](https://twitter.com/giuseppegurgone))