Svelte Fundamentals

Classes & Styles

Svelte Fundamentals

Check out a free preview of the full Svelte Fundamentals course

The "Classes & Styles" Lesson is part of the full, Svelte Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Rich walks through specifying classes, shorthand classes, inline styles, and component styles. Student questions regarding adding multiple classes and binding to multiple elements are also covered in this segment.


Transcript from the "Classes & Styles" Lesson

>> Okay, so like any other attribute, you can specify classes with a JavaScript, you can specify classes on an element using attributes. We could add a flipped class to the card, like this, flipped is. So the class is flipped if the value of flipped is true, otherwise it's false, we've got a syntax error somewhere, okay, there we go.

So, now if I click on this this button inside this card, its gonna activate this event handler and this class is going to change. All the CSS is down here, if you wanna see how this is working, we're just using CSS transforms. We can make this a little bit nicer.

Instead of having this ternary operator inside our attribute, we can use this shorthand, class:flipped=flipped. Right, this means add the flipped class when flipped is a truthy value and remove the flipped class when flipped is a falsy value. And it's particularly convenient when you have multiple styles that are dynamic, or multiple classes that are dynamic rather.

And as in other contexts, we have a shorthand version of this, class:flipped=flipped is duplicative. We don't need to repeat the word flipped, just get rid of that and everything continues to work. And just like with classes, you can put all of your styles in an inline style attribute.

So maybe we don't wanna use a class for this, maybe we wanna use a style and we could write out style=transform and if it's flipped, we're gonna have. Rotate y zero, Otherwise it's gonna be the empty string and maybe we wanna have some other styles in here, we'll specify some colors.

Specify three colors, make it look a little bit different. Right, and you can see from the difficulty that I'm having keeping all this on the screen that, this is starting to get a little bit out of hand and it would be nicer if we had a better way of doing this.

Starts to look a little bit crazy. We can tidy things up using the style directive which lets us control one style at a time. So instead of having all of this text here like that, we can have a style transform which is equal to the value of that ternary.

We can have a style bg-1, which is equal to pale goldenrod. I'm having some difficulty with the editor here, bear with me. So you can see how when you have multiple styles, using the style directive is a little bit nicer than putting everything in one single style string.

Now often you will need to influence the styles inside a child component. Perhaps we wanna make these boxes here red, green and blue. One way that you can do this is with the global CSS modifier, which is sort of an escape hatch when you're writing styles that are scoped to the component.

Inside our App.svelte, we could have a style tag, and we could target each of these boxes individually. So we could use global, and then inside that, we're gonna target the nth child one, give that a background color of red and we can do the same thing for all the others.

For there's lots of reasons why we shouldn't do that. For one thing, as you can see, it is a lot of code to write, it's not fun code to write, for another is kind of brittle, right? At the moment this box component just has a div element with a class of box, but that's really just private implementation detail.

It's not something that you can rely on as a user of that component. If we were to change the structure of this and implement it in a different way, then our selectors in app.svelte could break. So in general, I don't recommend controlling styles that way. Finally, it's a little bit rude to control the contents of a component.

Components should be able to decide for themselves, which files can be controlled from outside, in the same way that they decide which variables are exposed as props. And so global is something that you should reach for as a last resort. Instead we can use CSS custom properties for this.

This is a way that a component can say, this is a value that is allowed to be set from outside. So inside Box.svelte, this background down here we're gonna change that to be a CSS custom property. We'll call it color, could be anything and we'll give a default value of ddd, which is what we had before.

And now any parent element that uses this component can set a value of color. So we could, for example, do it here, style equals boxes purple, sorry, color purple and that will set a default value. But another thing that we can do is set the color property directly on the component.

Right, so we can now get rid of our inline styles. All right, so you can think of this as passing styles to the component, the same way that you would pass props to a component. Implementation wise, the way that this works is we wrapped each of those components in a div with display contents, which means that it doesn't affect the structure of the DOM.

But it allows us to place those values in the DOM in such a way that those CSS custom properties will be inherited by child content. These values can be dynamic, here, we're using static strings, but it could be some local variable as well. And it's really a very flexible way to control the styles inside components.

Any questions on classes and styles? Mark.
>> When you add a class, can you add multiple classes?
>> You absolutely can, you can add as many classes as you like to a component. So here we could do class foo=1, class bar= 2 and similarly with these values, say we had, I don't know, border 3px, solid var --border, right?

We could add border=yellow, and things like that. So, yeah, you can add as many of these as you want.
>> Well, with the class directive though, could you add more than one class?
>> Yeah.
>> Or do you need several classes?
>> So, you would have one directive per class, but you can have as many of those directives as you like.

>> Okay, so you can't set multiple classes with one directive.
>> No, sorry, if they're all controlled by the same value, then no, you would need separate directives for each of those.
>> Question back to the bind element instead of query selector. What if I needed to bind more than one element with something like query selector all?

>> That's a great question, you can bind to a whole bunch of elements. Let me see if I can demonstrate that real quick. So. Let divs = that, and then each, I'm pretty sure this will work. And then let's add an onMount so that we can actually make this observable.

You're really putting me on the spot here, whoever asked that question. For const div of divs div.text content equals it works. Okay, so yes, you can bind to elements inside arrays and that's how you would do the equivalent of document query selector all Did you hear my comment when I said Tailwind users are crying right now because they have lots and lots of classes?

>> Yeah.
>> Yeah.
>> Yeah. Well, Tailwind makes me cry.
>> Woo, I take over now. Ended up using the ternary operator instead of the class directive for this very reason.
>> Yeah which is a totally valid thing to do.

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