10/30/2019, 12:50:00 PM
There are more than enough options when deciding a toolset for building the common components in React. In this post, we are going to explore how to build common components with CSS and SASS and what kind of benefits and pitfalls there are.
From the all options, CSS files with SASS addition has the lowest learning curve because these tools are used very similarly to a normal web page development. CSS files are very simple to import to React component and SASS gives some nice optional additions like variables and calculations which ease up more complex work.
Setting up a CSS and SASS files to React project also very simple to do whether you are using Create React App or Webpack.
In case you are doing a separate package, you need to take care of both the package and the consumer sides. On a separate package, you can either distribute the CSS files as is and let the consumer do the transpiling or transpile the CSS files already on the package and distribute the result. I would suggest using the first choice since it gives more options to the consumer.
If you are using Create React App you just need to install node-sass.
npm install node-sass --save-dev
With webpack, the project needs a bit more configuration but setup is still very straight forward. Besides node-sass we need to install sass-loader, css-loader and style-loader.
npm install node-sass sass-loader css-loader style-loader --save-dev
And then add all these to webpack.config.js
Parcel handles both css and scss out of the box so you can start using them immediately without any configuration.
Once CSS file is imported, the content becomes available everywhere in the application (as long as it is imported). This means you don't necessary have to import the css file where you are using the classes. In a sense this gives a huge flexibility regarding how to handle the styles. In a most extreme way you could import the css in a root JS file but I wouldn't suggest to do that.
Since CSS has a global namespace, it's very likely that at some point in a project two classnames overlap or otherwise cause issues. To mitigate these this, it's advisable to use some naming convention to separate the component from each other ensure that all unique components have their own classnames. One of the most popular is Block, Element,Modifier (BEM).
The idea with naming convention is the use same way to determine the classnames so that they are easy to recognize and reuse. Instead of making the classes be applicable for one use case like:
We would split the classes to be more generic and only add the necessary additions to more specific classes.
This structure is very extendable and easy to use in different situations. We can use the css straight away:
or build a layer inside the component to handle classnames:
Note that in the latter example we are using classnames which helps out handle multiple class names tremendously. While both ways of using class names are correct, I would strongly recommend using the second one where class names are handled inside the common component and only properties are exposed outside.
Having properties handle the class name changes limits the amount of available different ways the component can be manipulated, which simplifies the testing and ensuring that the changes won't break the design.
Unfortunately, there is no way to extend the common component when only exposing the properties so if you need an extendable component, it could be done by creating a base component with className property and build the used component without className property.
For example if we extend the previous example the used component would look like:
This way we get both extendability and limited amount of options.
The scss file could look like:
And to be used other scss files like:
If the theme file starts to get bigger, there are also way to use SASS functions and mixins to help out keeping a better structure and easing the usages.
The benefit of using the global variables comes yet again from restrictions. When you limit yourself to use theme variables when defining colors or spacing, you also make sure that there is an easy overview what different option are used. This makes things yet again easier to test and ensure that everything works as they should.
As we have seen, CSS and SASS bring a powerful way to do common components/design without adding too much complexity. The component library would be easy to understand even by the developers who haven't done a lot with React and it most likely would be understandable for the people who mainly use only HTML + CSS.
The biggest advantage to use CSS and SASS is the convertibility. Since the styles are separated from the React component, the style can be reused between the frameworks. This gives a huge advantage if the same design is shared between an application that is not done only with React.
There are a couple of drawbacks too. Handling the class names manually creates a lot of possibilities to create an unmaintainable mess. The naming convention will help but this needs be managed constantly (or to have proper Eslint rules).
In my opinion, this toolset is still relevant and should be seen as an equal option when deciding what to use in a project.
Repository css-sass has an example how to use this in a project.
This is a second post from the series Speed up development by creating a common Component library. The later posts will cover up the other options to build the common component library and how to document the library.Comment or ask about the post in Dev.to
Join to my monthly newletter that covers articles about software engineering and news/events that happened lately with my thoughts about them.