react-css-in-jsdeprecated

Minimal React css-in-js styled components.

Usage no npm install needed!

<script type="module">
  import reactCssInJs from 'https://cdn.skypack.dev/react-css-in-js';
</script>

README

React CSS-in-JS

gh-stars npm-version npm-license npm-types npm-downloads bf-size bf-deps

A library designed for styling React components with tagged template strings. It provides a great developer experience in addition to having a tiny footprint, supporting all CSS features, and requiring zero configuration. It can even be used in component libraries.

Links

Getting Started

A Styled wrapper creates a "styling context" where you compose css tagged template style strings and the components which are styled. This keeps component styles directly adjacent to the components being styled, while still giving you complete control over your React component markup.

import { css, Styled } from 'react-css-in-js';

const color = 'white';

render(
  <Styled>
    {css`
      padding: 32px;
      color: black;
      background-color: hotpink;
      font-size: 24px;
      border-radius: 4px;
      &:hover {
        color: ${color};
      }
    `}
    <div>Hover to change color.</div>
  </Styled>
);

Re-styling

Any component that accepts a class name can be styled. So, to make your pre-styled component support re-styling, give it a className property and pass that property value through to the internal Styled component.

IMPORTANT: When a pre-styled component accepts a class name, do not concatenate, stringify, or otherwise modify the class name string! The class name injected by a Styled component is actually a boxed string with style metadata attached. This metadata allows child Styled components to give the outer styles a higher precedence. If the boxed class name string is un-boxed, it will lose its metadata and style overriding may not work as expected.

interface IMyComponentProps {
  className?: string;
}

function MyComponent(props: IMyComponentProps): ReactElement {
  return (
    <Styled className={props.className}>
      {css`
        color: red;
      `}
      <div className={'my-component'}>Hello, world!</div>
    </Styled>
  );
}

Now your custom component can be (re-)styled just like any plain HTML (eg. <div>) element.

<Styled>
  {css`
    color: blue;
  `}
  <MyComponent />
</Styled>

This works even when adding other class names.

<Styled>
  {css`
    color: blue;
  `}
  <MyComponent className={'other class names'} />
</Styled>

Global Styles

Global styling is similar to styling components, except you use the Style component (instead of Styled), and it should only have tagged template children (no component children).

import { css, Style } from 'react-css-in-js';

render(
  <Style>
    {css`
      html, body {
        padding: 0;
        margin: 0;
      }
    `}
  </Style>
);

Advanced Configuration

This library is designed to require zero-configuration. Class names are stable and have a very high probability of uniqueness, and server-side rendering works out of the box. But, there are always cases where the defaults need a little modification.

import {
  configure,
  defaultCssPrinter,
  defaultStyleManager,
  defaultHashFunction
} from 'react-css-in-js';

configure({
  // A custom CSS printer can be used to change how CSS rules are
  // formatted. You could use it to minify or add auto-prefixing.
  customCssPrinter: defaultCssPrinter,

  // A custom style manager can be used to change how styles are
  // injected into the DOM, or to capture styles during server-side
  // rendering if the default SSR inline injection behavior isn't
  // suitable for your application.
  //
  // By default, no (undefined) style manager is used during SSR,
  // which causes style elements to be injected inline, adjacent to
  // the element being styled. These inlined styles will be moved to
  // the document head on the client side, prior to React
  // rehydration.
  customStyleManager: defaultStyleManager,

  // A custom hash function can be used for testing, enhanced
  // collision avoidance, etc.
  //
  // The default hash function is the same one used by Emotion and
  // styled-components: https://github.com/darkskyapp/string-hash
  customHashFunction: defaultHashFunction,
});

Configuration must be done before rendering!

It will have no effect if done after rendering, and a warning will be printed to the console.

Feature Highlights

  • Supports nested selectors with SCSS-like parent references (&)
  • Supports block (/* ... */) and line (//) comments.
  • Supports all CSS at-rules (eg. @media, @font-face, @keyframes, etc.)
  • Supports class name hash and style injection customization (See the configure function).
  • Supports interoperability with previous version of itself (>= v4.0.0).
  • Styles are injected on first render and de-duplicated (cached) when used repeatedly.
  • Styles are removed (GC-ed) when unused.
  • Class names are stable (deterministic) to support SSR and testing.
  • SSR (server-side rendering) "just works" with zero-configuration.
  • Works with concurrent mode.
  • No extra compilation is required, so it works anywhere.
  • No runtime dependencies.
  • Tiny bundle size.

In comparison to other libraries

Like @emotion/react, but you don't have to use a special JSX pragma or worry about css property gotchas.

Like styled-components or @emotion/styled, except you still control the React markup, SSR works without any configuration, and you don't have to create multiple components to have styled component children.

Like styled-jsx, but you don't need a babel plugin, styles precede styled components, and you can style more than one component at a time.

It can be used in component libraries, because it's small, has no dependencies, works when multiple versions are resolved, and requires no setup.