Nuxt 3 Fundamentals

CSS Styling

Ben Hong

Ben Hong

Nuxt 3 Fundamentals

Check out a free preview of the full Nuxt 3 Fundamentals course

The "CSS Styling" Lesson is part of the full, Nuxt 3 Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Ben demonstrates how to style a single file component. CSS styles are treated as global styles, so to avoid naming conflicts, the scoped attribute can be added to the style block to limit the styles to that component. Binding to styles is also demonstrated in this lesson.


Transcript from the "CSS Styling" Lesson

>> For this session, we're gonna talk about something that well, we all need to do when it comes to our apps, and that's making it look better, right? Applying design, applying CSS, because, yes, does this work functionally? Yes, technically it does. But to be totally honest, it could use some help.

And so, we're not gonna do like a full blown CSS course, but I do wanna just talk a little bit about how basically some best practices for approaching styling within Vue, next and how you might do those things. So first thing first, let's talk about a popular way of managing this.

So let's say, for instance, we wanted our to do list to be in two different columns. That's what we wanted to do. Then what we can do is we can go ahead in here and we can take a look at our styles here and we could go, okay, well let's see the ul here is like this.

So what if we did something like, okay, so first we'll start by opening the style block. So if you haven't used single file components before, this is kind of what makes them a bit unique. Is that it contains the scripts, the JavaScript, the HTML, and the CSS all in one file so that it's encapsulated and then your concerns are basically all related together.

So that when you delete the file, it's impacting that file specifically. So in this case, what we can do is let's call this todo list, let's call it the class. So that's really what this is, it's the todo list. And so we do todo lists and then let's say it has display, let's say grid and then grid-template-columns.

We'll say we'll repeat it twice, and each column will be one fraction of the width. That's what that CSS means. So we go ahead now and check it out and refresh. Okay, perfect. Fetch, wallah. Okay, so we see that we have our two columns. Now, here's the thing that some people might not know, is that when you use the style block like this, what you're actually defining is you're defining global styles.

So if you look inside of our app you'll see here that we have here ul class todo list. And then, you'll notice that todo list it's just a generic style block basically found inside of the head. So in other words, when it comes to CSS and specificity this could theoretically impact other components on the page should they share the same name.

So how might we get around this? Well, of course, you can certainly try naming things uniquely yourself and hopefully no one collides with your CSS styles. But anyone who's done that at scale can tell you it's basically impossible to do because, eventually developers start naming things a bit shorter on the short side, and they wanna do it what makes most sense in a component, and then collisions happens because the cascade can be hard to predict, and things blow up.

So what can we do instead? Well, instead of using a global CSS, most of you might have heard about scoped CSS. So, what is scoped CSS? Well, by adding the scope to attribute to your CSS styles, we get something pretty interesting here. You'll notice that one, when I open this, it still looks like the two columns, but we'll notice something pretty different though.

And that is, that when you look at the styles over here, let me pump this up a little bit so you read that a little bit easier. You will notice that our todo list now is appended with an attribute selector. More meaningfully it is appended with this custom hash, data-v-938b838b0, basically it is randomly generated.

And that corresponds with this element over here that also has that attribute data-v-938b83b0. And so this is a pretty cool way of actually starting to scope things a little bit because what it does is essentially add a little bit of specificity to your code. And for the most part, this saves people most of the headache because it feels pretty native, but there's a third approach that I do wanna make people aware of.

And that is the fact that, in the event that you wanna actually name it something generic. Let's say we wanted to name something like lists, right? Lists is something that especially if you're importing a third party library, that could blow up all sorts of different ways. But for the sake of like, not having to rely on generating really really long names, which was very popular, well, still popular, right?

It's known as BEM. If you haven't heard of it, you can look that up. BEM CSS, where you name the components or it would be like, todo lists underscore like list underscore item, like it was long and it's kind of hard to read and cumbersome. And so we have built tools, can we make this easier for ourselves?

And the answer is yes you can. And the way you do that is one, you start by searching scope for the module attribute. But that's not just it. This is the part where it gets a little bit controversial. What we gonna do is we gonna bind the class that we wanna use and we're gonna use the dollar signs style and then we're gonna basically tack on the class name.

So as you can see style.list, this maps to here and the style object basically maps to a JavaScript object of whatever CSS you've written inside of your style block. Now you're like okay, that's weird syntax, what do I get for that? All right, that's a good question. So let's go ahead and fetch the data again, looks good.

What's the difference? The difference is you'll notice that Vue has gone ahead and generated a completely new class name for you. And it's got a custom hash and everything, which means yes, theoretically there is a chance, right, that you could generate the same hash. But I think we know statistically speaking, that's probably not going to happen.

And so more importantly, we're not gonna get into the configuration and stuff, but you can actually even like prepend the generated class name with the component that it's coming from because I'm a big fan of having CSS class names that you can actually debug. Because I know that some frameworks and some approaches will just do a random hash period, right, never conflicts basically.

But then the problem is when you look at it you're gonna be like there's a bug, I don't know where this is coming from. And I mean debugging is really where the value comes out of it. Like it's nice to think of optimizations and it can be only five letters.

That's a random hash. That's nice. But when things break, I need the tools to help me debug not the other way around should make it harder for me. So at the bare minimum, you can see here it's underscore list. So at the bare minimum if I were looking for my code base I can look for .list.

And that does narrow it down a bit. But again I would recommend like if you're gonna configure it a little bit more maybe prepend it with a component name automatically so you know which file to look at. Again, those are just suggestions and preferences. But, the main thing to know about styles is that this syntax is a little bit awkward for people, because especially when you start tagging on multiple ones then you have the array syntax as well so you'd be like style list.

And then it feels a little awkward to people like that's like JavaScript. It's not really like a native anymore. And so my recommendation for this is that use it in a way that like when you know you need to escape you know the styles need to live in isolation.

It is worth the trade off here's the headache you save by being able to write native CSS in here, which I really think is where it's most important that's where you get most of your benefits and then you can deal with a couple of kind of ugly V bind classes with dollar symbol styles.

>> What is your opinion about using Tailwind CSS with Vue?
>> Okay, so the question here is around Tailwind CSS, but I think more important let's talk more about utility CSS, because that's really the paradigm shift. So I won't comment on Tailwind specifically just more as a paradigm.

And so I guess let me just show the one that's another open source one that's actually really popular in the Vue community called, I think it's called no, wait. Andu utility CSS. Yeah, I think we know CSS as an example. But basically what it's known to do is, you'll see an example.

Yeah, okay, here are some examples here. For those who've never used libraries like this before what they essentially allow you to do is pen a bunch of mini classes to, like an element and those styles add up to something bigger. And so for a lot of people this provides a lot of standardization.

Again, any tools and libraries you choose will have trade offs because on the other hand it does mean that your HTML gets bloated with a ton of different styles, like class names. And so one way you can get around that if you are using that you wanna still use something like Tailwind or like UnoCSS, is that you can basically use I think post CSS to actually pre process all those things under a class name so that you're leveraging the design system to keep that consistency while also actually having cleaner CSS class names.

And so I will say from a personal opinion perspective, I actually really like writing CSS. And so usually libraries like Tailwind and that kind of stuff they're good for teams that you can't really ensure who's writing the CSS and so you want just consistency to be applied across the board.

And so design systems like that can be incredibly powerful in that regard. But just remember the trade offs of having to deal with all that configuration versus just knowing CSS and just be able to write it yourself. Again, depending on your team and your skill that's how I would choose to basically optimize for which kind of CSS way you apply.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now