What is CSS-in-JS? | neoco

/what-is-css-in-js

What is CSS-in-JS?

Marc Amer

Marc Amer

7 min

08/03/2022

What is CSS-in-JS?

It is a styling technique in which the CSS is defined in the JavaScript files where the components are developed, avoiding the use of .css files. This technique became popular with the appearance of libraries or frameworks based on components such as React, Vue or Angular.

How to use CSS-in-JS?

In order to start styling your components with CSS-in-JS what you have to do is install one of the many libraries at your disposal. Some of these are styled-components, JSS, emotion, etc.

Depending on the library you decide to use, the implementation will be carried out in one way or another. In this case we are going to see an example with styled-components:

import React, { useState } from "react";
import { colors } from "styles";
import styled from "styled-components";

const Button = styled.button(() => ({
  background: colors.yellow,
  color: colors.black,
  textAlign: "center",
  maxWidth: "300px",
  padding: "10px 20px",
  margin: "0 auto",
  fontWeight: 600,
  lineHeight: "19px",
  cursor: "pointer",
}));

function CTA({ text = "Buy Now!" }) {
  return <Button>{text}</Button>;
}

What disadvantages does CSS-in-JS have?

  1. Variety: As mentioned in the previous point, there are multiple options to choose from. CSS is just that, you create a file and start writing. Instead, if you want to start using CSS-in-JS you have to choose from one of the available options.

  2. Learning curve: Once you have chosen a library you have to learn how to use it, review its documentation and invest that time.

  3. Code more complicated to read: Some programmers think that using this type of libraries makes component files more complicated to read.

What advantages does CSS-in-JS have?

There are many advantages provided by this type of libraries, but some of the most important are:

  1. Dynamism: With dynamism I mean that the styles of a certain component react depending on the state of the component. Even using the most advanced properties that CSS3 provides us with, we cannot achieve something like this. To achieve this we should use techniques such as applying one class or another to certain elements depending on the state, let's see an example:
// Using CSS-in-JS / CTA.js

import React, { useState } from "react";
import { colors } from "styles";
import styled from "styled-components";

const Button = styled.button((props) => ({
  background: props.specialOffer ? colors.pink : colors.yellow,
  color: props.specialOffer ? colors.green : colors.black,
  textAlign: "center",
  maxWidth: "300px",
  padding: "10px 20px",
  margin: "0 auto",
  fontWeight: 600,
  lineHeight: "19px",
  cursor: "pointer",

  "&:disabled": {
    cursor: "default",
    opacity: 0.7,
  },
}));

const CTA = ({ text = "Buy Now!", isSpecialOffer }) => {
  const [isActive, setIsActive] = useState(true);

  return (
    <Button disabled={!isActive} specialOffer={isSpecialOffer}>
      {text}
    </Button>
  );
};

export default CTA;
/* Using CSS / styles.css */

:root {
  --neo-yellow: #fcff51;
  --neo-pink: #ff7373;
  --neo-green: #60bfb9;
  --neo-black: #0c0c0c;
}

.cta-base {
  background: var(--neo-yellow);
  color: var(--neo-black);
  text-align: center;
  max-width: 300px;
  padding: 10px 20px;
  margin: 0 auto;
  font-weight: 600;
  line-height: 19px;
  cursor: pointer;
}

.cta-base.special-offer {
  background: var(--neo-pink);
  color: var(--neo-green);
}

.cta-base:disabled {
  cursor: default;
  opacity: 0.7;
}
// Using CSS / CTA.js

import React, { useState } from "react";
import { colors } from "styles";
import styled from "styled-components";

const CTA = ({ text = "Buy Now!", isSpecialOffer }) => {
  const [isActive, setIsActive] = useState(true);

  return (
    <button
      disabled={!isActive}
      className={`cta-base ${isSpecialOffer ? "special-offer" : ""}`}
    >
      {text}
    </button>
  );
};

export default CTA;
  1. Local Scope: By default, CSS does not allow local scope, so you, as a developer, have to be very careful not to repeat classes (thus overwriting existing ones) or to edit styles by looking at a component and not realizing the changes you have made to the other elements that contain that class. The use of CSS-in-JS allows these libraries to perform classes dynamically depending on the component they are being called on, thus creating modules and preventing styles from being overridden and causing styling errors.

  2. Reuse: These styles can be located in separate files, as if it were one more component, and run as many times as you want. This allows these styles to only have to be defined once and used as much as desired.

Disarticulating the cons

  1. Variety: Nowadays, as a programmers, we are used to new technologies or techniques appearing constantly. Taking a look at them shouldn't be a problem.

  2. Learning curve: If using this technology brings us so many advantages, the learning curve should not be an obstacle, since if we are able to learn to use libraries like Redux, we can learn to use much simpler ones like styled-components. As we have seen in the previous examples, the implementation of a style is not far from anything we have not already done in JavaScript, especially if we have programmed in React, the notation is familiar to us from the already known in-line styles.

  3. Code more complicated to read: I strongly disagree with this "disadvantage". For me, seeing the styles located in the same .jsx file in which we have our component is a huge advantage. This gives you context to the code and allows you to immediately understand which elements of the component are styled and how.

Conclusion

All ways of styling are valid as long as there is a system and order. But if certain technologies ease our work, it is better to use them.