Stop using CSS in JavaScript for Web development

Original address: gajus.medium.com/stop-using-…

Gajus Kuizinas

CSS doesn’t appear anywhere. Many projects choose to style in JavaScript for the wrong reasons. This article lists common misconceptions and existing CSS solutions to these problems.

Nothing in this article is a personal attack on a specific project or person. I define “CSS in JavaScript” to use styled- Components, as this is the recent trend for styling components in React.

Styled – Component author (Max Stoiber and Glen Maddern; And other contributors) are smart people with smart ideas and good intentions.

For full transparency, I should also say that I’m the author of react-CSS-modules and babel-plugin-react-CSs-modules.

History of CSS and JavaScript

The Cascading style Sheet (CSS) language was created to describe the presentation of documents written in markup languages. JavaScript was created as a “glue language” for assembling components such as images and plug-ins. Over the past few years, JavaScript has evolved and changed to accommodate new use cases.

The advent of the Ajax term marks an important milestone. The Prototype, jQuery, MooTools, and other libraries at this time attracted a lot of community collaboration to solve the problem of background data fetching and cross-browser inconsistencies. This raises a new question: how to manage the data?

Fast forward to 2010, backbone. js emerged as the industry standard for application state management. Soon Knockout and Angular attracted everyone with two-way binding. React and Flux followed soon after. This ushered in the era of single-page applications, where applications are made up of components.

CSS?

Styled components, as in the documentation:

The problem with pure CSS is that it was created in an era when the Web was made up of documents. The Web was created in 1993 to exchange more scientific documents, and CSS was introduced as a solution for styling those documents. Today, however, we are creating rich, interactive, user-facing applications, and CSS is not built for these use cases.

I don’t agree.

CSS has evolved to meet the requirements of modern UIs. The number of new features (pseudo classes, pseudo elements, CSS variables, media queries, keyframes, relational selectors, columns, Flex, Grid, computed properties, etc.) has grown beyond reasonable bounds over the past decade.

From a UI perspective, a “component” is a separate piece of a document ( is a component). CSS is designed to style documents that contain all the components. What’s wrong with that?

As the saying goes, “Use the right tools for your job.”

Styled-components

Styled – Components allows you to write CSS in JavaScript using token template text. It removes the mapping between components and styles — components are constructed into low-level style structures, such as:

import React from 'react'; import styled from 'styled-components'; // Create a <Title> react component that renders an <h1> which is // centered, Style: style 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>Copy the code

Results:

Stylde-components is now emerging as the new way to style components in React.

Styled Components Let’s be clear about one thing: Styled – Components is just a higher level abstraction over CSS. All it does is parse the CSS you define in JavaScript and create JSX elements that map to the CSS.

I don’t like this trend because it is surrounded by a lot of misunderstanding.

I surveyed why people use Styled components on IRC, Reddit, and Discord, and compiled a list of common responses that choose to use styled components, which I call hypothems.

Hypothesis 1: It resolves global namespace and style conflicts

I call this a hypothesis because it sounds like these problems haven’t been solved yet. CSS Modules, Shadow DOM, and countless naming conventions have all been solved in the community for a long time.

I do not recommend that a new project rely on naming conventions. Naming conventions are prone to user errors.

Styled – Components (like the CSS module) take naming responsibility away from the human. Humans are fallible; And computers can reduce the frequency of mistakes.

In and of itself, this is not enough reason to start using gravitation-Components.

Hypothesis 2: Use styled- Components to make the code more concise

Here’s an example:

<TicketName></TicketName>
<div className={styles.ticketName}></div>
Copy the code

First of all — there’s no direct correlation. The difference is negligible.

Second, it’s not true. The total number of characters depends on the name of the style.

<TinyBitLongerStyleName></TinyBitLongerStyleName>
<div className={styles.longerStyleName}></div>
Copy the code

The same applies to the build styles mentioned later in this article. (Myth 5: It makes it easy to conditionally style components). Styled – Components wins only in the case of the underlying component.

Hypothesis 3: Using styled- Components will make you think more about semantics

This premise is false. Styles and semantics represent different problems that require different solutions. To quote Adam Morese:

Content semantics have nothing to do with visual style. In the past when I used Lego to build something, I never thought ‘oh, that’s part of the engine’, I’d think ‘Oh cool, that’s a 1×4 blue Lego, I can do anything I want with it’. Whether I’m building underwater voyager bases or airplanes, I know exactly how to use that Lego block.

– MRMRS. IO/writing / 201…

(I highly recommend reading Adam’s article on extensible CSS.)

Nonetheless, let’s take an example.

<PersonList>
  <PersonListItem>
    <PersonFirstName>Foo</PersonFirstName>
    <PersonLastName>Bar</PersonLastName>
  </PersonListItem>
</PersonList>
Copy the code

Semantics are about building tags with the right tags. Do you know what HTML tags these components will render? No, you don’t.

Compare:

<ol>
  <li>
    <span className={styles.firstName}>Foo</span>
    <span className={styles.lastName}>Bar</span>
  </li>
</ol>
Copy the code

Myth 4: It makes styles easier to extend

In the first version, you can use styled(StyledComponent) to extend the style structure; The extend method was introduced in the second version to extend existing styles, for example:

const Button = styled.button`
  padding: 10px;
`;
const TomatoButton = Button.extend`
  color: #f00;
`;
Copy the code

That’s very good. But you can do it in CSS (either using CSS module combinations, or using SASS to extend mixin@extend).

button {
  padding: 10px;
}
button.tomato-button {
  color: #f00;
}
Copy the code

What makes JavaScript methods easier?

Myth 5: It makes it easier to conditionally style components

The idea is that you can style components based on their props, for example:

<Button primary />
<Button secondary />
<Button primary active={true} /
Copy the code

This makes perfect sense in the React world. After all, component behavior is controlled through the use of props. But does it make sense to append the value of prop directly to the style? Maybe. But let’s look at component implementation first:

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}; `;Copy the code

The power of using JavaScript and conditionally creating stylesheets gives you a lot of power. However, this also means that styles are harder to explain. Compare this to the following CSS:

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;
}
Copy the code

In this case, the CSS code is much simpler and subjectively easier to understand. In addition, using preprocessors in CSS makes this code more streamlined and orderly, for example:

button { background: #00f; opacity: 0; color: #000; &.primary, &.seconary { color: #fff; } &.primary { background: #f00; } &.secondary { background: #0f0; } &.active { opacity: 1; }}Copy the code

Hypothesis 6: It allows for better code organization

Several people have said to me that they like Styled – Components because it allows styles and JavaScript to be included in the same file.

I can understand how tedious it is to set up multiple files for the same component, but cramming styles and marking them as a single file is also a terrible solution. Not only does this make version control difficult to track, but it also requires long scrolling in any component that isn’t a simple button.

If you must include CSS and JavaScript in a file, consider using CSS-litter-loader. The latter allows you to extract CSS at build time using extra-text-webpack-plugin and use your standard loader configuration to handle CSS.

Hypothesis 7: It makes DX better. The tools are great too!

Styled components are obviously not used by you.

  • When a style error occurs, the entire application crashes with a long stack exception error trace. Contrast this with CSS, which renders only the wrong element when there is a styling error.
  • The element is not recognizedclassnameSo you’ll be switching between the React element tree and the DOM tree development tool as you debug.
  • No code check errors.
  • Because no warnings or errors are given, invalid styles are easily ignored (e.gclear: both; float left; color: #f00;Debugging was difficult, and I spent nearly 15 minutes looking at the stack trace, even reading itstyled-componentsThe source code. It was only when I cut and pasted code in chat to find help that anyone noticed the missing:. You noticed that, didn’t you?)
  • A few ides support syntax highlighting, code hints, and other IDE details. If you are working with a financial or government agency, the Atom IDE may not be part of the discussion.

Myth # 8: Better performance, smaller package size

  • For now,styled-componentsCannot be extracted as static CSS files (e.gextract-text-webpack-plugin). This means that your browser cannot interpret styles untilstyled-componentsParse the style and add it to the DOM.
  • The lack of a separate file means you can’t cache CSS and JavaScript separately.
  • All style components are wrapped in additional higher-order components. This results in an unnecessary loss of performance. The same architectural flaw is why I stopped using react-CSS-modules (and created babel-plugin-react-CSs-modules).
  • Because of the higher-order components, if you render on the server side, this will cause it to produce larger markup documents.
  • Don’t ask me to animate with dynamic style values as opposed to Keyframes.

Hypothesis 9: It allows the development of responsive components

This topic focuses on the ability to design component styles based on the surrounding environment, such as parent container size, number of child elements, and so on.

First, styled- Components does nothing about it. It is outside the scope of the project. In this case, you are better off setting component style values directly to avoid additional overhead.

However, element queries are an interesting topic and a hot topic in CSS, mainly used for EQCSS projects and their counterparts. Element queries are syntactically similar to @media queries, except that they operate on specific elements.

@element {selector} and {condition} [ and {condition} ]* { {css} }
Copy the code
  • {selector}Is a CSS selector for one or more elements, for example:#id.class
  • {condition}Consists of measurements and values.
  • {css}You can include any valid CSS rule. (such as:#id div { color: red })

Element selector allows use of elements such as min-width, max-width, min-height, max-height, min-characters, max-characters, min-children, max-children, Styles of conditional design elements for min-lines, max-lines, min-scroll-x, max-scroll-x, and other attributes (elementQueries.com/).

One day, changes to EQCSS will appear in the CSS specification.

Wait a minute

Most of these things can be fixed for the long term by the community, changes in React, or styled- Components. But what’s the point? CSS is widely supported, has a large community around it and works just fine.

The point of this article is not to prevent readers from using CSS or using styled components in JavaScript. There is a good use case for styling using styled- Components: better cross-platform support. But don’t use it for the wrong reasons.

So what to use now?

It’s too early for Shadow DOM V1 (only 51% support). With naming rules (I recommend BEM) use CSS. If you’re worried about class name conflicts (or too lazy to use BEM), you can use CSS Modules. If you’re developing React Web, consider using babel-plugin-react-CSs-modules. Styled Components are a good choice if you are developing React Native.

What are the arguments for using CSS in JS?

Read this article by Max Stoiber at mxstbr.com/thoughts/cs… .