/injected-css

{:;} CSS in JS

Primary LanguageJavaScriptMIT LicenseMIT

{:;} injected-css

Structured way to write CSS in JS file.

Usage

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>
`;

Benefits

  • 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)

Custom postcss config

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
  ]
})

Inject global styles

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 */
    }
  }
`)

Server side render

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;
  }
`)

Syntax highlight

Atom with language-babel plugin supports syntax highlight and autocompletion by default. atom-language-babel

Credits

  • 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

License

MIT