Check out a free preview of the full Professional CSS: Build a Website from Scratch course
The "Creating Flow & Spacing" 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 the concept of flow in CSS and how to reintroduce spacing between elements. He also explores different methods, such as using the pros class or the lobotomized owl selector.
Transcript from the "Creating Flow & Spacing" Lesson
[00:00:00]
>> Kevin Powell: Now, one thing you might have noticed in our site is all of our spacing disappeared, cuz we did a margin zero really early on for our paragraphs or headings and other things like that. And it looks kinda weird that everything's glued together. And when we have spacing between type and things like that, it's generally called flow.
[00:00:17]
You have the CSS flow, page flow includes that space normally. So we need to reintroduce the flow, and there's different ways that we can do this. If you're used to Tailwind, you know the prose class. The prose class, I have an example of it here, I don't, but I do mention it and I have a link to it.
[00:00:33]
The prose class brings margin-top and bottom back, cuz their reset takes the margins away, like we've done. And their prose class takes anything that's a descendant of that and adds the margin-top and bottom back in with some tweaks to what those are. There's another thing, which is the lobotomized owl, which is by Heydon Pickering, who coined that term.
[00:00:52]
And I have a link to the article from way back when he coined it, which is the * + * selector. You can see here, it's actually on my shirt right now, that we have the * + * selector that's right there, where it looks a bit weird.
[00:01:07]
There's other ways that we can write that, but basically, it reintroduces. By doing it like this, we can reintroduce flow back into our document. And if we go and take a look, I'm not gonna use it properly at the beginning. But I'm just gonna come here and do .flow > * + *, and I'll show you the alternatives, too.
[00:01:30]
I would suggest potentially leaving a comment here cuz people do complain that it's not very readable. If they come across, it's not obvious what it's doing, and I'm gonna say for now, color is red. Just so we can see what this is actually doing. And I'm gonna go, where should we put this?
[00:01:45]
I'll put it in the heading, the hero. So if we come all the way up to the top and we find my hero, we'll do it on this wrapper just cuz I have three paragraphs here. So in this wrapper, if I add a flow, this paragraph and the next one after it are getting a red color on it, the first one isn't.
[00:02:07]
So what the * + * is, it's using the direct sibling selector. Or it's a preceding sibling selector, so it's only selecting an element if it has an element before it. So this paragraph, does it have an element before it that's a direct sibling? Yes, it does. Does this one?
[00:02:27]
Yes, it does. Does this one? No, it doesn't, cuz if we look in the HTML, it's at the top. It doesn't have a sibling that comes before it, so it doesn't get selected. The alternative to writing it this way is saying not(:first-child), and you'd get the same result.
[00:02:47]
If I hit save, it's selecting all of them other than the first child. The only problem with doing it with the not(:first-child) is this does bring in extra specificity with it, which the star selector has no specificity. So here, we now have two class selectors. If you wanna get rid of the specificity, we do have where now.
[00:03:04]
So you could come in and say, where:not(:first-child), and then you've eliminated the specificity of it. And it's only a class selector again, but it just feels really heavy-handed in my opinion, and it's really not that much more readable than just doing this. I had a comment saying, selects everything except the first direct child.
[00:03:23]
I think is good enough for most people. Obviously, though, instead of doing the color, what we can do here is do it a margin-top of var. I'm goinna do it as a var(--flow-spacer), something like that, and then just have a 1em as a default. And I'm choosing 1em as a default on purpose rather than 1rem, because for the flow of text, here's this quick example I put together so we don't have to build it out.
[00:04:01]
This side here, they're both using the * + * for these two columns. The one on the left is using the one on the right is using rem. So the one on the left with the you'll notice that the space here is bigger, because the is based on the font size of that element.
[00:04:17]
So it's creating more space right here, and then it's creating more space here cuz this is bigger than those. And it creates just a better visual hierarchy for the way typography is supposed to work. Anybody who knows about topography, it's all about the hierarchy, and proximity to things is the word I'm looking for.
[00:04:35]
And so we're trying to keep the proximity of what this is related to closer to here, and it just creates a more visually appealing thing. It's easier to skim and everything else. Then when you have 1rem and all the spacing ends up being the same. This is for regular flow text, there are times you want consistent spacing, we'll look at that in a second.
[00:04:53]
But when you want regular flow, it doesn't make sense, it just makes a lot of sense to use. And it's the reason we're using margin-top instead of margin-bottom, cuz some people prefer doing the same thing on margin-bottom. But I want a bigger margin on top of the large text.
[00:05:07]
So if I hook into the fact that the large text 1em is bigger than 1m on my smaller text, using margin-top is the easiest way to do that. So flow, just like that, gives us that type of thing. So that means we can come into our project now that we've added that there, and we can add the flow wherever we want.
[00:05:26]
Now, I did say I like having wrappers just be wrappers. So this is another divisive thing, well, it's not divisive, but it depends on how you like to work. But you might want to have another div with a class of flow cuz you'll need it there. Cut that, paste it down here, and have the wrapper and then the flow, or you might just wanna put them together.
[00:05:49]
I've done it both ways, it just depends, you want another div or do you mind mixing the wrapper plus the flow together? It's completely up to you. I am gonna add it to my hero too, though, cuz right now, the mushroom foraging is touching the text that's underneath it.
[00:06:02]
So I can add a flow here. Whoops, I don't wanna remove those. I'm gonna add the flow right there just to give us the space we need right there. The advantage of the flow being here too, this font size actually needs to be bigger. Potentially, we put the class there, we have the utility for that now, but we can come down to the next section.
[00:06:22]
And it's a little bit annoying, and this is one of the reasons when you do a reset, maybe you don't wanna remove all your margins, cuz then you do have to find a way to bring spacing back into things. So it is an argument for not just nuking margins right off the top.
[00:06:34]
So here we have the wrapper, so I can do another flow.
>> Kevin Powell: And I want to close it right there, so that adds the spacing between those, I think. The cards, I'll talk about in a second. We'll come back to those in a minute, but I'll leave those alone, and we'll circle back.
[00:06:54]
The next section down here, these two, we need some flow, so I can add my .flow. While I'm on this one, though, one thing I didn't do earlier, so we did create those utility classes before. So I am gonna say this is also a text, no, sorry, font-size.
[00:07:13]
I talked about them and we didn't do a lot with them. font-size, I think it would be the md or even lg, I think, which gives us that larger font size that we had there. And we want the text to be white, so I could do text-high-contrast. And this is where I have three utility classes, basically on one element.
[00:07:33]
And I might say, do I really want three utility classes there or should it be a component? Cuz we also wanna come on the very top here and probably do a text-center as well. And then everything centers cuz that area is always centered. But this is where you will start seeing, when you have these different utilities that are in there and you're going through your site, how quickly you can start working.
[00:07:53]
Or these more generic selectors, let's say, instead of utilities. So then we can come down to this next section that's two columns. In this case, I don't want it just by my wrapper, cuz my wrapper then has the image. And after that, it has this div that's sitting here, creating the other column, so that one can get the flow on it.
[00:08:16]
And I could also do my font-size, I keep saying text, font-size-lg on that one as well. We could come down to this next section, wrapper equal-columns. I have this div that has the text in it. So basically, anytime I have text, I need a flow class around it.
[00:08:37]
And then if I do need to change the font size, I can come in and do that at the same time, so font-size-lg. I think those are supposed to be lg anyway. There we go, and those ones come through like that.
>> Kevin Powell: I might have missed one along the way.
[00:08:53]
So it's one of those things that as you're going through the project, you might be like, I forgot a flow here, you just add it in wherever you need it. So just making sure, and you just go through and visually check your site after to see if there's things that are stuck together that shouldn't be stuck together.
[00:09:06]
I'm doing a quick check now, and the one area that I see where I have a problem is inside my cards, where everything is glued together. We'll get to that in the next little bit, just cuz those spacing we actually want it to be consistent instead of different.
[00:09:18]
So for those cards, what we wanna do is we have two choices. You could use the flow and then you could change what the --flow-spacer is to make it 1rem instead. I personally have the habit of doing a grid-flow, cuz it just distinguishes the two between each other for me, grid-flow.
[00:09:37]
And the reason I use grid for this, you could also use Flexbox, but with Flexbox, you have to change the flex direction. With grid, you don't. And I do a display: grid and a gap: var(--grid-flow-gap. You get where this is going, but 1rem instead of 1em. Even though in this situation because it's a gap, the 1em, it wouldn't change anything in any situation.
[00:10:04]
And this is the name, grid-flow, for me, is because I know grid is going to be consistent spacing, cuz I know I'm gonna be relying on gap instead of using margin. If you'd want consistent flow or, I don't know, a name that would imply that the spacing is always the same instead of being more general flow, you can go with another name.
[00:10:24]
For that, that would sort of hammer home that idea a little bit better. But then on these cards that we have here right now, we will change it a little bit after, but I just wanna show how this can be useful. So I think I actually called those cards.
[00:10:38]
So for now, we can also give each one of those cards the grid-flow. And we could have done this a bit faster, but we'll do it the slow way by scrolling to each one of them. You can see this change it already made, but if I make that bigger now and I go and take a look at those cards, we can see we get a bit of spacing coming between them there.
[00:10:59]
And I just realized I don't have any space here. So I'm gonna fix that really fast while we're at it, which would be that flow. I'm gonna do it on here for now. No, we shouldn't need that, the wrapper. No, one second. We have the flow is adding flow to here.
[00:11:25]
For this case,
>> Kevin Powell: I want an extra space, we'll figure that one out.
>> Kevin Powell: Yeah, if we added flow here, it would actually work. You can see it's adding the space there. Maybe I'll make that exception there just so we don't have to get some extra divs, layers, a wrapper flow could be a bit annoying.
[00:11:48]
The reason that one's working is because if we look directly in there, it's adding the space between this and then those three columns we have there. So by having that extra flow and then the nested flow. It might be an argument in this case, actually, of not having this one here at all.
[00:12:08]
We could do it that way to simplify things a little bit and then just combining those two together. Maybe in this case, we'll cheat a little bit and allow them to be combined just so we don't have extra divs for nothing and having to redo the extra classes for nothing.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops