Styles under pressure: CSS-in-JS, CSS variables, and zero runtime
Ant Design's Button showed how a component can keep a complete vocabulary of variants and states while consuming shared tokens. That design creates a second problem: how should the library produce and manage all of those styles? This chapter compares Ant Design's component-level CSS-in-JS, hashed scopes, CSS variables, and zero-runtime output. The aim is not to name one universally best mode, but to match each mode to the problem it actually solves: stable component reuse, fast theme switching, isolated nested themes, or removing runtime style generation.
Why Ant Design specializes CSS-in-JS for components
Application-level CSS-in-JS and component-library CSS-in-JS have different operating conditions. In an application, a style may depend on arbitrary props, local data, layout state, and user-authored combinations. The style engine cannot assume that a component's complete style graph is stable. In Ant Design, the library controls the component implementations and knows the set of variants and states that a component promises. That makes a narrower optimization possible.
The project's CSS-in-JS explanation describes a component style as stable for a given library version and theme. Instead of repeatedly serializing a large CSS object to discover a hash, the library can use the version and theme inputs as a stable basis for component-level caching. The Button style hook registers shared, size, variant, block, and group rules as one component style system. Once a matching component and theme have been processed, later uses can reuse the cached result rather than regenerate a new stylesheet for every Button instance.
This is why a component library can cache more aggressively than an arbitrary application stylesheet. The library owns the style graph, and ordinary component props select among rules that already exist. A Button's loading prop changes behavior and class selection; it does not require the library to invent an entirely new Button stylesheet with unknown application CSS. The same reasoning applies to a Table or Modal whose supported states are known in advance.
The optimization has a boundary. The project's own article says that the component-level solution is not intended as a general application styling engine. An application needs flexibility for arbitrary components and often benefits from automatic scoping such as CSS Modules. Reusing a library's component-level assumptions for a large body of application-specific styles would make cache identity and troubleshooting harder. In other words, the constraint that improves Ant Design's component reuse—stable, predefined style graphs—also limits its role as a replacement for application styling architecture.
The hash has two related jobs in this design. It contributes to cache identity: a different library version or theme should not silently reuse the wrong rules. It also helps isolate styles and theme scopes, especially when nested themes use the same semantic class names with different values. The hash is not meaningful because it looks random; it is meaningful because it marks the conditions under which a style result is valid.
That makes a hash a useful debugging clue. If two Buttons under different themes should look different, they need a scope that prevents one theme's values from leaking into the other. If a team disables hashing because its application contains only one Ant Design version, it is accepting a simpler output boundary in exchange for less isolation. The repository documents that choice as a configuration option, not as a universal improvement.
Hashing is also tied to output cost. The CSS-in-JS article notes that Ant Design's component-level approach can include a component's complete style set even when a page uses only one variant. This can make CSS output larger, particularly in server-side rendering where style tags may be emitted into the response.