Stop using CSS in JavaScript for web development

9 fairy tales

Little Red Riding Hood

History of CSS and JavaScript

What about CSS?

Styled-components

import React from 'react';
import styled from 'styled-components';
// Create a <Title> react component that renders an <h1> which is
// centered, palevioletred and sized at 1.5em
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
// Create a <Wrapper> react component that renders a <section> with
// some padding and a papayawhip background
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
// Use them like any other React component – except they're styled!
<Wrapper>
<Title>Hello World, this is my first styled component!</Title>
</Wrapper>
Live demo

Myth #1: It solves the global namespacing and styling conflicts

Myth 2: Using styled-components makes for a more succinct code

<TicketName></TicketName>
<div className={styles.ticketName}></div>
<TinyBitLongerStyleName></TinyBitLongerStyleName>
<div className={styles.longerStyleName}></div>

Myth 3: Using styled components makes you think more about semantics

<PersonList>
<PersonListItem>
<PersonFirstName>Foo</PersonFirstName>
<PersonLastName>Bar</PersonLastName>
</PersonListItem>
</PersonList>
<ol>
<li>
<span className={styles.firstName}>Foo</span>
<span className={styles.lastName}>Bar</span>
</li>
</ol>

Myth 4: It makes it easy to extend styles

const Button = styled.button`
padding: 10px;
`;
const TomatoButton = Button.extend`
color: #f00;
`;
button {
padding: 10px;
}
button.tomato-button {
color: #f00;
}

Myth 5: It makes it easy to conditionally style components

<Button primary />
<Button secondary />
<Button primary active={true} />
styled.Button`
background: ${props => props.primary ? '#f00' : props.secondary ? '#0f0' : '#00f'};
color: ${props => props.primary ? '#fff' : props.secondary ? '#fff' : '#000'};
opacity: ${props => props.active ? 1 : 0};
`;
button {
background: #00f;
opacity: 0;
color: #000;
}
button.primary,
button.seconary {
color: #fff;
}
button.primary {
background: #f00;
}
button.secondary {
background: #0f0;
}
button.active {
opacity: 1;
}
button {
background: #00f;
opacity: 0;
color: #000;

&.primary,
&.seconary {
color: #fff;
}
&.primary {
background: #f00;
}
&.secondary {
background: #0f0;
}
&.active {
opacity: 1;
}
}

Myth 6: It allows better code organization

Myth 7: It makes the DX great. The tooling is awesome!

  • When something goes wrong with styling, the entire app will crash with a long stack trace error (anecdotal experience using v2). Contrast this with CSS, where a “style error” will merely incorrectly render the element.
  • Elements do not have a recognizable className, therefore you will end up switching between React element tree and DevTools DOM tree when debugging (for the record, in v2 this can be addressed using babel-plugin-styled-components).
  • No linting (there is a stylelint plugin in development).
  • Invalid styles are simply ignored (e.g. clear: both; float left; color: #f00; will give no error or warning; good luck debugging, took me about 15 minutes of going through the stack traces, even reading styled-components source code. Only when I copy-pasted the code in a chat to ask for help did someone notice the missing :. You’ve noticed it, right?)
  • Syntax highlighting, code completion, and other IDE niceties are supported in few IDEs. If you are working with finance or governmental agencies, chances are that Atom IDE is not on the table.

Myth 8: Anything better performance, anything smaller bundle size

  • As it stands, styled-components cannot be extracted into a static CSS file (such as using https://github.com/webpack-contrib/extract-text-webpack-plugin). Meaning that your browser is not able to start interpreting styles until after styled-components parses them and adds them to the DOM.
  • Lack of separate files means that you cannot cache separately CSS and JavaScript.
  • All styled components are wrapped in an additional HoC by their nature. Thats an unnecessary performance hit. The same architectural flaw is the reason why I’ve discontinued https://github.com/gajus/react-css-modules (and created https://github.com/gajus/babel-plugin-react-css-modules).
  • Because of the HoC, if you are rendering server-side, this is going to result it a lot bigger markup document.
  • Don’t get me started on animating components using dynamic style values vs keyframes.

Myth 9: It allows developing responsive components

@element {selector} and {condition} [ and {condition} ]* { {css} }
  • {selector} is a CSS selector targeting one or many elements. Ex: #id or .class
  • {condition} is composed of a measure and a value.
  • {css} can contain: Any valid CSS rule. (Ex: #id div { color: red })
Meowway!

But wait!

So what to use today?

What are the arguments for using CSS in JS?

If (you support my open-source work through Buy me a coffee or Patreon) {you will have my eternal gratitude 🙌}

--

--

Founder, engineer interested in JavaScript, PostgreSQL and DevOps. Follow me on Twitter for outbursts about startups & engineering. https://twitter.com/kuizinas

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Gajus Kuizinas

Founder, engineer interested in JavaScript, PostgreSQL and DevOps. Follow me on Twitter for outbursts about startups & engineering. https://twitter.com/kuizinas