Understanding the Implementation of CSS-in-JS with Styled-Components
The article explains CSS‑in‑JS fundamentals, examines styled‑components’ source code—including its styled function, createStyledComponent factory, and runtime style injection—compares it with emotion, demonstrates a simple SolidJS MVP implementation, and discusses the technique’s rise, limitations, and possible compile‑time or atomic‑CSS future.
This article introduces the principles behind CSS-in-JS and walks through the source code of styled-components to reveal how the library creates styled React components.
Research : The author compares two popular CSS‑in‑JS libraries, emotion and styled-components . Due to the mixed TypeScript/Flow code in emotion , the author chooses styled-components for deeper analysis.
Core API : The entry point is the styled function, which ultimately calls createStyledComponent . The API also provides shortcuts like styled.div for HTML elements.
const baseStyled = (tag) =>
constructWithOptions(createStyledComponent, tag);
const styled = baseStyled;The constructWithOptions factory returns a template function that receives a template string and interpolations:
export default function constructWithOptions(componentConstructor, tag, options) {
const templateFunction = (initialStyles, ...interpolations) =>
componentConstructor(tag, options, css(initialStyles, ...interpolations));
return templateFunction;
}When a component is rendered, useInjectedStyle generates a unique class name, injects a <style> tag into the document, and returns the class name:
function useInjectedStyle(componentStyle, isStatic, resolvedAttrs, warnTooManyClasses) {
const styleSheet = useStyleSheet();
const stylis = useStylis();
const className = isStatic
? componentStyle.generateAndInjectStyles(EMPTY_OBJECT, styleSheet, stylis)
: componentStyle.generateAndInjectStyles(resolvedAttrs, styleSheet, stylis);
return className;
}The author also builds a minimal MVP implementation for SolidJS, consisting of two simple functions:
const createClassName = (rules) => {
return () => {
className++;
const style = document.createElement('style');
style.dataset.sc = '';
style.textContent = `.sc-${className}{${rules[0]}}`.trim();
document.head.appendChild(style);
return `sc-${className}`;
};
};
const createStyledComponent = (tag) => {
return (rules) => {
const StyledComponent = (props) => {
const className = createClassName(rules);
const [local, others] = splitProps(props, ['children']);
return (
{local.children}
);
};
return StyledComponent;
};
};The article discusses why CSS‑in‑JS became popular (tight coupling with JSX, no need for separate CSS files, easier dynamic styling) and its drawbacks (runtime parsing, larger JS bundles, render‑blocking). It also speculates on future directions, such as moving runtime parsing to compile time and combining with atomic CSS.
Finally, the author shares a brief team introduction from Alibaba’s cross‑platform tech department, indicating the practical relevance of the research.
DaTaobao Tech
Official account of DaTaobao Technology
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.