In 2015, a JavaScript library called JSS (which is still actively maintained) was launched, which allowed developers to use JavaScript to describe styles in a declarative, conflict-free, and reusable way. JSS will automatically apply the declared properties to their respective selectors after the page is loaded. As frontend JavaScript (JS) libraries like React grew in popularity, they came up with a new CSS-in-JS solution called Styled-Components. What CSS-in-JS libraries like Styled-Components and Emotion have in common is that they all allow web developers to write CSS properties for components via JavaScript. This web development tutorial will introduce some of the general features of CSS-in-JS, as well as discuss its strengths and weaknesses. Finally, you also need to know what to look for when deciding between a CSS library like CSS-in-JS, LESS or SASS and good ole vanilla CSS.
How does CSS-in-JS work?
As the name suggests, CSS-in-JS allows programmers to style their components by writing CSS directly in their JavaScript or TypeScript code. Of course, you can do this yourself by defining constants, as shown in the code example below:
const styles = background: "#FE0000", color: "#FFFFFF" ;
Then all you have to do is pass it up to the element Style attribute, like this:
<div style=styles> <!-- some content --> </div>
Although there is nothing wrong with using inline styles like this, this approach is severely limited because plain objects like this are missing a lot of useful CSS features. For that reason, most developers choose to go with a library, of which there are many. Here’s an example of a styled React button using styled components:
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
width: 90px;
height: 40px;
background: $props => props.active ? "black" : "darkgrey";
color: blue;
`;
const Button = () => (
<StyledButton>
My Styled Button
</StyledButton>
);
export default Button;
Note that we can set values dynamically based on conditional values props,
Look: Learn JavaScript from scratch for $30
Framework-specific vs framework-agnostic libraries
Now that we’ve established that using a CSS-in-JS library pays off, let’s explore the two prevalent types: framework-specific and framework-agnostic.
Some libraries, such as Radium and JSX, only work with a specific JavaScript framework. For example, Radium was built for React apps, while Styled JSX only supports components written in JSX (though it can be used with React as well).
Not surprisingly, framework-specific CSS-in-JS libraries use the same syntax for the framework they support. For example, Styled uses template literals within JSX syntax to add CSS styles to JSX components. Here’s an example of styled JSX code that creates a dynamically styled button:
const Button = props => (
<button>
props.children
<style jsx>`
button
padding: $'large' in props ? '40' : '22'px;
background: $props.theme.background;
color: #555;
display: block;
font-size: .5em;
`</style>
</button>
)
Other CSS-in-JS libraries like jss, emotion, and styled components are framework-agnostic, meaning you can use them with any component-based framework or even plain JavaScript. Other libraries such as Aphrodite also work with Web Components.
Here’s an example of a web component that uses Aphrodite to set the background color:
/* Registers a Web Component with blue background */
import StyleSheet, css from 'aphrodite';
const styles = StyleSheet.create(
blue:
backgroundColor: 'blue'
);
class App extends HTMLElement
attachedCallback()
this.innerHTML = `
<div class="$css(styles.red)">
This is red.
</div>
`;
document.registerElement('my- app', App);
Look: bitbucket review
Benefits of CSS-in-JS
Whichever library you choose, all include the following features:
- Scoped CSS: All CSS-in-JS libraries generate unique CSS class names. In addition, all styles are placed within the scope of their respective component, providing encapsulation without affecting any styling defined outside the component. This obviously avoids CSS class name collisions, specification wars, and spending a lot of time coming up with unique class names throughout the application.
- Server-Side Rendering (SSR): While Server-Side Rendering (SSR) does not provide much benefit in Single Page Apps (SPA), it is extremely useful in websites or applications that need to be parsed and indexed by search engines as it requires both the page and the styling to be generated on the server.
- Automatic Seller Prefix: All CSS-in-JS libraries provide vendor prefixes out-of-the-box. This is a great time saver because developers don’t have to figure out which features in older browsers require vendor prefixes.
Disadvantages of CSS-in-JS
CSS-in-JS is certainly not without its drawbacks. There are instances where project developers have abandoned this in favor of a more traditional CSS approach. Here are some reasons:
- runtime overhead: As the components render, the CSS-in-JS library must convert the styles to plain CSS to be inserted into the document. There is some debate as to whether or not this can have a significant impact on application performance. This will probably depend on a number of factors ranging from code complexity to hardware.
- Big Bundle Size: Every user using your application will need to download the JavaScript for the CSS-in-JS library. The emote is 7.9kb minzipped and the style-component is 12.7kb. React + react-dom is 44.5kB, for comparison, so a css-in-js library probably won’t be the straw that breaks the camel’s back.
Final Thoughts on CSS-in-JS
This tutorial introduced some of the general features of CSS-in-JS as well as its strengths and weaknesses. While CSS-in-JS offers many benefits, don’t rush to jump on the CSS-in-JS bandwagon just because all your friends are doing it. Be sure to consider all the pros and cons before making any decision. Although CSS-in-JS may be what you need, there may be tradeoffs you’re not ready to accept.











