CSS Shapes 101

Rectangles inside other rectangles: this is what our webpages have always been made of. We’ve long tried to break free from their restrictions by using CSS to create geometric shapes, but those shapes have never affected the content inside the shaped element, or how the element is seen by other elements on the page.

Article Continues Below

The new CSS Shapes specification is changing that. Introduced by Adobe in mid-2012, its goal is to provide web designers with a new way to change how the content flows inside and around arbitrarily complex shapes—something we’ve never been able to do before, not even with JavaScript.

For example, notice how the text flows around the circular images in the following design. Without Shapes, the text would be rectangular—throwing off the sophisticated touch that takes the design to the next level.

Image of a magazine layout with text wrapped around circular shaped images.
Notice how the text wraps around the circular shape of a bowl in this example. Using CSS Shapes, we can create similar designs for the web.

Let’s walk through how Shapes work, and how you can start using them.

Browser support#section1

CSS Shapes are currently supported only in Webkit Nightly and Chrome Canary, but its Module Level 1 has reached the Candidate Recommendation status, so the properties and syntax defined in the spec are pretty stable. It won’t be long before they’re implemented in other browsers. This level focuses on the Shapes properties that change the flow of content around a shape. More specifically, it focuses on the shape-outside property and its related properties.

Combined with other cutting-edge features such as Clipping and Masking, CSS Filters, and Compositing and Blending, CSS Shapes will allow us to create more polished and sophisticated designs without having to resort to graphics editors like Photoshop or InDesign.

Future levels of CSS Shapes will focus on wrapping content inside a shape as well. For example, today it’s easy to create a rhombic shape in CSS: just rotate the element by 45 degrees, and then rotate the content inside it back so that it lies horizontally on the page. But the content inside the rhombus won’t be affected by the rhombic shape of its container, and will always remain rectangular. When the CSS Shapes shape-inside property is implemented, we will be able to make the content also become rhombic, making layouts like the one shown in the following image very much possible.

Image of a magazine layout using rhombic shapes.
Soon, CSS Shapes will also allow text inside shapes, like these rhombuses, to adjust to the edges of its container, rather than overflow or get cut off.

In order to use CSS Shapes in Chrome Canary today, you have to enable the experimental features flag. If you’re not sure how to do that, have a look at this walkthrough on the Adobe blog.

Creating a CSS Shape#section2

You can apply a shape to an element using one of the Shapes properties. You pass the shape property a shape function as a value. The shape function is where you pass in arguments that define the shape that you want to apply to the element.

Illustration showing different parts making up a shape rule.

Shapes can be created using one of the following functions:

  • circle()
  • ellipse()
  • inset()
  • polygon()

Each shape is defined by a set of points. Some functions take points as parameters; others take offsets—but they all eventually draw the shapes as a set of points on the element. We’ll cover the parameters for each of these functions in the examples we’re going to create.

A shape can also be defined by extracting it from an image with an alpha channel. When an image is passed to a shape property, the browser then extracts the shape from the image based on a shape-image-threshold. The shape is defined by the pixels whose alpha value is greater than the threshold. The image must be CORS compatible. If the image provided cannot be displayed for any reason (such as if it doesn’t exist), then no shape will be applied.

The shape properties that accept the above functions as values are:

  • shape-outside: Wraps content around (outside) a shape
  • shape-inside: Wraps content inside a shape

You can use the shape-outside property in conjunction with the shape-margin property to add a margin around the shape that pushes the flowing content away from the shape, creating more room between it and the content. Just like shape-outside gets a shape-margin property, shape-inside gets a shape-padding property, which adds inner padding.

Using the shape properties and functions, declaring a shape on an element can be as easy as adding one line of CSS to it:

.element {
	shape-outside: circle(); /* content will flow around the circle defined on the element */
}

Or:

.element {
	shape-outside: url(path/to/image-with-shape.png);
}

But…

If you apply that line of CSS to your element, the shape won’t be applied to it unless two conditions are met:

  1. The element must be floated. Future levels of CSS Shapes may allow us to define shapes on non-floated elements, but not yet.
  2. The element must have intrinsic dimensions. The height and width set on an element will be used to establish a coordinate system on that element.

As you have seen in the function definitions above, the shapes are defined by sets of points. Because these points have coordinates, a coordinate system is necessary for the browser to know where to position each point on the element. So, the above example would work if it included something like:

.element {
	float: left;
	height: 10em;
	width: 15em;
	shape-outside: circle();
}

Giving an element intrinsic dimensions does not, however, affect its responsiveness (we’ll talk more about that later).

Since each shape is defined by a set of points positioned using a pair of coordinates, changing the coordinates of a point will directly affect the shape created. For example, the following image shows a hexagonal shape that can be created using the polygon() function. The shape is made up of six points. Changing the horizontal coordinate of the point in orange will change the resulting shape, and will affect the flow of content inside and/or outside any element this shape is applied to.

Image showing the result of changing the coordinate of a point on the created shape.
If the element is floated to the right and has this shape applied to it, the content on its left will change its flow when the coordinate of the orange point is changed inside the polygon() function.

A Shape’s reference box#section3

CSS Shapes are defined and created inside a reference box, which is the box used to draw the shape on the element. In addition to the element’s height and width, the element’s box model boxes—margin box, content box, padding box, and border box—are also used as a reference to specify the extent of the shape on an element.

By default, the margin box is used as a reference—so, if an element you want to apply a shape to has a margin at the bottom, the shape you define on the element will extend to the edges of the margin area, not the element’s border area. If you want to use one of the other box values, you can specify it in conjunction with the shape function that you pass to the shape properties:

shape-outside: circle(250px at 50% 50%) padding-box;

The padding-box keyword in the above rule specifies that the shape is going to be applied and restricted to the padding box (padding area) of the element. The circle() function defines a circular shape, its size, and position on the element.

Defining Shapes using shape functions#section4

We’ll start by wrapping some information around a circular user avatar picture, like you might use to display a user profile or a testimonial.

Screenshot showing a user profile picture with text flowing around its circular boundaries.
Using CSS Shapes, text around a circular user profile image wraps to the shape, instead of staying rectangular.

We’ll use the circle() function to apply a circular shape to the profile image, using the following markup:

<img src="http://api.randomuser.me/0.3.2/portraits/men/7.jpg" alt="profile image" />

<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum itaque nam blanditiis eveniet enim eligendi quae adipisci?</p>

<p>Assumenda blanditiis voluptas tempore porro quibusdam beatae deleniti quod asperiores sapiente dolorem error! Quo nam quasi soluta reprehenderit laudantium optio ipsam ducimus consequatur enim fuga quibusdam mollitia nesciunt modi.</p>

You might ask, “Why not use border-radius to round the image?” The answer is that the border-radius property has no effect on the flow of the content inside or around the element it’s applied to—it does not affect the content area of the element, or the flow area of the content around the element. It only affects the borders of an element, and any backgrounds. The background area is clipped to the curved corners created by the property, but that’s it. The content inside the element will remain rectangular, and the content outside the element will still see and treat the element as if it were rectangular—because it is.

We are going to use the border-radius property to make the image circular—this is what we usually do to round images or other elements on a page:

img {
	float: left;
	width: 150px;
	height: 150px;
	border-radius: 50%;
	margin-right: 15px;
}
Screenshot showing how text would normally flow around an image without applying a CSS Shape to it.
Without CSS Shapes, the text sees the image as rectangular, and hence wraps around a rectangular shape, not a circular one.

In a browser that does not support CSS Shapes, the content around the circular image will flow around it as if it weren’t circular. This will be how the fallback will look in older browsers.

In order to change the flow of content to accommodate a certain shape, you use the shape properties.

img {
	float: left;
	width: 150px;
	height: 150px;
	border-radius: 50%;

	shape-outside: circle();
	shape-margin: 15px;
}

With this code, the text will “see” the circular shape applied to the image and wrap around it, as shown in the first screenshot. (You can see the result live here.) In non-supporting browsers it will fall back to the result shown in the second image.

You can use the circle() function as is, or by passing parameters to it. Its official syntax is:

circle() = circle( [<shape-radius>]? [at <position>]? )

The question marks indicate that these parameters are optional and can be omitted. If you omit one, that parameter is set to its default value by the browser. When you use circle() as is instead of explicitly setting its position, it will default to defining a circle that is positioned at the center of the element you’re applying it to.

You can specify the radius of the circle using any length unit (px, em, pt, etc.). You can also specify the radius using either closest-side or furthest-side, but closest-side is the default, which means the browser will use the length from the center of the element to its closest side as the length of the radius. farthest-side uses the length from the center to the farthest side.

shape-outside: circle(farthest-side at 25% 25%); /* defines a circle whose radius is half the length of the longest side, positioned at the point of coordinates 25% 25% on the element’s coordinate system*/

shape-inside: circle(250px at 500px 300px); /* defines a circle whose center is positioned at 500px horizontally and 300px vertically, with a radius of 250px */
Illustration showing a visual explanation of the closest-side and farthest-side values.

The ellipse() function works the same way as the circle() function, with the same list of values, except that instead of taking one radius parameter, it takes two: one for the length of the radius on the x-axis, and another for the y-axis.

ellipse() = ellipse( [<shape-radius>{2}]? [at <position>]? )

While not directly related to a circle or an ellipse, the inset() function is used to create rectangular shapes inside an element. Since elements are already rectangular, though, we don’t need it to make more rectangles. Instead, inset() can help us create rectangles with rounded corners that also have content flow around those corners.

Image showing text flow around an element with and without the inset() function applied to it.

The inset() function takes one to four offset values, which specify the offsets from the edges of the references box inward. These specify where the inset rectangle goes inside the element. The function also takes an optional parameter to round the corners of the inset rectangle. The rounded corners are specified exactly the same way as border-radius, using one to four values, in conjunction with the keyword round.

inset() = inset( offset{1,4} [round <border-radius>]? )

The following will create a rounded rectangle on a floated element.

.element {
	float: left;
	width: 250px;
	height: 150px;
	shape-outside: inset(0px round 100px) border-box;
}

Check the live example out here.

The last Shape function is the polygon(), which defines more complex arbitrary shapes using any number of points. The function takes in a set of coordinate pairs, each pair specifying the position of a point. The set of points make up the shape.

In the following example, an image floated to the right takes up the entire height of the screen using viewport units. We want to flow the text on the left around the hourglass inside the image, so we use the polygon() function to define an irregular shape on the image.

Screenshot showing the result of applying the polygon() function to define a shape on an image and have content wrap around that shape.

The CSS for the above image looks like this:

img.right {
	float: right;
	height: 100vh;
	width: calc(100vh + 100vh/4);
	shape-outside: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%);
}

You can set the coordinates of the points defining the shape in length units or percentages, as I have here.

This code alone will produce the the above result, but as you can see, the shape function does not affect the remaining parts of the image outside the defined shape. As a matter of fact, applying a shape function to an element—whether an image, a container, or something in between—will not affect anything except the content flow area. Backgrounds, borders, and everything else remain unchanged.

In order to visualize the shape of the polygon we created, we need to “clip out” the parts of the image outside the shape. This is where the clip-path property from the CSS Masking Module can help.

The clip-path property takes the same shape functions and values as the shape properties. If we pass the same polygonal shape we used in the shape-outside property to the clip-path property, it will clip all the parts of the image that are outside the defined shape.

img.right {
	float: right;
	height: 100vh;
	width: calc(100vh + 100vh/4);
	shape-outside: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%);
	/* clip the image to the defined shape */
	clip-path: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%);
}

The result looks like this:

Screenshot showing the result of applying the clip-path property to a shaped element to clip out excess parts of the image outside the defined shape.

The clip-path property is supported with prefixes at this time, so it will work in Chrome with the -webkit- prefix added to the clip-path property. You can check the live demo out here.

The clip-path property is an excellent companion to the shape properties, as it helps visualize the created shapes and clip out any parts of the element that are outside the defined shapes, so you will probably find yourself using it a lot in conjunction with the Shapes properties.

The polygon() function also takes in an optional fill keyword, which can be either nonzero or evenodd. This specifies how to treat areas inside the polygonal shape that may intersect itself. See the SVG fill-rule property for details.

Defining a shape using an image#section5

To define a shape using an image, the image needs an alpha channel from which the browser can extract the shape.

A shape is defined by the pixels whose alpha value is greater than a certain threshold. That threshold defaults to a value of 0.0 (fully transparent), or you can set it explicitly using the shape-image-threshold property. So, any pixel that is not transparent will be used as part of the shape defined from the image.

A future level of CSS Shapes may define a switch to use the luminance data from an image instead of the alpha data. If this happens, shape-image-threshold will be extended to apply its threshold to either alpha or luminance, depending on the switch state.

We’re going to use the following image to define a shape on an element and have text wrap around it:

Using the shape-outside property with the url() value pointing to this image, we can flow the content around an element with this leaf shape.

.leaf-shaped-element {
	float: left;
	width: 400px;
	height: 400px;
	shape-outside: url(leaf.png);
	shape-margin: 15px;
	shape-image-threshold: 0.5;
	background: #009966 url(path/to/background-image.jpg);
	mask-image: url(leaf.png);
}

Of course, if you were to apply a background to the element, the background would need to be clipped outside the defined shape. The mask-image property (with appropriate prefixes) from the Masking Module can do that, since the clip-path property doesn’t take an alpha image as a value. The result looks like this:

Screenshot showing text wrapped around a shape extracted from an image with an alpha channel.

If you’re creating complex shapes, you might want to define a shape using an image. This allows you to use an alpha channel image in Photoshop instead of manually defining the points.

You will also want to use an image instead of a shape function when you have multiple float or exclusion areas inside an element—because you can’t, for now, declare multiple shapes on an element. But if the image contains multiple areas, the browser will extract these areas from the image and use them.

CSS Shapes in responsive design#section6

Can CSS Shapes fit into our responsive workflows? The current specification for shape-outside has this covered, because it allows you to specify the dimensions of the element in either percentages or other length units, and the points defining the shape (parameters of the shape functions) can also be set in percentages. This means that an element with a shape-outside would be fully responsive, just like any other float with percentage dimensions.

shape-inside is not as responsive yet, but that’s because it has been pushed to Module Level 2. Many of its current limitations will be resolved in the next level.

Shape tools#section7

Creating complex shapes using Shapes functions can be a daunting task, especially if you’re creating one with many points and coordinates using polygon(). Thankfully, Adobe’s web platform team has been working on interactive tooling that makes this much easier. Bear Travis has created a collection of Shape Tools that allow us to create polygonal shapes visually. The tool then generates the shape function for us. This is useful, but it can be limited if you want to create a shape based on a specific image, because there is no way for you to insert the image into the tool and then create the shape for it.

A more advanced and interactive Shapes tool has been developed by the Adobe Web Platform team. The tool has been recently released as an extension for Adobe’s free Brackets editor. It allows you to visualize and edit shapes directly in the browser, and has a live preview feature that updates the shape values in the stylesheet as you change them on the page. This gives you instant visual feedback for your changes, allowing you to see how your shapes interact with other elements on the page.

Screen capture showing how the new Shapes Editor can be used to edit Shapes right in the browser.
Editing a polygonal shape right in the browser using Brackets’ live preview mode. Screen capture courtesy of Razvan Caliman.

This tool will be indispensable because it facilitates creating, editing, and debugging our shapes. Razvan Caliman has written an article on the Brackets blog explaining how you can get the Shapes editor in Brackets and start using it today.

The future: CSS Exclusions#section8

The CSS Shapes specification used to be the CSS Shapes and Exclusions spec, but the two specs were separated. While CSS Shapes defines the shape-inside and shape-outside properties, CSS Exclusions will define properties that allow us to wrap content around elements that are not floated, such as absolutely positioned elements. This will make it possible to make content wrap the entire shape from different sides, as shown in the following image.

Screenshot of a magazine layout with text wrapped around a pullquote.
In the future, CSS Exclusions will allow us to wrap text around a shape like a pullquote, as shown in this magazine layout. The pullquote can also be circular, and the text would wrap around it just as well. Image by Justin Thomas Kay.

Similar layouts with shaped elements positioned absolutely at the center of an article—with text flowing around the element on all sides—will also be possible.

Taking Shapes further#section9

The current CSS Shapes specification is merely the first step. Soon, new options will give us more control over creating shapes and wrapping content in and around them, making it a lot easier for us to turn our mockups into live designs with just a few lines of code. Today, spec editors are focused on shipping shape-outside, and you’ll likely see CSS Shapes in more browsers by the end of 2014.

You can use Shapes today as part of a progressive enhancement workflow, knowing they have acceptable fallbacks in non-supporting browsers. I’ve recently started applying them to my own website, and the fallback is very “normal.” For more complex designs, you can use a script to check whether a browser supports Shapes, and provide any fallback you want if it doesn’t. You can also extend Modernizr’s tests with this script to test whether shape-outside is supported, or download a custom build including this test.

CSS Shapes allow us to bridge one more gap between print and web design. The examples in this article are simple, but should give you a foundation for creating designs as complex as any magazine or poster—without having to worry whether you’ll be able to recreate it on-screen. Whatever you explore—from non-rectangular layouts to animating Shapes—the time to experiment is now.

About the Author

Sara Soueidan

Sara Soueidan is a freelance front-end web developer from Lebanon. She loves teaching, and writes tutorials on her blog and on Codrops, where she's an author and team member. You can find her on Twitter and Github.

55 Reader Comments

  1. I always thought CSS shapes were too confusing and therefore not going to be successful but your example with the leaf and using an image as a shape is convincing this is the future of web design. Awesome article!

  2. This looks incredibly powerful, but as with all new features, I fear abuse. I fear the day polygonal, animated ads actually roll through an article as I read it…

    Either way, this looks badass and I’m looking forward to playing with and digging through the code of amazing new interfaces using shapes 🙂

  3. @nathanhammond

    Thank you for your comment and for the resource you linked to, nicely done!

    The text-inside-shape I was referring to in the article is the CSS version of it, namely using `shape-inside`. It was supported up until recently when it was pulled out from webkit browsers so that the guys working on the spec can focus more on the `shape-outside` which is now a candidate recommendation. Text inside shapes has been pushed to a future level of the spec, that’s why it’s currently not supported.

    Of course, as you have shown, we can do similar things with SVG combined with Javascript, but isn’t it much simpler, easier, and faster to do it with CSS? =) Hopefully, some time in the future we will.

    Cheers!

  4. @ Michael Mullany

    Transforms don’t affect the flow of content inside or around the transformed element at all. So, no, rotating the element (be it shaped with CSS Shapes or not) will not affect the way the text wraps around it.

    Cheers! 🙂

  5. @ Jason Edelman

    With great power comes great responsibility, right? ^^ Many great CSS features can be abused, so it’s up to us to decide how and when it’s best suitable to use a certain feature (or not to). = )

  6. Just added this to a site I’m working on with lots of circular images. I realize 0.001% of users will see the text wrapping today, but it makes me happy for just 2 lines. No need for fall backs or (hopefully) future maintenance.

  7. CSS shapes are awesome and all that, but when is CSS going to make it easy to center text and other things vertically? Do the authors of CSS design sites? Do they hear all the wailing and gnashing of beginner designers? I wonder.

  8. This is great! For me these are completely new features of CSS and I need some time to learn all about this. Thank you for sharing.

  9. Great in depth article Sara, It is a very interesting time for shapes, some amazing looking sites should be appearing soon!

  10. Great article! I really inspire about your work. You have good knowledge of CSS design. My professional background also designing, like logo design for business and brand from our online network 10alogo. Your article very helpful for me. Thanks a lot Sara.

  11. You might ask, “Why not use border-radius to round the image?” The answer is that the border-radius property has no effect on the flow of the content inside or around the element it’s applied to

    This is not entirely accurate. You can use the new box model values (margin-box, border-box, padding-box etc) for shape-inside/outside to make it follow the curvature of the respective box. Demo: http://dabblet.com/gist/11558395

    Also, (some of?) your demos don’t work on newer Chrome because you’re using the older syntax for the shape parameters (even though the code here uses the newer syntax).

  12. @ Lea

    Thanks for your comment!
    I think I may not be getting your point exactly because it seems that what you’re saying does not negate what I said at all.
    The border-radius property has no effect on the flow of content inside and around the element, not even in your demo. Without `shape-outside: margin-box` in the dabblet you linked to, the content would not flow around the circle created with `border-radius`, and that was my point in the quote you wrote.
    1) border-radius: makes element circular but the content around the element still flows around a rectangle, and any content inside the element would also still be rectangular (remove shape-outside from your demo to see what I mean)
    2) shape-outside: of course you can use *only* the box model values as a value for shape-outside. So, yes, I could have left the circle() function out.

    re demos not working in Chrome:
    I think I added this note to my articles on my blog:
    Canary supports the new syntax and unprefixed properties. Webkit nightly supports the new syntax but with prefixes. The **old** syntax is there for stable Chrome, which currently still supports the old syntax because the new syntax hasn’t been shipped yet afaik. So I used it just so that someone using Chrome to view the demos (with experimental features flag enabled) can see the working demo without having to use Canary/Webkit Nightly.

    Also, some of the demos in my articles won’t work because they use `shape-inside` which has been pulled from all browsers at this time. That’s why I made sure screenshots are available to see how the demo looked like before and how it would look like once shape-inside is supported again.

    Let me know if I missed anything and thanks again for your comment! 😉

  13. I think I may not be getting your point exactly because it seems that what you’re saying does not negate what I said at all.

    I see what you mean upon re-reading it, however the article seems to imply that without the circle() function, border-radius does not affect flow at all, whereas you can make it do so by using the box model values (which is preferable when possible, as it eliminates duplication). Also, by using the margin-box value you avoid having to encode the margin in the shape-margin property, making the whole thing degrade more gracefully.
    So, to sum up, yes, there is technically nothing incorrect there, but that particular example would be better for demonstrating box model values, as using circle() is not ideal there. Same goes for the inset() example, using margin-box greatly simplifies the code (and makes it more DRY). Using shape functions there makes the author/reader wonder “Couldn’t there be a simpler way to just make the flow follow the element’s existing shape, that I defined through border-radius?” when in fact, there is (and it was added to the spec exactly to simplify such use cases!).

    The syntax is there for stable Chrome, which currently still supports the old syntax because the new syntax hasn’t been shipped yet afaik.

    I don’t understand why you wouldn’t use both, like so:

    shape-outside: circle(50%, 50%, 50%);
    shape-outside: circle(50% at 50% 50%);
  14. > the article seems to imply that without the circle() function, border-radius does not affect flow at all, whereas you can make it do so by using the box model values (which is preferable when possible, as it eliminates duplication).

    The article should imply that without the *shape properties*, border-radius has no effect on the flow at all. I guess I should have added that the box model values can be used as values without needing to specify a shape function, but this would only be true if the border-radius property is used because it creates a circular shape without having to redefine it using a shape function. But, again, that would only be true in case border-radius is used as in my example here.

    > I don’t understand why you wouldn’t use both, like so:
    shape-outside: circle(50%, 50%, 50%);
    shape-outside: circle(50% at 50% 50%);

    I edited my comment shortly after I posted it so you may have missed it. The “old” word wasn’t outputted (my bad). The code on my website *does* use the old and new syntax the way you mentioned! Old first, new second. (I think I just forgot to add the prefixes for Webkit Nightly, but regarding old and new, both are there.)

  15. I guess I should have added that the box model values can be used as values without needing to specify a shape function, but this would only be true if the border-radius property is used because it creates a circular shape without having to redefine it using a shape function. But, again, that would only be true in case border-radius is used as in my example here.

    Yup, and that in those cases it’s actually better to not use a shape function, as this way you are duplicating values (e.g. border radii). Also, since both the circle() and the inset() example don’t really need shape functions (since both use border-radius for the curvature), one is left wondering whether these functions are useful at all. So, an example that can’t be simplified with box model keywords would be preferable for demonstrating those. It doesn’t seem easy to come up with one though!

    The code on my website does use the old and new syntax the way you mentioned!

    I was talking about the codepens 🙂

  16. > So, an example that can’t be simplified with box model keywords would be preferable for demonstrating those.

    Good point! I guess creating a circular function on an element but not centering the circle is one option, or creating a circle with `closest-side` and `farthest-side` possibly on a non-square element maybe? But even in those cases you’re right, I think using box model keywords with margins/padding on the element could be enough!

    > I was talking about the codepens 🙂
    Okay so the Animating CSS Shapes article then? I’ll check on those asap, thanks for the heads up! =)

  17. Sorry if this was covered. I haven’t been through all the comments. I just tried this in Chrome Canary (JUST downloaded now for this) and I had an issue with the circle demo. Your codepen didn’t produce the pictured results. It showed the square edge of the circular image. When I played with it, this was what I used to get it to work:

    .shape{
    background-color: purple;
    float: left;
    width: 150px;
    height: 150px;
    border-radius: 50%;
    margin: 10px;

    shape-outside: circle();
    }

    shape-margin didn’t work, but regular margin did. Was this a recent change?

  18. fantastic. thank you for shedding light on this topic as i’ve always been curious about css shapes! keep up the great work sara 🙂

  19. @Kenneth Brøgger-Luplau

    Maybe that exact blockquote example isn’t the best to illustrate CSS Exclusions. Imagine the quote wrapping content from two adjacent columns and that would be a clearer use case.

    Your jsfiddle example is good, but it requires positioning of the floated element in the DOM, between two other paragraphs. A floated element will align to with the top edge of the element it is floated against. With CSS Shapes it’s possible to get that effect without the explicit DOM position – it’s a case for using `inset()`.

  20. Very detailed breakdown and explanation of the present and future of shapes with text and images. The examples have opened my mind to new approaches to how I present data within my projects. Thanks for taking the time to share this valuable info.

  21. Spectacular read. Very insightful and full of actionable items. One thing to always keep in mind – “responsive” and “mobile friendly” are not the same thing. This is why Google created the mobile friendly testing tool. SEO received a big shakeup when the search results changed due to mobile.

    At the end of the day, design should never be taken lightly. This is an excellent explanation.

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA

Nothing Fails Like Success

Our own @zeldman paints the complicated catch-22 that our free, democratized web has with our money-making capitalist roots. As creators, how do we untangle this web? #LetsFixThis