Why I Switched from traditional CSS/SCSS to CSS-in-JS libraries

Sunny Yadav
5 min readApr 28, 2024

Let’s dive into a new way of styling websites: CSS-in-JS. Traditional web development often involves writing CSS code in separate files or using preprocessors like SCSS. But CSS-in-JS changes that game. It lets us write CSS styles directly within our JavaScript files. Picture this: instead of juggling between CSS files and JavaScript logic, we can keep everything in one place. This approach, offers a more cohesive development experience by encapsulating styles with their corresponding components, resulting in improved modularity and reusability. This is offered by libraries like Emotion, Styled Components, and MUI Styled, is gaining popularity for its simplicity and efficiency.

CSS-in-JS offers a significant advantage by solving a common headache in traditional CSS: the global scope chaos. In simpler terms, when we use CSS-in-JS, we tie our styles directly to specific components. This means that styles stay within their own little bubbles, preventing them from accidentally affecting other parts of our website. This makes our styling behavior more predictable and makes it easier for us to keep our code organized and maintain it over time.

Moreover, CSS-in-JS tools come with some pretty cool features. They can automatically add those tricky vendor prefixes to our styles, which saves us a ton of time. They can also get rid of any unused styles, making our code cleaner and more efficient. And get this — they can even change our styles based on what’s happening in our components. Like, if a button is clicked, we can make it change color or size using JavaScript magic.

On top of all that, CSS-in-JS makes it super easy to create reusable pieces of our website. We’re talking about components that come with their own styles packaged right alongside their functionality. This makes them like little building blocks that we can easily move around and share with other developers. It’s like having a set of Legos that fit perfectly together every time, making teamwork a breeze.

Let’s compare a traditional CSS approach with CSS-in-JS using Emotion as an example.

Traditional CSS:

/* styles.css */
.button {
background-color: blue;
color: white;
padding: 10px 20px;
border: 2px solid blue;
border-radius: 5px;
cursor: pointer;
}

.button:hover {
background-color: darkblue;
}
// App.js
import React from 'react';
import './styles.css';

function App() {
return (
<div>
<button className="button">Hello, World!</button>
</div>
);
}

export default App;

This CSS code defines styles for a button element with the class .button. It sets the background color, text color, padding, border, border radius, and cursor properties. Additionally, it specifies a hover effect where the background color changes to dark blue when the button is hovered over.

CSS-in-JS with Emotion:

// App.js
import { css } from '@emotion/react';
import styled from '@emotion/styled';

// Define a styled button component
const Button = styled.button(props => ({
backgroundColor: props.primary ? 'blue' : 'white',
color: props.primary ? 'white' : 'blue',
padding: '10px 20px',
border: '2px solid blue',
borderRadius: '5px',
cursor: 'pointer',
'&:hover': {
backgroundColor: props.primary ? 'darkblue' : 'lightblue',
},
}));

// Usage of the Button component
function App() {
return (
<div>
<Button primary>Hello, World!</Button>
</div>
);
}

This code creates a button that changes color when hovered over, and its style can change based on the primary prop. Neat, right?

The styled.button function from Emotion is used to create a styled button component called Button. This function takes in a object containing the CSS styles defined earlier. This injects the styles into the button component.

Traditional CSS VS CSS-in-JS-

Global Scope Management:

  • Traditional CSS: Classes are globally scoped, which can lead to unintended style overrides and class name clashes.
  • CSS-in-JS: Styles are encapsulated within components, reducing the risk of global scope issues and providing more predictable styling behavior.

Dynamic Styling:

  • Traditional CSS: Limited support for dynamic styling based on component state or props.
  • CSS-in-JS: Allows for dynamic styling using JavaScript, enabling conditional styles based on component state or props. In the example, the button’s background color changes dynamically based on the :hover pseudo-selector and the primary prop.

Code Organization:

  • Traditional CSS: Styles are stored in separate CSS files, leading to a separation of concerns between markup and styles.
  • CSS-in-JS: Styles are defined directly within JavaScript files, keeping components and their styles together. This can improve code readability and maintainability, especially for small to medium-sized projects.

Tooling Support:

  • Traditional CSS: Well-established tooling support with various preprocessors (e.g., SCSS) and build tools.
  • CSS-in-JS: Growing ecosystem of tools and libraries, although may not be as mature as traditional CSS tooling. However, libraries like Emotion provide features like automatic vendor prefixing and dead code elimination to enhance productivity.

Advantages:

  1. Say goodbye to the mess of global styles! With CSS-in-JS, styles stick with their components, so no more accidental clashes.
  2. Cool time-saving stuff like adding those annoying vendor prefixes automatically and getting rid of unused code makes our coding life smoother.
  3. Our styles can groove along with our components, changing styles based on what’s happening in our app.
  4. Reusing stuff becomes easy. Components come bundled with their own styles, so we can easily move them around and share them with others.

Disadvantages:

  1. Our code might bulk up a bit because of all the styles bundled in with our components. It’s like adding a few extra pounds to our website’s weight.
  2. Learning CSS-in-JS can be a bit tricky if we’re used to the old-school CSS way of doing things. It’s like learning a new dance move — it takes some practice.
  3. There aren’t as many fancy tools and plugins for CSS-in-JS as there are for old-school SCSS. It’s like having fewer toys to play with in our coding sandbox.

Conclusion

In the grand scheme of web development, the shift from CSS/SCSS to CSS-in-JS is a game-changer. Sure, there are hurdles to overcome, but the benefits far outweigh the drawbacks. With libraries like Emotion leading the charge, we can streamline our styling process, create more maintainable code, and build better websites. So, why did I switch? Because CSS-in-JS isn’t just a trend — it’s the future of web styling.

--

--

Sunny Yadav

Frontend engineer. Loves clean code & user-friendly design. Proficient in HTML, CSS, JS, TS, React.JS and Next.JS. Constantly learning