CSS-in-JS - myths and reality (for example, styled-components)

    CSS-in-JS , being not entirely new technology and implemented in many libraries , still raises doubts and disputes over the expediency of its use. He put his points on “i” in the debate about CSS-in-JS in general, and about styled-components in particular, a year ago, (27 Apr 2017), and Gajus Kuizinas , by react-css-modules and babel-plugin -react-css-modules , in still, in my opinion, the current publication "Stop using CSS-in-JavaScript in web development . "
    The following is a slightly abbreviated translation of it with some additions and conclusions:


    CSS doesn't go anywhere . In many projects, the choice in favor of JavaScript styling is done in error. We will give a list of common misconceptions (myths) and their corresponding solutions through CSS.


    Css and JavaScript history


    CSS was created to describe the presentation of a document written in markup language. JavaScript was created as a “language-glue” for assembling components, such as images and plugins. Years later, JS grew and changed, adapting to all new areas of application. And, as a result, we today live in the era of one-page applications (SPA), applications assembled from components.


    What about CSS?


    Let's quote from the styled-components documentation :

    The problem with regular CSS is that it was created in an era when the web was made up of documents. The Web was created to share primarily scientific documents in 1993, and CSS was introduced as a solution for styling these documents. However, today we are developing advanced, interactive, user-oriented applications, and CSS is simply not designed for this.

    This is not true.


    CSS already takes into account all the requirements of modern user interfaces. The number of new functions implemented in the last decade is such that it is impossible to even list them all here (pseudo-classes, pseudo-elements, CSS variables, media queries, keyframes, combinators, columns, flex, grid, computed values, ...).
    From the point of view of the user interface, “component” is an isolated fragment of a document (<button /> is “component”). CSS is designed to style documents, and the document covers all components. What is the problem?
    As the saying goes: "Use the right tool for the job."


    Styled-components


    styled-components allows you to write CSS in JavaScript using the so-called. tagged pattern strings . The library removes the mapping between components and styles — the component becomes a low-level styling design, for example:


    // Createa <Title> reactcomponentthatrendersan <h1> whichis
    // centered, palevioletredandsizedat 1.5emconstTitle = styled.h1`
      font-size: 1.5em;
      text-align: center;
      color: palevioletred;
    `;

    styled-components is now popular and is known as a new way of styling components in React, although sometimes it is even presented as “the pinnacle of the development of CSS”:
    CSS Evolution: From CSS, SASS, BEM, CSS Modules to Styled Components .


    But let's clarify the following: styled-components is just an add-on for CSS. This library parses the CSS styles you define in JavaScript and creates the corresponding JSX elements.

    The popularity of styled-components is fraught with many delusions. An overview of the programmers' responses (found on IRC, Reddit and Discord) to the question about the reasons that prompted them to use this library, allowed us to make a list of the most mentioned. Let's call them myths.


    Myth # 1: styled-components solves the problems of the global namespace and style conflict


    This is a myth, because it sounds so, the allegedly mentioned problem has not been solved yet. However, CSS Modules , Shadow DOM, and countless naming conventions (such as BEM ) suggested solutions to the problem a long time ago.
    styled-components (in the same way as CSS modules) removes the problem of responsibility for naming. It is human nature to err, computers err not so often.
    By itself, this is still not a good enough reason to use styled-components.


    Myth 2: Using styled-components allows you to get a more compact code.


    In confirmation, an example is often given:


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

    First of all - it does not matter. The difference is insignificant.
    Secondly, it is not true. The total number of characters depends on the name of the style.


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

    The same applies to the creation of styles that we will see later in this article
    (Myth 5: styled-components facilitates the conditional styling of components). styled-components benefits in short only in cases of the most basic components.


    Myth 3. The use of styled components makes you think more about semantics.


    The initial message itself is wrong. Styling and semantics are different problems and require different solutions. Read, for example, this is Adam Morse (mrmrs) .


    However, consider:


    <PersonList>
      <PersonListItem><PersonFirstName>Foo</PersonFirstName><PersonLastName>Bar</PersonLastName></PersonListItem>
    </PersonList>

    Semantics deals with the use of correct tags for markup. Do you know which HTML tags will be used to render such a component? No, you do not know.
    Compare:


    <ol>
      <li><spanclassName={styles.firstName}>Foo</span><spanclassName={styles.lastName}>Bar</span></li>
    </ol>

    Myth 4: Easier to expand styles


    Compare:


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

    Wonderful! But you can do the same in CSS (or use CSS module composition, as well as SASS inheritance mixin @extend).


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

    And the simpler the first option?


    Myth 5: Conditional component styling is facilitated.


    The idea is that you can stylize elements using props, for example:


    <Button primary />
    <Button secondary />
    <Button primary active={true} />

    This makes sense in React. In the end, the behavior of the component is controlled through props. Does it make sense to directly bind prop values ​​to styles? May be. But let's consider the implementation of such a component:


    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};
    `;

    Creating conditional styles with JavaScript gives you a ton of possibilities. However, it also means that styles will be much harder to interpret. Compare with 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;
    }

    In this case, CSS is shorter (229 characters versus 222) and easier to understand (subjectively). Moreover, in CSS you could use a preprocessor to get an even shorter and more grouped result:


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

    Myth 6: Code organization is improving.


    Some people say that they like styled-components, because it is possible to place styles and scripts in one file. It can be understood that having multiple files for one component may seem tedious, but cramming styles and markup into a single file is awful. This not only makes the version control system more difficult to track changes, but also leads to an endless scrolling on any element more complicated than a simple button.
    If you absolutely need to place CSS and JavaScript in the same file, try the css-literal-loader . The latter will allow you to build styles during the “build” by extract-text-webpack-plugin and use the standard loader configuration for CSS processing.


    Myth 7: “Developer Experience (DX)” becomes beautiful. The tool is amazing!


    Obviously, you didn't use styled-components.


    • If something went wrong with the styles, the entire application “crashes” with a long stack error tracing. The opposite of this is CSS, where an error in the styles will simply result in the element being incorrectly displayed.
    • Elements have no distinguished className, so when debugging you will have to switch endlessly between React element tree and DevTools DOM tree.
    • And although plugins for linting, code highlighting, code completion, and other similar “charms” already exist for styled-components, they may still not be available for your IDE. If you work with finances at a government agency, there are chances that the Atom IDE will not be available.

    Myth 8: Everything is getting “faster”, everything is becoming “easier”


    • As it turned out, styled-components styles cannot be extracted into a static
      CSS file (for example, using extract-text-webpack-plugin ). This means that the browser will not be able to begin interpreting the styles until the styled-components have “parsed” them and added them to the DOM.
    • Combining styles and scripts in one file means that they cannot be separately cached.
    • The nature of styled-components is such that they are all wrapped in an extra HOS . And this is an unnecessary decrease in performance. The same flaw led to the termination of support for react-css-modules and the emergence of babel-plugin-react-css-modules .
    • Due to the same HOC , server-side rendering results in significantly larger document markup.
    • Don't even try to animate components using dynamic styles, not keyframes.

    Myth 9: It becomes possible to develop responsive components.


    We are talking about the ability to stylize a component based on the environment, for example, the size of the parent container, the number of heirs, etc.
    First of all, the styled-components have nothing to do with this.
    This is outside the scope of the project. In this case, it is better to directly set the component style values ​​in order to avoid additional processor loads.


    Wait a minute, however!


    Most, if not all of these problems can be solved in perspective, either by the community, changes in React or in the styled-components itself. But why? CSS is already widely supported, there is a solid community and ... it just works.
    But do not always avoid using CSS-in-JavaScript or styled-components.
    There is something that makes styled-components a good library - this is the best cross-platform support.
    Just do not use styled-components based on erroneous views.


    A couple of opinions from interested parties


    Talia Marcassa : What did we find disappointing in styled-components?


    Applying styled-components in our project, we found that there are some style rules that are difficult to implement in styled-components; for example, the rules that control the placement of elements on the page (margins or display property). It was hard to standardize, so we still had to pretty much rely on simple CSS to place components in the stream of elements.
    ... although there were difficulties in applying styled-components, the library helped us reduce the code base.


    Prometheus : In the end what?


    (commentary on “CSS Evolution: from CSS, SASS, BEM and CSS – modules to styled-components” )


    ... There is no evolution of CSS here, tools are evolving.
    In my opinion, there is no problem when the typesetter is engaged in the layout, and the programmer is programming.
    But when programmers do layout, this is when the whole zoo begins, which instead of SIMPLICITY with further support, gives you an extra headache.
    ...
    Write in pure CSS, and give the tools the role of the namespace and the collector - then everyone will be happy ...


    And in conclusion, the word author:


    Gajus Kuizinas: - So, after all, use?



    Also popular now: