Beyond CSS-in-JS: From Element Styles To Component Themes
This is part of my Building Fluentic Style series, where I’m writing down the design decisions, tradeoffs, and small surprises from building Fluentic Style . I started Fluentic Style with a small idea: I wanted React Native-style composition in React web. < View style = { [ base , active && activeStyle , props . style ] } /> That kind of style composition always felt practical to me. You have a…
This article discusses the evolution of Fluentic Style, a design system that aims to address the challenges of styling in React applications. The core concept began with the desire to implement React Native-style composition in React web, allowing for easy style composition using a base style, active state styles, and prop styles. The initial implementation looked like this:
div css = { [ base, active && selected, props.css ] }
However, as Fluentic evolved, it became apparent that the problem was not solely about CSS-in-JS or build-time extraction. The real challenge was the need for a better pattern for component-level styling and theming that could move from app-wide defaults down to specific components.
The key question emerged: Can a styling system cover the everyday path from styling an individual element, through reusable components, component themes, and app-wide themes, while maintaining usability in both debugging and production extraction?
The article emphasizes that CSS-in-JS, while useful, only solves one aspect of styling. Real app styling involves multiple layers: element styles, component styles, component variants, component themes, and app-wide themes. Many existing styling approaches excel in specific areas, such as quick element styles, app-wide tokens, utility classes, local CSS files, runtime dynamic values, extracted CSS, or a combination of these.
However, in practice, developers often require a unified system to handle all these layers seamlessly.
The article then introduces the concept of starting with one element. For simple cases, Fluentic allows for straightforward style attachment to a single element:
const saveButton = style ({
borderRadius: 8,
padding: "8px 12px",
});
button css = { saveButton }
To handle hover, media, or state styles, the style can be extended:
const saveButton = style ({
borderRadius: 8,
padding: "8px 12px",
}).hover({
backgroundColor: "#f3f4f6",
});
button css = { saveButton }
For utility-class authoring, Fluentic also offers flexibility, allowing developers to combine styles using a utility-class approach:
const saveButton = cx(
inline-flex,
items-center,
rounded-md,
px-3,
py-2,
).hover({
bg-slate-100,
});
button css = { saveButton }
This approach maintains simplicity for styling individual elements while providing more advanced options for reusable components and themes. The article concludes by highlighting Fluentic's goal of seamlessly integrating these different styling layers, from simple element styles to complex component themes and app-wide themes, without isolating each layer into separate systems.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.