Telerik blogs
ReactT Dark_870x220

We thought React was crazy when it came with HTML-in-JS (JSX), but today, we are happy that revolution happened. It helped us build better components. Why not do so with CSS too? As a matter of fact, you can. Meet CSS-in-JS.

Since the emergence of React, there’s been a serious debate about writing CSS in JavaScript. Some were strongly against it while some were curious enough to give it a try. But slowly, over time, adoption of CSS-in-JS libraries has increased significantly and new libraries are being churned out by the hour.

Today, we’ll be looking at some of the popular CSS-in-JS libraries that have become a mainstay in our applications and projects. We’ll list some of them in no particular order, with examples and a walkthrough of their implementation.

Glamor

A few of the libraries listed here were built around Glamor, which means that there’s a lot that Glamor does right in its CSS-in-JS implementation. Glamor allows composition, which means you can easily overwrite CSS rules by spreading new rules within a component’s class name or within its props. The ability to write and combine CSS rules makes Glamor a pretty interesting pick.

Let’s create a button component using Glamor’s rule combining and spreading features:

const rule = css({  
	padding: '1rem 4rem';  
	margin: '10px 20px';  
	border-radius: '5px';  
	background: 'linear-gradient(90deg, #D26AC2, #46C9E5)';  
	color: '#1D2029';  
})  
  
const primaryRule = css({  
	color: '#D26AC2'  
	background: 'red'  
})  
  
//As data attributes  
<button {...rule} {...primaryRule}>  
	Primary button  
</button>  
  
// As classes  
<button className={`${rule} ${primaryRule}`}>  
	Primary button  
</button>  

Glamorous

As a JavaScript developer and a CSS-in-JS skeptic, you’ll enjoy the syntax adopted by Glamorous. It provides the familiar JavaScript syntax for styling components and creating dynamic themes. By letting users provide dynamic props for styling, it has an edge over some of the other libraries in this list. Also, Glamorous was built on the popular JavaScript CSS-in-JS library Glamor.

The project is currently not actively maintained. So you should think hard before going with this option.

It has a simple, easy-to-understand API:

const Heading = glamorous.button({  
	fontSize: '14px',  
	marginTop: 10,  
	color: '#CC3A4B',  
	padding: '1rem 4rem',  
	margin: '10px 20px',  
	'border-radius': '5px',  
	background: 'linear-gradient(90deg, #D26AC2, #46C9E5)',  
	color: '#1D2029',  
});  

Emotion

Using template literals and object styles, Emotion allows you to style apps quickly. It provides source maps and labels while also providing two separate methods of styling applications. If you’re not familiar with template literals and would rather use object styles, Emotion supports both.

They took what was so great about other CSS-in-JS libraries and combined them into a great library. They provide support for props and composition. It is performant and provides heavy caching in production, according to their documentation. Emotion has a theming library and supports server-side rendering.

We can style button component using template literals and object styles:

// template literals  
const Button = styled.a`  
	padding: 1rem 4rem;  
	margin: 10px 20px;  
	border-radius: 5px;  
	background: ${(props) =>  
		props.background && 'linear-gradient(90deg, #D26AC2, #46C9E5)'};  
	color: ${(props) => (props.primary ? '#1D2029' : '#D26AC2')};  
	&:hover {  
		opacity: 0.95;  
	}  
`;  

Using object styles:

// Object styles  
const Button = styled.a(props => ({  
	padding: '1rem 4rem',  
	margin: '10px 20px',  
	border-radius: '5px',  
	background: props.background && 'linear-gradient(90deg, #D26AC2, #46C9E5)',  
	color: props.primary ? '#1D2029' : '#D26AC2',  
}));  

Styled-components

Styled-components is (according to Github stars) the most popular CSS-in-JS library out there. It uses tagged template literals to style your components. It removes the mapping between components and styles, making it easier to achieve low-level styling. Styled-components generates unique class names for all your components, so you don’t ever have to worry about conflicting class names.

Styled-components has a very rich and intuitive API alongside a huge community following. It fully supports server-side rendering, React Native, theming, media queries and a lot more.

Creating a button component using Styled-components would look like this:

const Button = styled.button`  
	padding: 1rem 4rem;  
	margin: 10px 30px;  
	color: ${(props) => props.color};  
	background: ${(props) => props.background};  
	border: none;  
	border-radius: 4px;  
`;  

Radium

Radium is one of the original CSS-in-JS libraries. It aims to achieve CSS capabilities like media queries, selectors, psuedo-selectors and modifiers without writing CSS. It favors an expressive and optimized (through dead code elimination) style of development. Some other features supported by Radium are:

  • Automatic vendor prefixing
  • Keyframes animation helper
  • ES6 class and createClass support
  • Media queries

Creating a button component using Radium has a somewhat familiar feel:

import Radium from 'radium';  
import React from 'react';  
import color from 'color';  
  
class Button extends React.Component {  
	static propTypes = {  
		kind: PropTypes.oneOf(['primary', 'warning']).isRequired  
	};  
  
	render() {  
		// Radium extends the style attribute to accept an array. It will merge  
		// the styles in order. We use this feature here to apply the primary  
		// or warning styles, depending on the value of the `kind` prop. Since its  
		// all just JavaScript, you can use whatever logic you want to decide which  
		// styles are applied (props, state, context, etc).  
		return (  
		<button  
		style={[  
			styles.base,  
			styles[this.props.kind]  
		]}>  
		{this.props.children}  
		</button>  
		);  
	}  
}  
  
Button = Radium(Button);  
  
// You can create your style objects dynamically or share them for  
// every instance of the component.  
var styles = {  
	base: {  
		color: '#fff',  
  
// Adding interactive state couldn't be easier! Add a special key to your  
// style object (:hover, :focus, :active, or @media) with the additional rules.  
		':hover': {  
			background: color('#0074d9').lighten(0.2).hexString()  
		}  
	},  
  
	primary: {  
		background: '#0074D9'  
	},  
	  
	warning: {  
		background: '#FF4136'  
	}  
};  
  
//Primary button  
<Button primary>Primary</Button>  
  
//Warning button  
<Button warning>Warning</Button>  

We’ve had a brief look at five out of several hundreds of CSS-in-JS libraries out there, each with a distinct approach of solving a familiar problem. Other notable mentions are React-CSS-Modules, Styletron, jsxstyle and Aphrodite.

You can visit this css-in-js GitHub repository, which has a list of most of the CSS-in-JS implementations available. Have a look at the list and pick one that piques your interest.


For more info on building apps with React:  Check out our All Things React page that has a wide range of info and pointers to React information – from hot topics and up-to-date info to how to get started and creating a compelling UI.


About the Author

Christian Nwamba

Chris Nwamba is a Senior Developer Advocate at AWS focusing on AWS Amplify. He is also a teacher with years of experience building products and communities.

Related Posts

Comments

Comments are disabled in preview mode.