Structured way to write CSS in JS file.
Install the package:
$ npm install injected-css
Add injected-css/babel
to plugins section in your babel config:
{
"plugins": [
"injected-css/babel"
]
}
Define real CSS in your JS file using css{}
template expression,
and refer to resulted classes using style
object.
import { css } from 'injected-css'
import { red, white, mobile } from '../my-theme' // use js variables
const style = css`
text-align: center;
&-button {
background-color: ${red};
width: 32rem;
padding: 2rem;
border-radius: 0.5rem;
border: none;
&:hover {
background-color: ${white};
}
@media ${mobile} {
width: 16rem;
}
}
`
document.innerHTML = `
<div class="${style}">
<button class="${style.button}">Click me!</button>
</div>
`
It transforms to:
import { css } from 'injected-css';
import { red, white, mobile } from '../my-theme';
const style = css.inject({
toString() { return 'c3423985940'; },
button: 'c3423985940-button',
_css: `.c3423985940 { text-align: center } .c3423985940-button { background-color: ${red}; width: 32rem; padding: 2rem; border-radius: 0.5rem; border: none
} .c3423985940-button:hover { background-color: ${white} } @media ${mobile} { .c3423985940-button { width: 16rem } }`
});
document.innerHTML = `
<div class="${style}">
<button class="${style.button}">Click me!</button>
</div>
`;
- Write real CSS and use JS for import/export, variables and dynamic strings
- Use powerful tools of JS world
- ES modules to manage dependencies between styles and JS components
- Eslint to ensure, it's hard to write bad CSS
- Variables and functions
- Webpack 2, Hot Module Replacement, code splitting, and server side render
- Built-in naming convention for component world
- Postcss integration (100s of plugins and custom syntaxes like SASS)
- Minimal overhead (no parsing cost, 400 byte runtime)
Just create .postcssrc.js
file with content similar to (read more about postcss config):
module.exports = (ctx) => ({
plugins: [
require('postcss-cssnext')({ 'features': { 'rem': false } }),
ctx.env === 'production' ? require('cssnano')({ autoprefixer: false }) : false
]
})
Use inject()
method to insert global css
string.
Everything tagged literal with css`` will be preparsed with postcss.
import { inject, css } from 'injected-css'
import normalizeCss from 'normalize.css'
import { mobile } from '../my-theme';
// insert regular css, like normalize.css
inject(normalize)
// setup global typography
inject(css`
html {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-weight: normal;
font-size: 62.5%; /* 1rem ~ 10px */
@media ${mobile} {
font-size: 56.25%; /* 1rem ~ 9px */
}
}
`)
Use flush()
method to get all css calls.
import { flush } from 'injected-css'
import { App } from './App'
const body = renderToStaticMarkup(<App />)
const css = reset._css + flush().join('')
const html = `
<!doctype html>
<html lang='en-US'>
<head>
<title>My App</title>
<style>${css}</style>
</head>
<body>
${body}
</body>
</html>
`
const reset = inject(css`
html {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
margin: 0;
}
`)
Atom with language-babel plugin supports syntax highlight and autocompletion by default.
- BEM and SUIT CSS - for name convention, that works
- CSS modules - for embracing CSS syntax and adding the way to reference on classes from JS code
- style-loader - for concept of loading styles with js
- styled-jsx - for idea of babel plugin and this credits section
- @rtsao - for his open-source work on many css-in-js libraries
- styling - for embracing ES modules to export CSS
- react - for component approach and development philosophy
- CSS: The Definitive Guide - for explaining me details of CSS
- styled-components - for showing how to highlight CSS in tagged template literal