styled-jsx
Version:
Full, scoped and component-friendly CSS support for JSX (SSR+browser)
112 lines (88 loc) • 3.36 kB
Markdown
# styled-jsx
Full, scoped and component-friendly CSS support for JSX (SSR+browser)
## How it works
Just include `<style jsx>`.
```js
export default () => (
<div>
<p>only this paragraph will get the style :O</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>
)
```
## Features
- Full CSS support, no tradeoffs in power
- Runtime size: *300b*
- Complete isolation: selectors, animations, keyframes
- Built in CSS prefixing
- Very fast, minimal and efficient transpilation (see below)
- High performant runtime CSS injection when not server-rendering
- Future-proof: equivalent to server-renderable "Shadow CSS"
- Works like the deprecated `<style scoped>`, but the styles
get injected only once per component
## How it works
The example above compiles to
```js
import _jsxStyleInject from 'styled-jsx/inject'
export default () => (
<div>
<p data-jsx='cn2o3j'>only this paragraph will get the style :O</p>
{ _jsxStyleInject('cn2o3j', `p[data-jsx=cn2o3j] {color: red;}`) }
</div>
)
```
- Data attributes give us style encapsulation.
- `_jsxStyleInject` is heavily optimized for:
- injecting styles upon render
- only injecting a certain componen'ts style once, even if the component is included multiple times
- keeping track of styles for server-side rendering
## How to use
Add `styled-jsx` to `dependencies` inside `package.json`
### Babel
Add `styled-jsx/babel` to `plugins` in your babel configuration
### Server-side rendering
In the server rendering pipeline, you can obtain the entire
CSS text of all the combined components by invoking `flush`
```js
import flush from 'styled-jsx/flush'
// …
// <render here>
// …
const styles = flush()
for (let id in styles) {
const css = styles[id]
console.log(id, css)
}
```
This API is also available on the client. Instead of returning
the CSS text, it returns a reference to the created `<style>` tag.
This is useful for performing diffs of elements between top-level
`render()` calls, and ditching style elements that are not longer
used.
## Credits
- Pedram Emrouznejad ([`rijs`](https://github.com/rijs/fullstack))
- suggesting attribute selectors over my initial class prefixing idea
- Sunil Pail ([`glamor`](https://github.com/threepointone/glamor))
- inspired usage of `murmurhash2` (minimal and fast hashing)
- efficient style injection logic
- Sultan Tarimo ([`stylis.js`](https://github.com/thysultan))
- super fast and tiny CSS parser and compiler
- Max Stoiber ([`styled-components`](https://github.com/styled-components))
- proved the value of retaining the familiarity of CSS syntax
- 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
- Yehuda Katz ([`ember`](https://github.com/ember))
- convinced me on Twitter to transpile CSS as an alternative to CSS-in-JS
- Evan You ([`vuejs`](https://github.com/vuejs))
- discussing his Vue.js CSS transformation
- Henry Zhu ([`babel`](https://github.com/babel))
- his helpful pointers on the babel plugin API
## Author
Guillermo Rauch ([@rauchg](https://twitter.com/rauchg) - [▲ZEIT](https://zeit.co)