Wrapping Content around images using CSS Shapes

Remember back in the golden ages of copying and pasting WordArt into you Microsoft Word document? Going to ‘Format Picture’, selecting the ‘Tight’ option so you could have the text automatically detect the graphic element and have the text wrap nicely around it? Unfortunately achieving the same effect on your website is not as elementary as just clicking a button, but with a little practice and a little education, you’ll be up and running in no time.

When we wrap text around graphic elements (PNGs, JPGs, SVGs, etc…) it helps the image to stand out. It makes the image more realistic and lively within the flow of the page. You can see in the photo how the text nicely wraps around the bowls of soup. And because of this, the bowls stand out nicely and become more important to the image.

Getting Started with CSS Shapes

By using CSS Shapes, we allow ourselves the freedom to specify various coordinates that will create a custom path, and eventually create our custom shape.

There are two main CSS properties that we will use to achieve the desired effect; Clip-path and Shape-Outside. When used together, these two properties compose the foundation properties of CSS Shapes.

Shape-outside and clip-path take many different vales, but the three I will focus on are circle(), ellipse(), and polygon(). While circle() and ellipse() will namely create a circle or ellipse respectively, the polygon() function is able to take an unlimited set of coordinates, that when connected, will create your desired shape.

But Nick, can’t I just use a transparent background .PNG image?

Unfortunately no. Using a transparent background .png image is the same as using any other graphical element, the only difference being that the background is transparent. 
You’ll notice that with your .png file, if you change the background colour, to (let’s say) red, you’ll be able to see the invisible background container that your image is sitting in. I call this the image footprint.

Clip-Path

Think of clip-path like you are cutting a shape from a rectangular piece of paper (this paper represents our graphical element). We are cutting up the image into our desired shape, but the important key to note here is that the image footprint will still remain. Meaning the rectangle container the image sits in will still be there, and you’ll see this because the content will flow around the image in a rectangular manner.

Shape-Outside

Shape-outside is the CSS property that will allow your content to flow around your shape. It essentially dictates how content interacts with your graphical element. Just used alone, your image will not be cropped or clipped, but rather the content will flow around the image as if it was.

Like with most things in life, we learn by example and by actually doing it. Below, I will include some examples to demonstrate how these two CSS properties are used in conjunction to create some cool design layouts.

Examples:

Note: All images used here are transparent background .png files. I added background colours to the images to make it easier to visualize the individual components.

Circle()

Before

.basketball {
width: 40%;
float: right;
background: red;
padding: 30px;
}

Just using shape-outside

.basketball {
width: 40%;
float: right;
background: red;
padding: 30px;
shape-outside: circle();
}

After: shape-outside + clip-path

.basketball {
width: 40%;
float: right;
background: red;
padding: 30px;
clip-path: circle();
shape-outside: circle();
}

Ellipse()

The ellipse and circle function work in an extremely similar fashion. Instead of showing the example of using shape-outside only, I will show you what happens when using clip-path on it’s own (remember the image footprint?).

Before

.coffee--left {
width: 65%;
float: left;
background: green;
}

Just using clip-path

.coffee-left {
width: 65%;
float: left;
background: green;
clip-path: ellipse();
}

After: shape-outside + clip-path

.coffee-left {
width: 65%;
float: left;
clip-path: ellipse();
shape-outside: ellipse();
}

Polygon()

This one is my favourite! It allows you to define a set of coordinates (using either pixels or percentage values), and when these coordinates are connected, it will create your custom shape.

Again, the clip-path and shape-outside properties work exactly the same as before, only that this time when we call the polygon() function, we can input coordinates inside the brackets.

Below is a great diagram that shows the main (x) and cross (y) axis. The top-left corner is (0%,0%), top-right is (100%,0%), bottom-right is (100%,100%), and bottom-left(0%, 100%)

clip-path: polygon(0% 0%, 70% 0%, 70% 25%, 100% 55%, 100% 100%, 0% 100%);
shape-outside: polygon(0% 0%, 70% 0%, 70% 25%, 100% 55%, 100% 100%, 0% 100%);

You’ll notice the x and y coordinate pairs are separated by commas, and NOT the individual x and y coordinates.

For example, by defining a set of coordinates, I have created paths around each wine bottle to make the text flow appear to be a wine glass, with the CSS shown below.

.wine — left {
float: left;
clip-path: polygon(0% 0%, 70% 0%, 70% 25%, 100% 55%, 100% 100%, 0% 100%);
shape-outside: polygon(0% 0%, 70% 0%, 70% 25%, 100% 55%, 100% 100%, 0% 100%);
}
.wine — right {
float: right;
clip-path: polygon(30% 0%, 100% 0%, 100% 100%, 0% 100%, 0% 50%, 25% 25%);
shape-outside: polygon(30% 0%, 100% 0%, 100% 100%, 0% 100%, 0% 50%, 25% 25%);
}

If you’d like to get more technical and test your knowledge, here is an example of a path around a minion.

Before

.myMinion {
width: 60%;
float: right;
background: orange;
}

After

.myMinion {
width: 60%;
float: right;
background: orange;
clip-path: polygon(29% 10%, 61% 0%, 72% 10%, 74% 33%, 94% 28%, 92% 48%, 86% 47%, 75% 56%, 65% 93%, 52% 93%, 52% 86%, 38% 87%, 25% 89%, 17% 76%, 25% 67%, 28% 53%, 10% 30%, 24% 24%);
shape-outside: polygon(29% 10%, 61% 0%, 72% 10%, 74% 33%, 94% 28%, 92% 48%, 86% 47%, 75% 56%, 65% 93%, 52% 93%, 52% 86%, 38% 87%, 25% 89%, 17% 76%, 25% 67%, 28% 53%, 10% 30%, 24% 24%);
}

A good practice is to define the clip-path and shape-outside properties in your text editor first, then go to the webpage and use the developer tools to define the path. This way you can get instant feedback on the coordinates you enter, making the process that much easier.

The best way to really test your knowledge to see if you really understand this concept is to practice! Pick an image, float it in one direction, throw a background colour on the image, mock up some lorem ipsum on the page, and get to clipping!


If you liked this article, please hit the ❤ button to recommend it. This will help other Medium users find it.

Find me on Facebook at Nick & Code and on Twitter at @nickevansmedia.