- Published on
Learning Next.js - CSS Styling Chapter 2
- Authors

- Name
- Brett Stockmeier
Introduction
I'm going to continue to refine and tinker with my process as I go through the next.js course. I fully intend to create a post for every chapter (maybe more than one post!) as I believe that blogging about something helps me organize my thoughts and work through my uncertainty with new topics.
And hopefully, it has more practical benefits1 as well.
Goals of this chapter
- How to add a global CSS file to your application
- Two different ways of styling: Tailwind2 and CSS modules
- How to conditionally add class names with the clsx utility package
Global Styles
I haven't worked much3 with CSS in over a year. I'm familair with what CSS are, and I know what they look like, but my experience using them at this point is basically back to zero. To use it properly, I'd have to relearn the contents of the tech.
Like I know I can set the width of an element, but I don't necesarrly have confidence I know how (or the correct keyword) to do it4.
So I'm taking the tutorial's word that it's best to put all style sheet classes in a single global style sheet currently. And likewise, it's also good practice to import that global style sheet into the top-level component of the project. (I'm told the reasoning behind this will be covered further in a future chapter).
Also during this section, I noticed an odd symbol in the included import statement for the style sheet:
import '@/app/ui/global.css';
After consulting with my brother, this appears to be like a macro (or I guess in Typescript terms, a "path") that has granted that symbol special meaning. Here is the definition in the project's tsconfig.json file:
"compilerOptions": {
...
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
}
While I was confused at first (the path seemed to substitute 2 characters for 2 other characters), this actually makes practical sense if you assume that the path always refers back to the context of the tsconfig.json file rather than the context of the file the path is being referenced from. In this sense, @ is a shortcut to always reference back to the root of the project folder structure! Very handy!
Tailwind
The chapter goes over two methods for styling your code. One of them is Tailwind.
As I have come to understand it, Tailwind takes the .css class that would ordinarily be defined in global.css and applied to multiple components, and instead requires that developers define these classes in the code itself via the component's className property.
A comparison below:
<h1 className="text-blue-500">I'm blue!</h1>
-vs-
<h1 className="my-blue-text-class">I'm blue!</h1>
I have mixed thoughts.
The tutorial makes the argument that with each class being singularly applied to each element, that means when you add or delete or modify your code and the elements in your project, you remvoe the headache of maintaining separate stylesheets, style collisions, and the size of your CSS bundle growing as your application grows in size. My experience being so small, perhaps I am just unable to appreciate how much removing these concerns really means to an experienced developer.
Instead, I see the work that goes into having to meticulously and individually style every single element used in the application. I see the work that happens when you want to change the styling across the project, ensuring you hunt down every single applicable element to make sure the sweeping change is applied to everything.
But on the plus side, to some extent you can look at a single code file and maybe with experience get the complete picture of what the output of that code will look like. You can open up the project locally, you can change one class name and see exactly the change you expect with confidence that there will be no unintended side-effects.
I had more thoughts to share on this topic, but they're escaping me right now. Suffice to say, I'm not entirely sold on the technology, but there's a good chance I could be convinced. I'm believe this way of styling could be great, but I also think it's better suited to more lightweight and agile projects, at least at first, at least for me as I become accustomed to it.
Although to be clear, the tutorial makes it clear that all tailwind styling has already been completed in the code for this tutorial project.
CSS Modules
While the tutorial itself admittedly seems to favor Tailwind, CSS Modules exist as well, being posited as "a agreat alternative" if you prefer writing traditional CS rules or want to keep your styles separate fro your JSX.
Personally, I appreciate clean code and cramming all the style rules into the class name of a component doesn't seem very elegant to me. But I can also appreciate the simplicity of it.
CSS modules instead create new .css files which contain pre-defined style classes that can be reused. These CSS files need to be imported before they can be used, and...
I'm sorry, I don't remember a LOT about CSS, but this just sounds like the way I learned how to use CSS from the very beginning (I don't remember if they were always called modules or not). I'm unclear if this is being posited like it's some new innovation in programming or what.
My initial thoughts are these: I am concerned I do not know the optimum way to write and organize CSS files. At least in that respect, Tailwind has CSS Modules beaten, because everything is defined in the ClassName without having to take that extra step and reference a pre-defined class by an alias.
So yeah, all things being equal, and this being a blog built on Tailwind, I'll be using that method going forward until I have enough experience to know my own preferences.
Using the clsx library to toggle class names
Here's a neat trick! Conditional styling! Like Tailwind, you can put it right in the className!
Example from the tutorial:
import clsx from 'clsx';
export default function InvoiceStatus({ status }: { status: string }) {
return (
<span
className={clsx(
'inline-flex items-center rounded-full px-2 py-1 text-sm',
{
'bg-gray-100 text-gray-500': status === 'pending',
'bg-green-500 text-white': status === 'paid',
},
)}
>
)}
I really do think it's a neat trick, and would be incredibly useful, perhaps specifically for me and Thirsty Libraries. But it's also code that gives me a headache looking at it. Perhaps I just need practice and experience (and exposure). It's just weird seeing an html element's opening tag be as long as some functions. In general, I'd rather write code that's a bit more... human readable. But maybe that's my hangup to get over.
Other Styling Solutions
This section exists. It doesn't go into detail about other styling solutions, but merely alerts you that they are options. I'm not inclined to study up on all of them when I'd rather focus on becoming confident with just one of them for the time being.
The options presented though:
- Sass
- CSS-in-JS libraries like "styled-jsx", "styled-components", and "emotion"
This is definitely a deep topic, but it just doesn't make sense for me to do a deep dive when I don't even have a pool at home yet. Or something. It's not a great analogy.
Footnotes
Hey! That's what this blog is built on! ↩
Or at all; even when I was working at Allstate, my front end work comprised a slim majority of my development time, and that had more to do with arranging components on a UI than styling that UI to begin with ↩
See also: regex, terminal command options ↩
Can you do footnotes in footnotes? ↩
