23
5 CSS-in-JS Frameworks to use in 2021
by author Nwose Lotanna Victor
As web development continues massive evolving, new ways of doing things emerge, and communities get built around them. Handling frontend development with JS frameworks, styling components have been all about having separately dedicated stylesheets for each component which are now applied to the DOM.
CSS can be really exhausting for developers, maintaining styles across components and context switching can become a chore, you can also relate to this if you have spent some time trying to center a div or a button before. Developers who primarily work with JavaScript started to innovate around styling and asking what if it can also be done in JS.
CSS-in-JS is a new approach to styling using JavaScript to style components in-line, on compile, the JS is parsed and CSS rules are generated and pushed to the DOM. This means you do not really have to carry the burden of the CSS learning curve, neither do you need to fully understand it as it is now totally abstracted for you. This approach promises to be more maintainable, easier to use (as you stick to the JS you already know) and some even have special features built to enhance CSS.
In today’s post, we will be looking at a few of these CSS-in-JS frameworks you can try out in your workflow right away.
This is the most popular CSS-in-JS library that currently exists and the term CSS-in-JS was also made very popular by Styled Components. With widespread usage, over 35,000 stars on GitHub with over 10m projects using it per month Styled Components lets you define CSS styles inline using ES6 template literals. Popular in the React community for styling React components easily. This is how easy a button is styled:
import styled from 'styled-components'
const Button = styled.button``
The style definition would look like this:
const Button = styled.button`
background: transparent;
border-radius: 3px;
border: 2px solid palevioletred;
color: palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
`
Styled Components comes with a lot of advantages asides we general ones we already mentioned above, you can do selector nesting, just like with SASS. You also never need to worry about class name bugs as it generates unique class names automatically and manages them as they go in and out of the DOM.
The first special thing about Emotion as a CSS-in-JS library is that is framework agnostic so you can use it in Vue and Angular projects as well as React too. With over 13,000 stars on GitHub Emotion is a very flexible library that is built on other CSS-in-JS libraries and another great thing about it is how it is predictable so even with little knowledge of CSS, you can start using it without any issues. It has a really cool documentation, the vue-style that you are probably already familiar with and is very performant.
A hover button in Emotion looks like this:
import { css, cx } from '@emotion/css'
const color = 'white'
render(
<div
className={css`
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
&:hover {
color: ${color};
}
`}
>
Hover to change color.
</div>
)
Debugging a web application in production may be challenging and time-consuming. OpenReplay is an Open-source alternative to FullStory, LogRocket and Hotjar. It allows you to monitor and replay everything your users do and shows how your app behaves for every issue.
It’s like having your browser’s inspector open while looking over your user’s shoulder.
OpenReplay is the only open-source alternative currently available.
Happy debugging, for modern frontend teams - Start monitoring your web app for free.
This is a very interesting one, with almost 4,000 stars on GitHub Stitches is a CSS-in-JS library that runs in near-zero runtime. It supports server-side rendering and has variants support. Basically, CSS was re-imagined as a JS library with stitches. It is also framework agnostic so you can use it with any frontend development library. It ships with smart tokens and even custom CSS properties.
With Stitches, you do not have to download an entire library because it does style injection. With a fully-typed API, token-aware properties, and custom utils, Stitches offers a fun and intuitive experience all-round.
A simple button is created like this:
import { styled } from '@stitches/react';
const Button = styled('button', {
backgroundColor: 'gainsboro',
borderRadius: '9999px',
fontSize: '13px',
padding: '10px 15px',
'&:hover': {
backgroundColor: 'lightgray',
},
});
Radium took a kind of radical approach, eliminating CSS totally for inline styles and making all of those styles global. This basically provides us with scoped styling without using selectors, eliminating dead code or chances of repeattition and being totally expressive. You might say inline styles are limited by default, that is correct but Radium offers a standard interface that deals with issues like media queries and browser or mouse states like click or hover.
A button in Radium looks like this:
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](http://twitter.com/media)) with the additional rules.
':hover': {
background: color('#0074d9')
.lighten(0.2)
.hexString()
}
},
primary: {
background: '#0074D9'
},
warning: {
background: '#FF4136'
}
};
It was built for React applications, most of the CSS-in-JS libraries have dedicated React libraries too.
A button looks like this:
import React from 'react'
import {render} from 'react-dom'
import {createUseStyles} from 'react-jss'
// Create your Styles. Remember, since React-JSS uses the default preset,
// most plugins are available without further configuration needed.
const useStyles = createUseStyles({
myButton: {
color: 'green',
margin: {
// jss-expand gives more readable syntax
top: 5, // jss-default-unit makes this 5px
right: 0,
bottom: 0,
left: '1rem'
},
'& span': {
// jss-nested applies this to a child span
fontWeight: 'bold' // jss-camel-case turns this into 'font-weight'
}
},
myLabel: {
fontStyle: 'italic'
}
})
const Button = ({children}) => {
const classes = useStyles()
return (
<button className={classes.myButton}>
<span className={classes.myLabel}>{children}</span>
</button>
)
}
const App = () => <Button>Submit</Button>
render(<App />, document.getElementById('root'))
We have gotten acquainted with the concept of CSS-in-JS and how it can be useful to us in our workflow. We also took a look at a few CSS-in-JS libraries we can start using today. You can follow the State of CSS survey here where thousands of developers share their feeedback every year. Which is your favourite and why?
23