Tailwind comes with pre-built, single-purpose CSS classes called utility classes that you use to style your application. If you’ve never used a utility-first approach before, you’ll be surprised at just how far you can get building a completely custom UI using only Tailwind’s defaults.
In this lesson we’ll style a message component from Discord. You’ll see how Tailwind lets us tweak our design directly from our template, all without having to write a single line of CSS ourselves. Because Tailwind’s utility classes live right alongside our markup, we won’t need to come up with any new naming patterns or conventions to keep our styling code maintainable.
This co-location of styles and markup is one of the biggest benefits of Tailwind, since it lets teams decide for themselves how best to break up their UIs – and their Tailwind styling code simply comes along for the ride.
Instructor: [0:00] Let's start by building this small piece of UI from the Discord app right here, this message component. I'm going to start off in this blank app. This happens to be a React app. Don't worry if you've never used React before. The lessons we're covering apply to any tool or framework. The biggest difference is that we use className instead of class in React.
[0:19] To start, we can see that Discord has this darker theme to it. Let's start by making the background of our app black. We can do this using the .bg-black utility class from Tailwind. Just like that, we can see our paragraph text is black. We can't read our text anymore, so let's go ahead and make our text white. Right away, we see the styles change.
[0:41] This is the heart of Tailwind. It's these little utility classes that we apply directly to our markup to style our app without having to write any of our own custom CSS. Let's keep going. We'll make this a min-height of the full screen, so it takes up all this space. Let's update this tag to be a div, and let's give it a display of flex with items-center and justify-center.
[1:07] Tailwind utilities are composable, which means that each one of these classes does one thing. If we pop open our DevTools, we can see that right here. We see that the flex class applies the display flex CSS rule. Items-center applies align-items-center, and so on. This is a handy way to see what each one of these classes is doing as you learn Tailwind.
[1:32] The background over in Discord is not pure black, so we can come back and change this to a gray. Tailwind comes with lots of colors out of the box. There's grays, blues, greens and reds, and for each color, there are many shades. For grays, we have gray 900 as the darkest gray. Then we go all the way down to gray 100 as the lightest gray, with even a 50 for a touch lighter.
[1:59] In our case, let's go with 700 for our background. You can see this gray doesn't match Discord's exactly. Later in the series, we'll talk about customizing these colors, so we can get a perfect fit. For now, we'll stick with the defaults. Let's take another look at this message component. We see it has an image, a name and a date, and then the actual message.
[2:19] Let's start with the image. I'll come over here. Let's drop in an image tag of Adam. We can see the image tag being rendered, but it's big. We can use some Tailwind utilities to control the sizing. If we set the width to four and the height to four, we'll see this makes the image tiny. If we inspect this, we can see that this ends up being a 16 by 16 image. This four comes from Tailwind's default spacing scale, which is in rems.
[2:49] Rems are a best practice to use as a unit in CSS, but we can see that there is a one to four ratio between the Tailwind spacing scale and the 16 pixels that our image ends up being right here. If we want to know the final pixel value of any of these sizes, we multiply by four.
[3:08] If we pop over to Discord and inspect this image, we can see that it is 40 by 40 right here. 40 divided by 4 is 10, which means we should just be able to set this to width and height of 10, come back to our app, and now we'll have a 40 by 40 image.
[3:27] The next thing about this avatar is that it's rounded. We can achieve that in our app using the rounded class. You'll see by default, rounded adds a little bit of border radius to the image, but there is a rounded full class that will make it a complete circle, and our image is looking good.
[3:48] Let's add a new paragraph tag, and we'll add, addMorphen, as the name, and 01/15/2021 as the date. Let's dial these. First, we can give the name here a color of text green, let's say 500. We also want to add a bit of space here to the right of the image. We can come to our image and add margin right of four on the spacing scale, and we'll also add a little bit of margin to the right of the name.
[4:21] Let's also make the name smaller, and we'll make the date extra small. If we look at Discord, we can see the date is lighter. Let's soften this text a bit. We'll make this text gray 500. Let's wrap the image and the text in a new div.
[4:43] We'll make this a flex container as well, and the paragraph will be flex items baseline, so that everything is nice and tidy up at the top.
[4:54] One thing you'll notice when working with Tailwind is that it doesn't abstract away CSS at all. If you want to lay out your UI elements using Flexbox, you have to know how Flexbox works in order to use it with Tailwind. This is a good thing, because the more you use Tailwind, the better at CSS you'll actually become.
[5:12] One last thing on our heading here. Let's make the name a little bit thicker by changing the font weight using font medium. I think that looks good.
[5:23] Now, we can grab the text of this first message, come back to our app. Drop it right below this heading here. We want these to be on top of each other, so wrap this in a div. Also wrap all of our content in a new div with the class name of max width large.
[5:45] Again, if we flip over to Discord, we can see that the text is not pure white. It's a little bit softer than that. We can come down to our paragraph and make it text gray 300. Let's grab the next message.
[5:59] In Discord, conceptually, you can see as we hover these, we highlight the full width here for each message. Conceptually, these are different things. We're going to copy this, and we're going to put it in an entirely new container that is a sibling to this first image and paragraph wrapper.
[6:19] Back in our code, that would be this div right here. We'll drop a new div with a paragraph and our second message. Let's also make this one text gray 300. You can see it's not aligned.
[6:35] One nice thing about the fact that Tailwind uses the spacing scale for things like width and margins is that we can just add these up. We know this image is width 10 and it has a margin right of 4 on it, so this total space right here is 14. We should be able to come down to our new paragraph and add padding left of 14, and get it to perfectly line up.
[6:59] We can also come to this wrapper div right here and go ahead and add a margin top of one, just to give it a bit of space, because we can see in Discord, there's a little space in between messages.
[7:11] Let's go ahead and grab this last message, come back, and we'll duplicate this and put in our last message. I'll zoom out just a bit here. Let's go ahead and apply this hover treatment. When we hover our message, we get a slightly darker background. In Tailwind, we can do that simply using the hover prefix.
[7:34] Remember, our app is currently a background of gray 700. Let's make it a background of gray 800 when we hover a message. Now we can see that new background is working. It's a little dark though, and Discord uses a background opacity to lighten it up. We can do the same thing with Tailwind using background opacity, and let's say 30 percent. That looks good.
[7:59] If we pop over to Discord, we can see there's little space on the side and above each message for the background. Come back over to our container, add some padding in the X direction of space four, and just a bit in the Y direction of space one. Grab these classes and apply exactly the same treatment to our other message containers. Now we can see all of our messages have the hover treatment, and this is looking really good.
[8:29] We ended up with a really nice reproduction of some custom UI here, and we didn't write a single line of CSS. No new files to maintain, no custom naming pattern that we had to come up with or explain to our coworkers. This is one of the biggest value propositions of Tailwind. We get to use all these shared utilities directly in our markup.
[8:49] This is absolutely one of my favorite things about this library, because how you break up your HTML and your templates depends so much on your team and what technology you're using. With Tailwind, all your styling code lives right here in the markup and just comes along for the ride. That's it for this quick intro, and I'll see you in the next video.