CSS Grid and Custom Shapes, Part 3
Should I read the previous articles before?
It’s not mandatory but highly recommended to cover as many tricks as possible. You can also read them in any order, but following along in chronological is a good idea to see how we arrived here.
Enough talking, let’s jump straight to our first example.
Before digging into the CSS, let’s check the markup:
Nothing but a few
<img> tags in a div wrapper, right? Remember, the main challenge for this series is to work with the smallest amount of HTML possible. All the examples we’ve seen throughout this series use the exact same HTML markup. No extra divs, wrappers, and whatnot. All that we need are images contained in a wrapper element.
Let’s check the CSS now:
Basically, this is a square grid with three equal columns. From there, all that’s happening is the second and third images are explicitly placed on the grid, allowing the first and last images to lay out automatically around them.
But what you really need to know is this:
…is equivalent to this:
Same for the
grid-area property. If we open DevTools and inspect our declaration:
grid-area: 1/2/span 2/span 2; you will get the following:
…that is the same as writing all this out:
Same deal for the other
grid-area declaration. When we put it all together, here’s what we get:
Yes, the second and third images are overlapped in the middle. That’s no mistake! I purposely spanned them on top of one another so that I can apply a
clip-path to cut a portion from each one and get the final result:
How do we do that? We can cut the bottom-left corner of the second image (
img:nth-child(2)) with the CSS
And the top-right corner of the third one:
Let’s try something different. We can take what we learned about clipping the corner of an image and combine it with a nice effect to reveal the full image on hover.
The grid configuration for this one is less intense than the last one, as all we need are two overlapping images:
Two images that are the same size are stacked on top of each other (thanks to
grid-area: 1 / 1).
The hover effect relies on animating
clip-path. We will dissect the code of the first image to see how it works, then plug the same thing into the second image with updated values. Notice, though that we have three different states:
In each case, we have a triangular shape. That means we need a three-point polygon for the
What? The second state isn’t a triangle, but more of a square with a cut corner.
You are right, but if we look closely we can see a “hidden” triangle. Let’s add a
box-shadow to the images.
A ha! Did you notice it?
What sort of magic is this? It’s a little known fact that
clip-path accepts values outside the
0%-100% range, which allows us to create “overflowing” shapes. (Yes, I just coined this. You’re welcome.) This way, we only have to work with three points instead of the five it would take to make the same shape from the visible parts. Optimized CSS for the win!
This is the code after we plug in the polygon values into the
--_p variable. I’m using that to optimize the code a bit as we add the hover transition. Instead of updating the whole
clip-path we only update this variable to get the movement. Here is a video to see how the points should move between each state:
We can take slap a
transition on the
<img> selector, then update the
--_p variable on the states to get the final effect:
If we don’t consider the gap (defined as
--g in the code) between the images, then the three values of
-50%. Each one defines one of the states we explained previously.
Let’s increase the difficulty level from that last one and try to do the same trick but with four images instead of two.
Cool, right? Each image is a quarter of a circle and, on hover, we have an animation that transforms an image into a full circle that covers the remaining images. The effect may look impossible because there is no way to rotate points and transform them to fill the circle. In reality, though, we are not rotating any points at all. It’s an illusion!
For this example, I will only focus on the
clip-path animation since the configuration of the grid is the same as the previous example: four equally-sized images stacked on top of each other.
And a video worth a boring and long explanation:
clip-path is formed by seven points, where three of them are in a fixed position and the others move as shown in the video. The effect looks less cool when it’s running slowly but we can see how the
clip-path morphs between shapes.
The effect is a little better if we add
border-radius and we make it faster:
And by making it even faster like in the original example, we get the perfect illusion of one quarter of a circle morphing into a full circle. Here’s the polygon value for our
clip-path on the first image in the sequence:
As usual, I am using a variable to optimize the code. The variable will switch between
1 to update the polygon.
You know mosaics, right? It’s an art style that creates decorative designs out of smaller individual pieces, like colored stones. But it can also be a composite image made up of other smaller images.
And, you guessed it: we can totally do that sort of thing in CSS!
First, let’s imagine what things are like if
clip-path were taken out of the mix and all we had were five overlapping images:
I am cheating a little in this video because I am inspecting the code to identify the area of each image, but this is what you need to do in your head. For each image, try to complete the missing part to see the full rectangle and, with this, we can identify the position and size of each one.
We need to find how many columns and rows we need for the grid:
I don’t want you to think that the way I sliced this up is the only way to do it. This is merely how I’ve made sense of it. I am sure there are other configurations possible to get the same layout!
Let’s take that information and define our grid, then place the images on it:
I think you get the idea of what’s happening here now that we’ve seen a few examples using the same approach. We define a grid and place images on it explicitly, using
grid-area so the images overlap.
OK, but the
aspect-ratio is different this time.
It is! If you get back to the reasoning we made, we have the first two images that are square next to each other having the same size. This means that the width of the grid needs to be equal to twice its height. Hence,
Now it’s time for the
clip-path values. We have four triangles and a rhombus.
Again, I’m using Clippy for all this math-y stuff. But, honestly, I can write many simple shapes by hand, having spent several years working closely with
clip-path, and I know you can too with practice!
Let’s increase the difficulty and try another mosaic, this time with less symmetry and more complex shapes.
Don’t worry, you will see that it’s the same concept as the one we just made! Again, let’s imagine each image is a rectangle, then go about defining the grid based on what we see.
We’ll start with two images:
They are both squares. The first image is equal to half the size of the second image. The first image takes up less than one half of the grid width, while the second image takes up more than half giving us a total of two columns with a different size (the first one is equal to half the second one). The first image is half the height, so let’s automatically assume we need two rows as well.
Let’s add another image to the layout
This one makes things a bit more complex! We need to draw some lines to identify how to update the grid configuration.
We will move from a 2×2 grid to four columns and three rows. Pretty asymmetric, right? Before we try to figure out that complete sizing, let’s see if the same layout holds up when we add the other images.
Looks like we still need more rows and columns for everything to fall into place. Based on the lines in that image, we’re going to have a total of five columns and four rows.
The logic is simple even though the layout is complex, right? We add the images one by one to find the right configuration that fits everything. Now we need to identify the size of each column and row.
If we say the smallest row/column is equal to one fraction of the grid (
1fr) we will get:
…for the columns, and:
…for the rows. We can consolidate this using the
grid shorthand property again:
You know the drill! Place the images on the grid and apply a
clip-path on them:
We can stop here and our code is fine, but we will do a little more to optimize the
clip-path values. Since we don’t have any gaps between our images, we can use the fact that our images overlap to slim things down. Here is a video to illustrate the idea:
As you can see, the image in the middle (the one with the camera) doesn’t need a
clip-path. because the other images overlap it, giving us the shape without any additional work! And notice that we can use the same overflowing three-point
clip-path concept we used earlier on the image in the bottom-left to keep the code smaller there as well.
In the end, we have a complex-looking grid of images with only four
clip-path declarations — all of them are three-point polygons!
Throughout this series, we explored many, many different types of image grids, from the basic stuff to the complex mosaics we made today. And we got a lot of hands-on experience working with CSS clipping — something that you will definitely be able to use on other projects!
But before we end this, I have some homework for you…
Here are two mosaics that I want you to make using what we covered here. One is on the “easier” side, and the other is a bit tricky. It would be really awesome to see your work in the comments, so link them up! I’m curious to see if your approach is different from how I’d go about it!
If you need help creating a digital marketing strategy for your business, don’t hesitate to contact one of Digidude’s consultants.