Create Complex Shapes with CSS Clip Path and Border Radius

Jhey Tompkins
InstructorJhey Tompkins

Share this video with your friends

Send Tweet
Published 2 years ago
Updated a year ago

In this lesson, we explore creating the Egghead Shell with CSS. We explore how different properties allow us to create different shapes and how we can use our developer tools to adjust and tweak style values.

Jhey Tompkins: [0:00] We have some markup for our egg. Let's style the shell. Let's start by applying a background-color to our shell container. Using a color with reduced alpha makes it easier for us to make comparisons with the image we are trying to trace.

[0:16] We won't see our shell element until we define a width and height for it. At this point, we have a decision to make. We can either use the responsive unit we defined earlier or percentage-based values for sizing things in our illustration.

[0:28] Let's use percentage and go with a height: 90% and a width: 70%. We want to center this shell in our illustration. We can use position absolute with a top: 50% and left: 50%. We can use transform: translate(-50%, - 50%). That centers our shell in our illustration.

[0:57] We can see the size of our shell isn't quite right. It's not quite tall enough and it's not quite wide enough. Using DevTools, we can tweak the dimensions of our container where 95% looks about right for the height and 74% looks about right for the width. Let's update those sizes in our CSS.

[1:20] Next, let's work on the pieces of our shell starting with the top. We want to be able to see the image underneath, so let's start by defining an opacity of .5. We can start with a height and width of 100%. Let's go with a background-color of purple.

[1:40] To get that curved shape, we can make use of the border-radius property. Border-radius not only allows us to create more basic shapes with a uniform radius, but it also allows us to create more complex shapes using the / notation where the first four values are for horizontal radius and the second four values are for vertical radius.

[2:04] For our radius, we're saying 50% horizontally for the top two corners and 85% vertically for those top two corners. If we look closely, we can see that the shape isn't quite there. It's not quite filling the width.

[2:19] Much like we did with the containing element for our shell, we can tweak the styles to try and make the shape we want. Here, it looks like stretching the height and increasing the width will get us close. However, we've hit an issue. Our eggshell piece is no longer centered in our eggshell container.

[2:37] Let's add the styles for that. Using position absolute, we want the shell to be aligned to the top of the container, so a top: , but we want this piece of the shell to be center aligned, regardless of its width. We can use left: 50% with a transform: translate(-50%, ).

[2:58] We can revisit DevTools to tweak the styles and create the shape we need. Let's add them to our CSS. Now, we've got the shape we want.

[3:09] How do we clip the element across here? For this, we can use a clip-path with a value of inset where the four containing values equate to the top, right, bottom and left sides of our element. If we change the bottom value of our inset to 50%, that will clip off the bottom 50% of the element.

[3:31] Once again, we can jump into DevTools and tweak the styles to find an appropriate value. Let's update our CSS with the 70% value.

[3:43] We also need to define the border for that outline. We can use our responsive unit that we defined earlier with the color we defined for the shell outline. We can see that our border isn't quite thick enough, so we adjust the values until we find a border that we're happy with. Lastly, we apply the background-color and that's the top part of our shell.

[4:10] We can follow the same process to create the other parts to our shell. Let's start with an opacity: .5, a height: 100%, and a width: 95%. To see what we have, apply background-color using the shell variable we created. This piece will also need to be center aligned. Let's apply the same border that we used for the top of the shell. Let's also attempt to use the same border-radius.

[4:41] We can see that the width isn't quite there. We can use DevTools to increase the width to something we're happy with. Apply that to our CSS and we're ready to clip our element. We can use the inset clip again, but this time, we need to clip from the top and from the bottom. A top value of around 30% and a bottom value of around 40 to 50%.

[5:07] Putting those values in gives us a shape that's quite close to what we want. However, we likely want to bump up that top inset value slightly, so that our border doesn't show or peek out above the spectacles. Let's try 32% and that looks great.

[5:25] Last stop is the bottom of our shell. The same process applies again. Use the same background-color and the same border. The bottom of the shell needs to be positioned at the bottom of the shell container. It looks almost circular. We can try border-radius: 50%, a width: 100%. Let's try a height: 60%. We need that reduced opacity to see what we're doing.

[6:00] If we try increasing the height in DevTools, we may be able to get the shape we want. A value of around 76% looks about there.

[6:11] An alternate approach would be to use a height: 100% and the more complex border-radius value, where we utilize the / notation to gain finer control over the curve of our element. This emphasizes how there's normally more than one approach to what we want to achieve.

[6:28] The last piece to the bottom part of our shell is to use a clip-path. This time, we are only interested in clipping the top part of the element. 50% doesn't quite cut it. How about 58? That looks pretty good.

[6:42] Now that we've created our shell with the different pieces, it wouldn't be a bad time to refactor those shared styles. We can extract the common styles from one of our shell pieces, where we reuse the background positioning, the translation, and the border.

[6:59] Let's remove some of those duplicate styles. That way, we can check that we've refactored everything correctly. We could refactor this slightly further. For now, let's leave it there and remove these opacity declarations. We can also remove the background-color for our shell container and that's our eggshell complete.

[7:34] In review, we've created our eggshell by using one containing element and then using elements for each part of the shell -- the top, the middle, and the bottom. These are positioned relatively to that containing shell element.

[7:49] We've used border-radius to achieve these curves and we used a clip-path inset to clip off parts of each shell piece that we don't need to see.

[7:58] We've looked for opportunities where we can share styles across classes. We've done so with the showpiece class by sharing things such as the background-color, the border properties and positioning.