Today we will be covering a few popular methods to style our React JS applications such as Styled Components and Sass to explain the benefits of both.
Why Do People Argue Over CSS-in-JS?
I don't know that there is necessarily a "correct" answer. I'm sure there are use cases where each is more appropriate, although I find myself reaching for Sass more often. Let's get into each a bit more so you can decide which you prefer!
The concept of CSS-in-JS started making waves when it was discussed in 2014. Since then, many different libraries have been created to try and make this concept a reality. A few of these libraries are: Styled Components, Radium, Aphrodite, or Emotion.
I will be using Styled Components in this post, although I'd suggest checking out each of these since each has it's own syntax and works a bit differently. The documentation for each of these is pretty good to learn the basics and see which feels most comfortable.
Installing Styled Components
Assuming we already have a React js project set up, we can add Styled Components to the project by running
npm install styled-components or
yarn add styled-components in the terminal. This will add the dependencies to the project and get us ready to style our application.
Creating a Card with Styled Components
The next step will be to create a component to show our card. We can use the code below to do this:
What the code above is doing is creating a
const variable called Card which says that
styled should create a div with the following properties. This can be done for any DOM element, so if you wanted to style an h1 tag you would use
Adding Media Queries and Nesting
Inside of the Card variable, we can also drop in media queries to make things a bit more responsive. If we add a media query like the code below, you can see that when we reach a max-width of 1000px the card background turns red. This isn't a style we actually want to add, it's just for demonstration purposes.
We can also nest our styles inside of the styled component, which simplifies the code we're writing. If you have used sass or less, you are already familiar with this concept. The example below shows how we can do this to handle styles for the image in our card component:
Using CSS-in-JS allows us to keep styles local instead of everything being global or having to add a ton of classes to everything to make it work. This means things can be more concise and we don't have to worry about one style overriding another. In addition, it means we always know where to look if we need to change the style. We don't have to go rooting around in a bunch of CSS files looking for a class.
To do this, we should import the ThemeProvider component from styled-components and provide a theme variable. The theme variable will contain any global variables we wish to use with our styles. For instance, if you have a primary color you are using for the navbar, buttons, and links, it doesn't make sense to hardcode that in every time you want to use it.
Using a Global Theme
What if you have to update it someday? That sounds like a lot of search and replace waiting to happen. Instead we can declare the global theme variable and access it from any of our styled components. Doing so is pretty simple and is illustrated below.
These theme variables can be used in any of our components since the ThemeProvider is wrapped around our entire application. We can then add a styled component to wrap our site in which will take care of all of the global styles such as typography, input styles, and other things that should be standard across all pages.
To demonstrate this, let's add some global styles and some content for our social card. The code below adds the necessary content to the social card and also adds a few global styles to be applied to text.
This is obviously a pretty basic example but it's a simple way to get our feet wet with Styled Components. There are also some more in-depth things we can do with it, which we can learn about in the documentation.
Styled Components are very nice because it allows us to throw our styles in the same file as our component rather than opening several different files to find the correct styles. Here is what our finished social card with Styled Components looks like:
Using Sass in a React Application
Sass was created several years ago and was originally implemented in applications built using Ruby. In recent years, it has been adapted to work with Node.js which is how we will be using it today. You may notice that we are creating "scss" files but calling it sass. This is because Sass was originally created with a certain syntax which is actually known as "Sass". Later an alternative syntax was created to closer resemble CSS, and this is called "Scss". Because Scss has the same functionality of Sass, it still falls into the category of Sass.
It is generally pretty simple to get up and running with Sass in a React js application, although it does make a difference how you go about bundling or compiling your application. In the code for this tutorial, I will be using Parcel js which is pretty easy to get up and running and handles the Sass for us. There are other libraries which are sometimes necessary such as node-sass, gatsby-plugin-sass, or next-sass.
Setting Up Our Sass Files
There are a few different ways to use Sass within a React js application. The first would be to create a component in a folder and include the styles for the component as a
.scss file within that folder and import them directly into the component. I have done it this way and have found it to be easy but I didn't care for the organization so much.
An alternative is to create a Sass folder within our project and this is where our styles will live. This is the organizational method we will be using today. That being said, we will create a folder in the project called "Sass" and add a file called "app.scss". While we could put all of our styles into this app.scss file, that would get messy and wouldn't provide much benefit over normal CSS.
Instead, we will create separate files and just import them into the app.scss file. We can then import the app.scss file into our app.js file and Parcel will do the rest.
Structure of Sass Folder
There are lots of different opinions on how to organize the folder with our styles. We could spend a TON of time going down a rabbit hole of organizational techniques, but I find that the way I like to do it is to organize my Sass folder the same as my project. Typically this would translate out to having the following layout:
- /Components - A directory which has a .scss file for each React component
- /Pages - A directory which has a .scss file for each page that requires custom styles
- /Templates (optional) - A directory for templates if using them (for tools such as gatsby)
_elements.scss- Any generic styles for the site. Shouldn't have any classes or ids for selectors.
_keyframes.scss(optional) - Any keyframes or animations I will be using for the site.
_mixins.scss- Any mixins (style snippets) that will be used over and over
_variables.scss- Any variables that will be used throughout styles
app.scss- The file that imports all other scss files
The first thing you may notice about the file names is that several of them start with an underscore. This is because outside of node, Sass is actually compiled to a CSS file. Any SCSS file without an underscore at the beginning is compiled as a different stylesheet. Since we are pulling all of our stylesheets into the app.scss file rather than separating them out, they should all start with an underscore.
Since our application is only one social media card, we won't need all of these. For the sake of simplicity while explaining this, we will be using the app.scss, the _variables.scss, and the _elements.scss files as well as the components directory.
That being said, let's get started!
Setting up variables in Sass
Since we have some variables in our Styled Components styles, we can go ahead and set them up here too. To do this, create a file called
_variables.scss in the Sass file for our styles. Inside of the
_variables.scss file, add the following code.
Once we have some variables added, we should import this into the
app.scss file. Since we want to use these variables anywhere in our styles, this import should be toward the top of the import list. The following line of code will add the variables to our styles. We can also see that we don't have to include the underscore or file extension in the import statement because Sass is smart enough to know that's what we mean.
Creating global styles for elements
We created some global styles for our styled components application which set our font to a sans-serif font and set the color of our text to
#333. Let's go ahead and create those styles in Sass too. To start, we will create a
_elements.scss file in our Sass folder. Below are the styles I'm using for this file and you will notice that I'm using the variables that we created just like we did with the styled components.
Now we can import the
_elements.scss file into our app.scss file. See if you can do it without looking. Our app.scss file should now look like this:
Adding Classes to Elements in Component
So we can target the elements in our React js component, we should add some classes and/or ids. CSS frameworks like Boostrap and Foundation require a lot of classes which can get pretty messy. My favorite code is the code that doesn't have 30+ classes on an element for styles, so with that in mind let's go ahead and add some classes to our component with the code below:
Awesome! Let's start styling our component! Inside the Sass folder, create a new folder called "components". This folder will hold the styles for all of our React js components. Typically, I would put each component into it's own file, this is a pretty simple application so we will keep it in the app.js file.
We can set up styles the same way as our styled components since Sass can also handle nesting and media queries as well. Since our import statement will occur after the variables import in app.scss, we can use anything that was imported before this file. This is useful with mixins, which are code snippets that you can reuse. You can even create a sort of function where you pass in an argument and use that throughout the mixin code.
The code below will style the social card to look the same as our styled components social card:
Now we can go ahead and write the import statement in the app.scss file so we are pulling in the styles for the card.
And just like that, here is the final Social Card component with our sass styles. It looks the same as the component did in Styled Components.
Final thoughts on Sass vs Styled Components
As you can see, both Sass and Styled Components are valuable ways to supercharge styles in React js applications. Ultimately, I think that you should use the one that you enjoy using the most. I find myself reaching for Sass more often, but I also enjoy using CSS-in-JS in some of my personal projects. If you'd like the code referenced in this post to look at or play around with, it can be found here.