SECRET OF CSS

How to Control Class Names in Styled Components | by Jennifer Fu | Jul, 2022


Babel configuration for styled-components

0*jN3EAzFekgkyyyv9
Photo by Pakata Goh on Unsplash

styled-components is a popular library to style React applications. We have introduced what it is and how to use it. We have also explored 7 ways to inherit styles and 12 coding examples of ampersand usages.

In this article, we are going to talk about how to control class names in styled-components.

We reused the Create React App working environment in the last article. The following package has been installed in the environment:

Here is src/App.js:

  • At line 1, styled is imported from styled-components. styled is the default export, used to create the styled.tagname helper method to transform the styling from JavaScript to the actual CSS rules.
  • At lines 3–13, the styled component, Container, extends the styles of div. It contains CSS properties of the div element. The ::first-letter pseudoelement (lines 8–13) applies styles to the first letter of the first line of a block-level element.
  • At lines 15–20, the styled component, Button, extends the styles of button. It contains CSS properties of the button element.

Execute npm start. We see a paragraph on the blue background. The first letter is red and bold, and there are two buttons at the end.

A paragraph is displayed on the blue background. The first letter is red and bold, and there are two buttons in the end.
Image by author

Here is the inspect window:

Container’s static class is sc-bczRLJ, and Button’s static class is sc-gsnTZi. Container’s dynamic class is OeNbu. Button’s dynamic classes are fiiIWC for My Button 1, and ccAjHy for My Button 2.
Image by author

Internally, styled-components generates two classes for each component— one is static and one is dynamic. The class name is generated by MurmurHash algorithm. It generates a unique identifier based on the component id and the evaluated style strings, and then, the hash number is converted to the alphabetic class name.

The static class name is sc-<hashedStringName>. It is used to identify the styled component, and there are no styles attached to it. The name will be the same for all instances. In the above example, Container’s static class is sc-bczRLJ, and Button’s static class is sc-gsnTZi.

The dynamic class name may be different for each instance, based on what the interpolations result in. In the above example, Container’s dynamic class is OeNbu. Button’s dynamic classes are fiiIWC for My Button 1, and ccAjHy for My Button 2.

Default class names are hard to recognize. Can we make them easier to identify while debugging?

Yes, we can.

It requires babel-plugin-styled-components and the custom babel configuration.

After styled-components is installed, babel-plugin-styled-components and and babel-plugin-macros come with it in package-lock.json.

There are a few options to set the custom babel configuration:

Here, we eject the Create React App by executing npm run eject. The ejected package.json has the following babel configuration:

A meaningful class name can be composed of namespace, displayName, and fileName, in addition to the default name. Maximally, we can configure a class name to be fileName__displayName-namespace-defaultName.

namespace

A namespace will ensure that the generated class names be unique. This is a handy way to avoid name collisions among applications.

Let’s try this babel configuration in package.json:

  • At line 9, namespace is configured to be my-styled-components-project.
  • At line 10, displayName is turned off.
  • At line 11, fileName is turned off.

Here is the inspect window:

Container’s static class is sc-hulcih-0, and Button’s static class is sc-hulcih-1. All names are prefixed with the namespace, my-styled-components-project.
Image by author

We can see Container’s static class becomes sc-hulcih-0, and Button’s static class becomes sc-hulcih-1. All names are prefixed with the namespace, my-styled-components-project.

displayName

displayName is the component name. This makes it easier to find styled components in the application.

Let’s try this babel configuration in package.json:

  • At line 10, displayName is turned on.

Here is the inspect window:

The styled components names, Container and Button, are placed in front of the namespace, my-styled-components-project.
Image by author

The styled components names, Container and Button, are placed in front of the namespace, my-styled-components-project.

fileName

fileName is the filename where the component resides. With the prefixed filename, the component name becomes as unique as possible.

Let’s try this babel configuration in package.json:

  • At line 11, fileName is turned on.

Here is the inspect window:

The filename, App, is placed in front of the displayName.
Image by author

The filename, App, is placed in front of the displayName.

What if the is the same as the displayName?

Let’s build an example for the case.

Here is src/components/Button.js where the styled component, Button, is placed:

Here is src/components/Components.js, where the styled component, Container, is placed:

Accordingly, src/App.js is modified as follows:

Here is the inspect window:

For Container, both fileName and displayName are displayed. For Button, only one of the names shows.
Image by author

For Container, since fileName and displayName are different, both of them are displayed.

For Button, since fileName and displayName are the same, only one of the names shows.

meaninglessFileNames

What if the styled component, Container, is placed in src/components/index.js, instead of src/components/Components.js?

Let’s take a look at the inspect window:

The directory name, components, is displayed as fileName, instead of index.
Image by author

The directory name, components, is displayed as fileName, instead of index.

It is because the default setting for meaninglessFileNames is equivalent to code below at line 11. It considers index as a meaningless filename. Therefore, the directory name is displayed instead.

Remove index as a meaningless filename in the babel configuration in package.json.

Here is the inspect window:

The filename, index, is displayed as fileName.
Image by author

Now the filename, index, is displayed as fileName, regardless of how meaningless it is.

Server-side rendering

We are trying to configure the styled component class names. Why should we talk about server-side rendering?

By default, ssr is set to true. It guarantees to generate a unique identifier for every styled component, which avoids checksum mismatches due to different class generations on the client and on the server.

Turning it off will result in class name changes. Let’s try it in src/package.json:

Here is the inspect window:

namespace is missing, and defaultName does not have a sc prefix.
Image by author

Consequently, namespace is missing, and defaultName does not have a sc prefix. Potentially, SSR shows an HTML attribute mismatch warning during rehydration. Therefore, it is recommended to leave ssr true as default.

styled-components is a popular library to style React applications. It is widely adopted by React projects. We have shown how to control class names in styled-components. Hopefully, the recognizable class names make your debugging easier.

Thanks for reading.



News Credit

%d bloggers like this: