/styletron

:zap: Toolkit for component-oriented styling

Primary LanguageJavaScriptMIT LicenseMIT

Styletron logo

build status

Toolkit for component-oriented styling

Check our documentation at styletron.org.

Looking for v3.x docs? | v3.x to v4.x migration guide

Packages

Design principles

  1. Component-oriented
    • Stateless, single-element styled components as base styling primitive
    • Prop interfaces for conditional/dynamic styling
  2. Embrace typed JavaScript
    • Composition of styles via (typed) JavaScript objects
    • No extra tooling (e.g. Webpack loaders, Babel plugins, etc.)
  3. Portability and flexibility
    • Portability of styled components across different rendering engines (e.g. atomic CSS)

See docs/design.md for more details.

Getting Started

Defining styled components

import {styled} from "styletron-react";

// Create a styled component by passing an element name and a style object
const RedAnchor = styled("a", {color: "red"});

<RedAnchor href="/foo">Hello</RedAnchor>;

// Or pass a function that takes props and returns a style object
const Panel = styled("div", props => {
  return {backgroundColor: props.$alert ? "orange" : "lightblue"};
});

<Panel $alert>Hello!</Panel>;

See packages/styletron-react for full documentation

Composing styled components

styletron-react also provides composition helpers such as withStyle to build styled components from existing styled components.

import {withStyle} from "styletron-react";

const FancyAnchor = withStyle(RedAnchor, {fontFamily: "cursive"});

<FancyAnchor href="/foo">Hello</FancyAnchor>;

const DeluxePanel = withStyle(Panel, props => ({
  backgroundColor: props.alert ? "firebrick" : "rebeccapurple",
  color: "white",
  boxShadow: "3px 3px 3px darkgray"
}));

<DeluxePanel>Bonjour Monde</DeluxePanel>;

See packages/styletron-react for full documentation

Providing a rendering engine

Styled components require a rendering engine to perform side effects (such as rendering styles to the page).

import {Provider as StyletronProvider} from "styletron-react";
import {Client as Styletron} from "styletron-engine-atomic";

// 1. Create a client engine instance
const engine = new Styletron();

// 2. Provide the engine to the app
React.render(
  <StyletronProvider value={engine}>
    <App />
  </StyletronProvider>
);

Server-side rendering

Extracting server-rendered styles

import {Provider as StyletronProvider} from "styletron-react";
import {Server as Styletron} from "styletron-engine-atomic";

// 1. Create a server engine instance
const engine = new Styletron();

// 2. Provide the engine to the app
const html = React.render(
  <StyletronProvider value={engine}>
    <App />
  </StyletronProvider>
);

// 3. Extract critical styles after SSR
const styles = engine.getStylesheetsHtml();
// → "<style ..."

Hydrating server-rendered styles

When server-side rendering, pass the server-rendered styled elements to the client engine constructor to hydrate the client-side cache. This prevents these styles from being re-rendered and avoids potential style conflicts.

import {Provider as StyletronProvider} from "styletron-react";
import {Client as Styletron} from "styletron-engine-atomic";

// create an engine instance
- const engine = new Styletron();
+ const engine = new Styletron({hydrate: document.getElementsByClassName("_styletron_hydrate_")});

// wrap root component with provider
React.render(
  <StyletronProvider value={engine}>
    <App/>
  </StyletronProvider>
);

See packages/styletron-engine-atomic for full documentation.

Tradeoffs

See TRADEOFFS.md