How to Vertically Center a DIV in React With CSS

In this lesson, we will learn how to build the Cover primitive, which will vertically center its children and allow you to inject a top or a bottom section around it.

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

Table of Contents

This lesson preview is part of the Composing Layouts in React course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to Composing Layouts in React, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Composing Layouts in React
  • [00:00 - 00:10] Hey everybody Travis here with another lesson in composing IELTS in React. In this lesson we are going to learn about the cover primitive.

    [00:11 - 00:22] Vertically centering has long been considered the holy grail of CSS. This has been the case even though there are actually multiple ways to do it.

    [00:23 - 00:46] What was coveted was actually a single property that you could set that would automatically center items vertically which is now possible in both CSS flex box and CSS grid . In this lesson we are going to learn how to build a cover primitive which will vertically center its children and allow you to inject a top or bottom section around it.

    [00:47 - 01:00] In this lesson we are going to build the following hero. This hero section will have a top and bottom section and a vertically centered section in the middle.

    [01:01 - 01:18] Now a gutter will also separate all three sections and a padding is added around the entire hero section as well. So just like always there is a link to the code sandbox site.io starter project .

    [01:19 - 01:44] Now we have in here we have just got this button that I created if you want to go look at it once again go ahead feel free to go look at it it is not important. Basically it just has two properties you can either give it a primary property and it is the start version or it is this white version and that is all there is to it.

    [01:45 - 02:00] And we are using this inline cluster as well. You can see we have already got the inline cluster a couple different places and allows us to achieve some of the layout.

    [02:01 - 02:25] So let's start off by making our cover component. Let's go ahead and import our styled from styled components.

    [02:26 - 02:42] And for now let's just not worry about the top and bottom section. Let's just worry about that middle section this stack right here.

    [02:43 - 03:02] And let's replace this div with a cover. And there we go we got that centered right there in the middle and this is done we are doing display grid we should be pretty familiar with that by now.

    [03:03 - 03:12] We are setting a minimum height of 100 view heights. Now we are going to make this configurable but we are just hard coding that for now.

    [03:13 - 03:46] And then before we were setting grid template columns to set column tracks this time we were setting a road tracks grid template rows and we are doing one of our and it works exactly the same way except for in this direction. So by setting one of our we are setting I want one road track which in this case means the entire element which is 100 view heights is going to be one road track one fraction.

    [03:47 - 04:05] And then we are using the direct child combinator here to align have the child align itself to the center. So that's awesome we did a lot already.

    [04:06 - 04:45] Now let's go ahead and address the the issue of these top and bottom sections because it's not as simple as soon as we put these in here if we we do this for example. Now things are not getting skew because we set one row and this thing is getting vertically centered then we are creating an automatic row below it and that's not what we want.

    [04:46 - 05:14] What we want is to conditionally create a top and a bottom row and then kind of adjust the rows accordingly. So the first thing we are going to do is we are going to use the render props pattern here.

    [05:15 - 05:25] Well it's not actually not render props it's just rendering a prop as a child. Now you are all familiar with rendering something as a child.

    [05:26 - 05:39] Let's say we have a component like this. We do props that children and then we can use it like this.

    [05:40 - 05:43] Right? We've seen this pattern before.

    [05:44 - 05:55] Well we could just as easily render this like that. This works.

    [05:56 - 06:04] This would do exactly the same thing. So if we can render children this way we can render any prop that way.

    [06:05 - 06:40] So we could do something like this for example and have a top section and a children and then we could call that like that. We can pass in a value into our top and that would get placed right here and then the children gets placed in the middle still.

    [06:41 - 06:51] So let's get rid of this example. And we are going to actually do this.

    [06:52 - 07:24] We are going to update our cover component to use that adders constructor that we used in the previous in the pad box lesson. Once again what this does is this takes a function and allows us to return updates to all the props and lets us hard code some values.

    [07:25 - 07:36] So from there we are pulling it destructuring off of the props the children, the top and the bottom. Then we are going to wrap everything in a React app fragment.

    [07:37 - 07:52] Now I just want to be explicit here that is why I am not using the close the shortcut. You could definitely use the shortcut if you wanted here that is totally fine that works just as well.

    [07:53 - 08:03] We could do that. And then if we have a top we are going to wrap that top in a div.

    [08:04 - 08:17] If we have children we are going to wrap that div in a children. The children in a div sorry and the same thing with the bottom.

    [08:18 - 08:37] So the children will always be placed in here but if we provide a top or a bottom we are going to conditionally put those inside of divs. Then all this gets wrapped up and that replaces the children prop.

    [08:38 - 08:51] It is a really cool thing. We can actually take props and override the original prompts with the prompts that actually get rendered based off what gets sent into this adders function.

    [08:52 - 09:21] It is really cool. Then we are going to update the code to do something very similar but instead of just displaying the grid we are going to do display grid.

    [09:22 - 09:34] We are going to set a gap of one RAM so if there is anything else out there we are going to put a gap in between them. We are going to set a minimum size of 100 view heights.

    [09:35 - 09:39] Once again we are going to address that in a few minutes. Actually we will address both of these in a few moments.

    [09:40 - 09:51] And here is the fun part. Instead of just hard coding 1FR we are going to break out we are going to check the prompts if we have and pull out the top and bottom.

    [09:52 - 09:58] If we have both the top and bottom we are going to create three road tracks. Auto, 1FR and Auto.

    [09:59 - 10:06] That means the top will be auto. The children will be whatever is left, one fraction and the bottom will be auto .

    [10:07 - 10:11] So that way the top and bottom can take up as much room as they want. Then everything else goes to that.

    [10:12 - 10:23] The children. If we do not have both top and bottom but we have the top we will just do two road tracks of auto and 1FR.

    [10:24 - 10:31] And the opposite if we have just the bottom. And then if we do not have either one then we just go back to the 1FR.

    [10:32 - 10:43] Default. And then we just need to get that.

    [10:44 - 10:52] Alignment itself. Now we cannot simply just do exactly what we had before where we could just grab anything.

    [10:53 - 11:04] So I kind of glossed over this a few seconds ago. But you notice I put on a data attribute called data cover child.

    [11:05 - 11:16] We are going to select any of the direct children that have that data attribute . Now we could have used the class name or an ID technically.

    [11:17 - 11:36] But IDs we really don't want to use IDs because those need to be unique and we don't want to accidentally forget that there is this ID hidden inside this cover one. And we could have used the class name but this is a personal preference in mind .

    [11:37 - 11:46] This kind of I feel is a little bit more expressive. And you are less likely to create naming conflicts with other class names out there.

    [11:47 - 12:05] If you bring in a third party library for example. So we added this data cover child data attribute to this div and we are selecting anything that has that data cover child attribute and aligning that.

    [12:06 - 12:14] So you see that is working already. We have this home for hire is the children and is automatically giving that one far.

    [12:15 - 12:25] And if we want to now update through the power of copy and paste. Oops.

    [12:26 - 12:34] I over copied. There we go.

    [12:35 - 12:43] Now we are putting that top section in the top prop. The bottom section in the bottom prop.

    [12:44 - 13:00] And they are going all the way to the top and bottom. And this middle section is automatically centering itself.

    [13:01 - 13:06] Now if you click here you can control the width and height. It is really cool.

    [13:07 - 13:18] You will see that we still have a gap. Of course I am recording.

    [13:19 - 13:25] It is not working here. There we go.

    [13:26 - 13:32] There we go. Just do this manually.

    [13:33 - 13:35] 500. And if we go.

    [13:36 - 13:43] It is going down way too slow. Let's try 300.

    [13:44 - 13:50] 200. What I am trying to show here is this gap is being maintained.

    [13:51 - 13:55] That is where this gap property is coming from. So that is really good.

    [13:56 - 14:08] So since it only appears in between elements we don't have to worry about if only a top or bottom it only will appear if there is an element. That is what is really cool about it.

    [14:09 - 14:25] So next step we just need to make that gap and then block size configurable. So let's override that.

    [14:26 - 14:58] And of course we need to bring in the spacing map. As of what we have here is we are setting the gutter just like we did with all of our spacers.

    [14:59 - 15:13] And then we are setting the min block size defaulting to 100 view heights but we are allowing it to be configurable. So if I want to come in here I can set and refresh that so that it is working again.

    [15:14 - 15:30] I can come in here and set the min height to be 50 view heights. And it helps to do that correctly with equals.

    [15:31 - 15:41] And now you can see the cover components only half the screen size. But let's keep that back to the full screen size.

    [15:42 - 15:46] And there we go. That's everything we need to get this working.

    [15:47 - 15:58] Now we did need to have padding around this entire amount. And luckily we already have a component that does that.

    [15:59 - 16:14] So let's go ahead and import the pad box. And we are going to get these are all coming from bedrock layout.

    [16:15 - 16:27] The exact same components that we already built. We are going to use this cover as a pad box.

    [16:28 - 16:37] And then we are going to set the padding to be large. There we go.

    [16:38 - 16:51] Now we got that padding that the mock up created. So now we have a complete set of tools to start composing any layouts that we want.

    [16:52 - 17:02] So what I thought I would like to do next is revisit that hero that mock up from the very first module. Yeah, the very first module and build that more complex hero.

    [17:03 - 17:10] This was a simple hero. Let's build that more complex hero that the mock up was showing in the very, very first module.

    [17:11 - 17:11] And we'll do that on the next lesson.