Professional CSS: Build a Website from Scratch

Styling the Cards

Kevin Powell

Kevin Powell

Kevin Powell Media Inc.
Professional CSS: Build a Website from Scratch

Check out a free preview of the full Professional CSS: Build a Website from Scratch course

The "Styling the Cards" Lesson is part of the full, Professional CSS: Build a Website from Scratch course featured in this preview video. Here's what you'd learn in this lesson:

Kevin discusses different approaches to styling cards in a web design project. He explore options such as using utility classes, creating separate classes for different card types, or using custom properties with fallback values. Kevin demonstrates how to implement these approaches and explains the benefits and considerations of each one.

Preview
Close

Transcript from the "Styling the Cards" Lesson

[00:00:00]
>> Kevin Powell: All right, so another more specific thing that we wanna work on is our cards. The hero, there's only one out of the cards, there's multiple of those. So we do need to think a little bit about how we want to approach things. Cuz if we take a look at the Figma design, we could just make these cards that we see cuz this is the part of the page we're at.

[00:00:17]
And we could tackle those and do what we want with them. We have different types of cards that are all very similar. But there's some differences, the font size of the titles noticeably being the one thing that actually switches depending on the situation we're in. So ideally, when we start tackling this, we need to sort of be forward thinking about like, how am I gonna treat those?

[00:00:34]
And there's different options we could take. I could say, you know what? My card titles are different enough between each one of them that I'm only gonna use utility classes for the titles, cuz it's just the easiest way. I already have those utilities in place, why bother worrying about anything else?

[00:00:48]
The other thing might be that you're going to have different classes. You can have a card title, one card title, two card title freer, large, medium, small, or whatever. You could come up with different modifiers or different titles in different classes for it if you want it as well.

[00:01:03]
Or I'm gonna suggest which is the third way, which is how I like to work. But again, any of those options would be completely valid and there is no issues with any of them. We'll see more once we start builiding out the other ones, the real benefit of them.

[00:01:15]
But I think, hopefully, even now the benefit will show through, but it will really hammer home once we start bringing in those other ones. But I'll say, if you're stuck a little bit, the one thing I always say is start with the easy things. If you're looking at this going, I'm not sure what I'm gonna do with my titles, but I know what I need the font sizes to be.

[00:01:33]
I know what I need border radiuses to be, and all these other things, the padding, do that first, just get through that. And then you might get some ideas on the other parts. Or at least you've made some forward progress instead of just staring at something for a while and not seeing any changes.

[00:01:47]
So if I come and take a look at the three cards here, I'm not gonna worry about the titles for now. That's the hard part, I don't wanna worry about the hard part. I'm gonna continue doing this in my components layer. I see this, it's a reuable component, more so than my hero, but it's still a component that I'm gonna be doing.

[00:02:03]
So while I'm in there, I can come down outside of the purple brace and .card on there. I know I need padding, so I can say padding: 1rem;. Padding doesn't really show me much, so it reminds me that I need a background-color. So come in with the background-color.

[00:02:21]
In this case, I don't really remember what the color is, but I know I need it to be lighter than that darker one. So, again, the naming convention I used, I have the different backgrounds in there and then I just remember, I probably had the main. So the background light is probably the one I want, and hit save and I can see that that is the one.

[00:02:40]
I'm just gonna gonna do this so we can see our code a bit better, even if it looks a bit uglier. Looking at it at this size, there we go. So the light background-color comes in and it's the same on all of the cards. So that works out perfectly for us.

[00:02:52]
The other thing, they need a border-radius, so border-radius. In this case, I think it was the middle-ish one. So I'll try my --border-radius-2 and take a look. And I think that's the right one. The problem is the images need a different --border-radius-2 cuz they had the big one on it.

[00:03:10]
I said that we'd run into a problem. This isn't the problem that we'd run into, we have another one that will come up later on. But I could say that any card that's in an image, and this would be again, you go and look at your Figma file.

[00:03:21]
And I can see that these cards have this smaller border radius in here. If I go look, these ones don't have any images, so I don't have to worry about it. But if I come and look at these ones, all of these images that are coming in here as well, they all need the same border-radius.

[00:03:37]
So I can just assume based on that, that every single one of my cards that has an image will have a border-radius. So this to me is the easier way than creating another class that I have to remember to put on all of my cards. And this is that point where having utility classes versus having classes, regular classes like we're creating right now.

[00:03:57]
Where I see the benefit of having a normal class, I can throw a card on there and it treats everything that's going on there. And it's just one thing that I can repeat over and over instead of having to remember, my card needs something, the image inside the card need something, the title inside the card need something.

[00:04:12]
If I can just do one parent class and it handles everything for me, that's awesome. So border-radius would then probably be --border-radius-1. I'm actually wondering, that looks really small, so that might actually be the 3 and the 2. That looks a little bit better, so I think it was the 3 and the 2.

[00:04:34]
If ever you're doing your own designs just really fast, if you have two elements that are nested and both of them have a border radius, you do not want the border radius to be the same. Cuz if it is the same, the one on the inside will look like the border radius is bigger.

[00:04:49]
Not super obvious in this case, but the one on the inside should always be smaller. There's a formula to figure it out, but well, these utilities or these custom properties work for us, so we're good on that. The text color is already taken care of thanks to inheritance.

[00:05:04]
The font size here is fine. So I'm just trying to think really quickly. I don't see anything else that I would need to add. If I forgot something, we'll add it in a minute. But I wanna talk now about those titles. The two choices or the three choices, as I said, we could either have to use utility classes, which feels like the easiest solution because we have the utility classes already in place.

[00:05:24]
The problem with using the utility classes is, when you get to here, you have to remember to use those utility classes here, here, here, four times the same ones. Here, we have 12 cards, yeah, 12 cards. You'd have to do the same utility classes across all of those ones.

[00:05:39]
Then you're using the same three ones over here. If you add another card or you switch out the content, then you have to remember to put those same ones again. It's not the end of the world. If that makes sense to you because we already have those things in place, by all means take that approach.

[00:05:52]
I think it's functional, it works. It's just for me, when I start having to repeat things, especially, again, in vanilla HTML and CSS like we're doing today. The utility class is here, this is when things start to fall apart for me a little bit, and I prefer taking different approaches.

[00:06:07]
We could come in here and say if it's an h3, cuz I think in all of these cards, it will be h3's. But once again, I don't like attaching styles directly to the semantic element. Just because you might have cards later on in the project where you change the organization of the page.

[00:06:22]
And it shouldn't be an h3 anymore, it should be an h4 or an h2. So for that, I do say coming in with another class here does work. And we did the hero title, so I think it's good to be consistent with a card title. If you have a different class name or anything there you'd wanna use, you can.

[00:06:40]
And if you don't mind using the semantic tag, you could also select your h3's. But just be really careful with that for just the potential future growth of the project. If I do that, it does mean on all those cards, let's just do a quick find. Whoops, not, .card.

[00:06:58]
To find them all, I just remembered coming here, I see the grid flow. I use the grid flow because we created it, it's a nice way to have consistent spacing. Do you really wanna do that every time you have a card too? So let's do the titles first, but then we'll circle back around to that.

[00:07:12]
So on all three of these h3s, I'm just gonna put my mouse there, scroll down, Alt and click, and probably Option on a Mac, I'm guessing. And then the same thing here. So my cursor is in the same place in all three, and I can just write it once, card-title.

[00:07:29]
So card-title on that one, card-title on that h3 and card-title down on that h3, except I did it without the double underscore. So just to be consistent again, we'll do the double underscore on all of those. What I'm gonna suggest is gonna be a bit weird, but it's gonna hammer home why I like using custom properties a lot.

[00:07:49]
So for this, let's start with the font size. And as a starting place, or actually I'm gonna do a var(--card-title-font-size). If you prefer fs cuz it's shorter by all means, font-size, comma, and I'm gonna give it a default value. If I have a generic card, what's my generic card going to look like?

[00:08:17]
And I have to make a decision on that. I'm just gonna say that these ones over here are my generic card and the other ones are the modified versions, just because this is the first one I'm doing. So the font size of that is quite big, I think that's my heading-regular.

[00:08:35]
We'll check that in a second. My color of it is gonna be a VAR A card title color, comma. And that one's easy becaus var(--card-title-color, ), and that one is easy cuz it's the --text-brand. And what this is doing is, because the card title font size doesn't exist, it can't find that custom property.

[00:08:57]
Oops, I made a small mistake here. I do need to wrap these in var and it didn't do it for me. It's gonna use these other custom properties as the fallback. So, yeah, these don't exist yet. And so now when I come in, and take a look at the card, it's using those two fallbacks instead.

[00:09:16]
And let's just put this on multiple lines cuz it might make it a bit more easier to read. And then we can do the same thing for the color. I'm not saying you need to format it this way, I just wanted to show all the text on the screen at once.

[00:09:28]
So it's looking for a card-title-font-size. It can't find one, so it goes to this fallback instead, which gives it the bigger size. And then it looks for the color, can't find it, uses this color as the fallback instead. Sometimes, when we did our wrapper and we did other things, I was taking a different approach, where I was coming on the card title and I was setting the defaults here.

[00:09:49]
So --card-title, let's just say orange or whatever, don't do this. Sometimes you'll wanna do things like this, where you sort of wanna encapsulate the styles. And you're just saying these are things like levers that can be pulled and changed when you're doing it for modifier classes or for different reasons.

[00:10:05]
But if it's something that I wanna change it on a large scale where I might wanna go on the parent and change what all of these values are, I wanna open that door up. So let's just say on these cards, I'm gonna do a quick example here. This isn't gonna work, so don't leave it in your code.

[00:10:22]
But I could come on my equal-columns now. And I could say any cards that are in my equal-columns, I could just say that the --card-title-font-size: 1rem. And now all of those cards that are in equal columns, they're getting that font size on them. And we could do the same with the color.

[00:10:41]
--Card-title-color: purple, and we could change the color of them. Because it's not gonna use the fallback anymore, it's gonna use the value that's over here. So as we get into the second page, this type of thing can be really useful. Cuz we could say any card that's in this parent can have these specific values for the card title and for other things along the way as well.

[00:11:05]
So we can set it all up like that and it's gonna pay off, again, a bit more work in the short-term. But in the long-term, it becomes a lot more adaptable and robust. And at the same time, I mentioned I put the grid flow on here. You could definitely leave it here, but it could be one of those things where you want the flow to change depending on the cards.

[00:11:24]
I don't think we necessarily need to do it in this case. But since we have all the other classes on our card. And because that would mean every time we use our card we'd always have to use the gridflow as well, it just seems a little bit pointless for it to be there.

[00:11:41]
When I'm using utility, the idea is because this card is gonna need it and this card isn't gonna need it. A little bit like our background-colors. This section needs this background-color, this section needs a different background-color. Because they're different, it makes sense to be able to plug and play things.

[00:11:54]
If it's always the same style every time and you already have a parent class on there, there's no reason not to just come on. Do a display: grid; gap: var: (--card-gap, 1rem);. And I think our gap there might actually wanna be smaller, I'm not sure. Maybe the 1rem is okay, though.

[00:12:17]
And now we have a card that will be able to be a little bit more robust. We can change it depending on the situation by having the --card-gap, the background or, sorry, the title and the colors changing on them. Whereas the things that we don't want changing, the border radius is always the same, the background colors always the same.

[00:12:40]
This is one of those situations, too, where you might wanna say, hey, you know what? I'm gonna have different cards on another page, maybe I'm gonna take that same approach for the color, or the same approach for the border radius. So again, I have one card, lots of shared properties.

[00:12:52]
But the more locally scoped properties you do with fallbacks on them, you're opening up more levers that can be pulled just to have one reusable component that can be tweaked and changed. It really depends on the project. I would actually leave it like this for now cuz it's doing exactly what I want it to.

[00:13:08]
And if I ever needed to have more adjustments, it's not that hard to jump into this and then just do a few tweaks along the way.

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