Layout a circular design using css transforms

Isaac Mann
InstructorIsaac Mann
Share this video with your friends

Social Share Links

Send Tweet

Most webpages are nothing but rectangles, but css can do circles too. We use css transforms (specifically translate and rotate) to break out of the rectangle mode and create a page where elements are positioned along the edge of a circle.

Isaac Mann: [0:00] One of the more interesting pieces of this design is this middle piece right here where you have an illustration that's an oval, and then the attributes for that character arranged as circles around that oval. Let's see how we're going to tackle that.

[0:17] The basic idea we're going to use is to try to position everything in the center, right here, and then individually move out these circles out to where they need to be on the outside. The easiest way to absolutely center something is to use CSS Grid, and then align items in the center, and justify items in the center.

[0:51] Each of the items inside of a grid need to either be assigned to a specific named area in the grid like main was here, or we can specify the starting row, starting column, ending row, and ending column, like this. We'll do the same thing for the attributes.

[1:17] Now, let's give these a border so we can see what's going on here. It'll have a width of 100% and a height. We'll give it a border-radius of 50% to give it that oval shape. Attributes here is the entire list.

[1:44] We need to again center each list item inside of that list. We'll do the same thing we did here, telling the list to center everything. Then the individual list items will be in the first row and first column.

[2:09] Now they're all lining up. Let's give them a border with a width of 100 pixels and a height of 100 pixels and a border-radius of 50 percent. Let's give this illustration an actual image here with a URL of ranger, and we don't want it to repeat.

[2:41] Now, this isn't quite right, we've got the bottom of the image showing up here, so let's give it a background-size of cover, so the image will always cover this whole oval here. We can also add a little trick here of adding a second background image to go behind the other one. That makes a nice effect there.

[3:08] These attributes, we want them to have a white background here, so they show up better. You notice that in our design, the oval for the illustration doesn't exactly line up in the center of the main area. It's offset a little bit to give space on the left and the top for these attributes circles.

[3:34] We don't want to just move the illustration. We want to move the illustration and the attributes together, so that the attributes are starting in the center of this oval. We'll add a margin to the main area here.

[3:49] We'll do a top margin of 50 pixels, and then a negative margin on the right-hand side, no margin on the bottom, and a positive margin on the left-hand side. Now, this makes it so that our oval sticks off the side a little bit the same way that this one does here.

[4:07] Next, let's look at these attributes circles. The label for the attribute is going to go in the bottom of this circle here. In the middle, we're going to put our modifier, and then up here is the base attribute. Then, down the bottom right is our save modifier.

[4:25] The only two things that we want inside of this circle are the label and the modifier value. We need to modify our HTML a little bit to make this CSS possible.

[4:38] For each of these list items here, we're going to select all of them. We're going to wrap them in a div with a class of circle. Now, we want the label to go inside and the modifier to go inside, but the base and the save value go outside. Now, we'll save that, and we need to save these styles, so we don't lose them. Now, we can refresh, and our HTML modifications have been put in place here.

[5:24] We actually want to put the border around the circle element, not the list items. We'll take the border-radius and background off of here, and the border as well. We'll give it a width of 100% and a height of 100%. There we go, so that looks right.

[5:55] Now, let's start moving each circle out to the edge of our illustration. We'll write a selector for the :nth-child() and the :first-child(). This selects only the first list item here. We're going to apply a transform that does a translation 42% of the view width to the left and nothing out. That looks about right.

[6:24] We'll do the same thing for each list item, except for each of them. We're going to change these values, just playing around until we find values that seemed to work.

[6:37] The illustration looks like it's not quite the right size. Let's give it a min-height of 500 pixels, and let's make these attributes circles a little bit smaller. It looks like we need more space along the top here, so let's give ourselves some more padding here.

[7:31] Now, our circles are positioned relatively close to where we want them to be. Let's get the label and the modifier in the correct position. Since the label and the modifier inside of the circle, we can just position them using Flexbox by making the circle be display: flex, and setting the flex-direction to column. Actually, we want column-reverse.

[7:59] Now, for the label, we'll set the text-align to center. We'll transform the text to make it uppercase. Let's give it a border across the top. Let's see. Now, we can see this line is coming outside the circle.

[8:21] Let's go and add overflow: hidden to that circle now that line gets cut off correctly. We want this to take up a little bit more space along the top here. Let's increase the line-height. That looks about right.

[8:47] For the modifier, we'll align it in the center. Let's increase the font-size. That's too big. That looks about right and give it a line-height, something like that. Now, let's do this save modifier, this bottom right circle here.

[9:34] First, we'll give it a width of 40 pixels and a height of 40 pixels, give it a border, and turn it into a circle. Position the text in the center with text-align and line-height equal to the same thing as the height of our circle.

[10:08] Now, we can give it a white background so it shows up. We can do another transformation. Translate, say 30 pixels - 20 pixels, to move it up a little bit, and we just keep moving around until we find the right positioning. That looks about right, but it's on top of this bigger circle when it should be underneath it.

[10:38] Let's fix that. Give it a position: relative so that the z-index will work. We'll get this a z-index of one, and then our circle, we need to give a position: relative and a z-index that's higher, of two. Nice. This is coming together. Now, all we need to do is this banner that will have the base attribute inside of it.

[11:17] First, let's use an SVG to render the small-ribbon banner. We want it to not repeat, and we'll give it a width of 80 pixels and a height of, let's try, 50 pixels. It's about right. We'll align the text in the center again. It looks like we need to make that banner a bit bigger. Give that a line-height. There we go.

[12:01] Now that text is lined up inside of the banner, and all we need to do is position that banner on the top left of each circle. We'll do a transform here. First, we will translate up. That's a little bit too high. We want to position it just above the circle here, and then we want to rotate it. Actually, let's rotate it first, and then translate it to where we want it to be. That looks about right.

[12:55] But that's messed up our saved circle here. Let's fix that one. There we go. That's better. Let's polish this up a little by moving the wisdom attribute down a bit. That's the fifth attribute here. Let's move over the charisma so it doesn't get fully cut off there. There we go. We've recreated this circular pattern here in CSS and HTML.