As I slowly work towards using react into some of my projects, my first real question was how to style my components. There have been quite a few evolutions of CSS in the past few years. We've gone from straight CSS to SASS or Less to give better maintainability, Bootstrap to deal with the volitile nature and make our pages a little more standarized. The list goes on but all of these solutions are to make the fundamental problems of CSS less bothersome.
Component centric CSS?
Component centric CSS is the concept of attaching your css to a react component. One of the main benefits that comes from a component driven front-end is the encapsulation that it engenders. No longer does the developer worry about merging multiple small pieces randomly throughout a codebase into a single structure. Instead, each component has its own style attributes. This component has its own error handling, it has its own event listening and it doesn't bother too much with what is going on in other components except when parameters are passed. Each component is the master of its own domain. The main qualm with traditional css is that it is essentially all defined globals. While there have been some attempts to solve this, notably with BEM it feels like a hack to codify your class names to handle a lack of namespacing in CSS.
Applying a component mentality to CSS
I know what you are thinking, "It is called Cascading Style Sheets for a reason". There are a few different approaches available, so bear with me. Here are a few solutions out there.
- Hard coding: Apply styles directly to elements via the style attribute
- Styled Components which allows for use of CSS but applied directly to components
The Old standard
I am currently using react-bootstrap in my project, and that works exactly how I would expect. There is a defined CSS file included in the site. The react portion handles only the setting of classes and other things which affect the style defined in the included CSS file. The points in using this are:
- There is potential for clobbering a namespace but the classes are well-defined so it isn't probable
- Having to debug styles based off of specificity(Why isn't my style showing up?)
- Having to manage the the structure of the files
- It is an old evil, but a well-known one. There aren't a lot of surprises in store.
Full disclosure, I am using this as a base and then using CSS-IN-JS to set the rest of my styles.
A New Approach: CSS-IN-JS
Some people have been jumping on the bandwagon for writing inline styles. There is another option though which builds CSS classes dynamically, directly into your components. You may be saying, "Inline Styles?! The warning flags are in the air!", and I will admit that I was skeptical at first. Styles are defined directly on the elements, though they are not truly "inline". This goes counter to everything most of us have learned when getting started with web development. But since, the un-examined belief isn't worth having, lets take a moment to stop and think about why.
Putting CSS Styles directly on elements hurts re-usability.
I want to make styles for a button and be able to use those styles for every instance of said button. The approach to CSS-IN-JS, is to define a dynamic class at instantiation time of a component, from then on, that class is applied to the component. What is nice about this is that you can have multiple styles associated to a component, and then attach them at runtime. You aren't actually re-adding styles to each element.
A side-effect of this, is that you view your styles more as something attached to your components. So structurally it makes sense to keep them with your component. All of my files are located with the component that they style.
/components /MyBadassComponent MyBadassComponent.jsx styles.jsx
Putting CSS styles directly on elements hurts caching
Putting CSS styles directly on elements will essentially override everything else
While this is true for styles written directly to an element via the style attribute, but CSS-IN-JS works by generating classes. This means that if you want to use something like bootstrap, you can happily use their solutions with yours. You can also use other outside libraries and they won't be overridden directly by any styles you choose to use.
Since react is still all new and magical to me, I may do a follow-up article, "Why to never use CSS-IN-JS", it is possible that I will hate it after I've spent some time implementing it. But for now it's my chosen way forward. Here are a few resources for learning more about CSS-IN-JS: