𝗗𝘆𝗻𝗮𝗺𝗶𝗰 𝗧𝗵𝗲𝗺𝗶𝗻𝗴 𝗪𝗶𝘁𝗵𝗼𝘂𝘁 𝗖𝗦𝗦-𝗶𝗻-𝗝𝗦
I used to be a huge fan of styled-components. I loved the flexibility. Then I hit a wall.
One project needed to drop runtime weight. I decided to try CSS Modules and native CSS. The result surprised me. I deleted styled-components, Emotion, and goober from my projects. I lost nothing that I actually needed.
The biggest win was not just performance. It was removing the styling dependency. In one project, the CSS-in-JS runtime took up 30% of the client bundle.
Plain CSS has grown up. You no longer need heavy JS libraries for these tasks:
• Nesting: Use native CSS nesting. • Color shifts: Use color-mix(). • Specificity control: Use @layer. • Responsive components: Use container queries.
Here is how you build a theme using only one file and custom properties.
- Define tokens in a CSS file.
:root { --color-bg: #ffffff; --color-text: #1a1a1a; --color-accent: #3c7dc4; }
[data-theme="dark"] { --color-bg: #14161a; --color-text: #f5f5f0; --color-accent: #6aa6e8; }
- Use those variables in your components.
.button { background: var(--color-accent); color: var(--color-bg); }
- Switch themes by changing a single attribute.
function setTheme(theme) { document.documentElement.dataset.theme = theme; localStorage.setItem("theme", theme); }
Components do not need a ThemeProvider. They do not need to re-render. The browser handles the update through the cascade. This keeps most of your app in Server Components.
To avoid the "flash" of the wrong theme on page load, use a tiny inline script in your HTML head:
Stop using JS to generate styles at runtime. Use native CSS variables for your tokens. It results in less code and faster load times.
Source: https://dev.to/kirill_c_7b35589230/dynamic-theming-without-css-in-js-d7e
