Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS update: overview of shapes guide #33771

Merged
merged 6 commits into from
May 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 30 additions & 28 deletions files/en-us/web/css/css_shapes/overview_of_shapes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,46 @@ page-type: guide

{{CSSRef}}

The [CSS Shapes Level 1 Specification](https://www.w3.org/TR/css-shapes/) describes geometric shapes in CSS. They are, in Level 1 of the specification, designed to be applied to floated items. This article provides an overview of what you can do with shapes.
The [CSS Shapes module](/en-US/docs/Web/CSS/CSS_shapes) describes geometric shapes in CSS. This article provides an overview of how you can use shapes to wrap text around floated elements that are not necessarily rectangular.

You could for example float an item left, which would cause the text to wrap round the right and bottom of the item in a rectangular fashion. If you then apply a circle shape, the text would then wrap round the line of the circle.
When you float an item left, text will wrap around the right and bottom of the item in a rectangular fashion. With CSS shapes you can, for example, apply a circle shape, and the text will wrap around the line of the circle.

There are a number of ways to create these Shapes and in these guides we will find out how CSS Shapes work, and consider some ways you might like to use them.
There are several ways to create this circle. In this guide, we will look at how CSS Shapes work and how to use them.

## What does the specification define?

The specification defines three new properties:
The specification defines a few properties, including:

- {{cssxref("shape-outside")}} — allows definition of basic shapes
- {{cssxref("shape-image-threshold")}} — Sets an opacity threshold value. If an image is being used to define the shape, only the parts of the image that are the same opacity or greater than the threshold value are used in the shape. Any other parts are ignored.
- {{cssxref("shape-margin")}} — sets a margin around the defined shape
- {{cssxref("shape-outside")}} — Allows definition of basic shapes.
- {{cssxref("shape-image-threshold")}} — Sets an opacity threshold value. If an image is being used to define a shape, only the parts of the image that are the same opacity or greater than the threshold value are used in the shape. Any other parts are ignored.
- {{cssxref("shape-margin")}} — Sets a margin around the defined shape.

## Defining basic shapes

The `shape-outside` property allows us to a define a shape. It takes a variety of values, all of which define different shapes, specified in the {{cssxref("<basic-shape>")}} datatype. We can start by looking at a very simple case.
The `shape-outside` property allows us to define a shape. It takes a variety of values that define different shapes specified in the {{cssxref("<basic-shape>")}} data type.

In the following example I have an image floated left. I have then applied the `shape-outside` property to it with a value of `circle(50%)`. The result is that the content now curves around the circular shape rather than following the rectangle created by the box of the image.
In the following example, an image is floated to the left. We apply the `shape-outside` property with a `circle(50%)` value. The result is that the content now curves around the circular shape rather than following the rectangle created by the box of the image.

{{EmbedGHLiveSample("css-examples/shapes/overview/circle.html", '100%', 720)}}

As in this level of the specification an element has to be floated in order to apply `<basic-shape>` to it; this has the side-effect of creating a simple fallback for many cases. If you do not have Shapes support in the browser, the user will see content flowing around the sides of a rectangular box as before. If they do have Shapes support then the visual display is enhanced.
Here we used the {{cssxref("basic-shape/circle", "circle()")}} function, which is supported across all modern browsers. If we used a newer shape type that doesn't have full support, users of non-supporting browsers would see the content flowing around the sides of a rectangular, due to the image being floated. Shapes are a visual progressive enhancement.

### Basic shapes

The value `circle(50%)` is an example of a basic shape. The specification defines four `<basic-shape>` values, which are:
The value `circle(50%)` is an example of a basic shape. The specification defines several `<basic-shape>` values, including:

- `inset()`
- `circle()`
- `ellipse()`
- `polygon()`
- {{cssxref("basic-shape/circle","circle()")}}
- {{cssxref("basic-shape/ellipse","ellipse()")}}
- {{cssxref("basic-shape/inset","inset()")}}
- {{cssxref("basic-shape/path","path()")}}
- {{cssxref("basic-shape/polygon","polygon()")}}
- {{cssxref("basic-shape/rect","rect()")}}
- {{cssxref("basic-shape/shape","shape()")}}
- {{cssxref("basic-shape/xywh","xywh()")}}

Using the value `inset()` wraps text around a rectangular shape however you are able to add offset values, thus pulling the line boxes of any wrapping content closer to the object than would otherwise happen.
Three of these functions only define rectangles. With the `inset()` function, you define four offset values, thus pulling the line boxes of any wrapping content closer to the object than they otherwise would. The `rect()` function defines a rectangle by specifying the distance from the top and left edges of the containing block. The `xywh()` function works by specifying distances from the top and left edges of the reference box and setting the width and height of the rectangle from that starting point.

We have already seen how `circle()` creates a circular shape. An `ellipse()` is essentially a squashed circle. If none of these simple shapes do the trick you can create a `polygon()` and make the shape as complex as you want.
We have already seen how `circle()` creates a circular shape. An `ellipse()` is essentially a squashed circle. If none of these simple shapes do the trick you can create more complex shapes using the `polygon()` function, which allows the definition of a series of lines. The `path()` and `shape()` functions can be used to create ANY shape via a series of line, curve, and move commands.

In our [Guide to Basic Shapes](/en-US/docs/Web/CSS/CSS_shapes/Basic_shapes) we explore each of the possible Basic Shapes and how to create them.

Expand All @@ -62,7 +66,7 @@ To explore the box values in more detail, see our guide covering [Shapes from bo

### Shapes from images

An interesting way to generate your path is to use an image with an alpha channelthe text will then wrap around the non-transparent parts of the image. This allows the overlay of wrapped content around an image, or the use of an image which is never displayed on the page purely as a method of creating a complex shape without needing to carefully map a polygon.
An interesting way to generate your path is to use an image with an alpha channelthe text will then wrap around the non-transparent parts of the image. This allows the overlay of wrapped content around an image or the use of an image that is never displayed on the page purely as a method of creating a complex shape without needing to carefully map a polygon.

Note that images used in this way must be [CORS compatible](/en-US/docs/Web/HTTP/CORS), otherwise `shape-outside` will act as if `none` had been given as the value, and you will get no shape.

Expand All @@ -78,7 +82,7 @@ You can see the threshold in action if we use a gradient as the image on which t

{{EmbedGHLiveSample("css-examples/shapes/overview/threshold.html", '100%', 820)}}

We take a deeper look at creating shapes from images in the [Shapes from Images](/en-US/docs/Web/CSS/CSS_shapes/Shapes_from_images) guide.
To learn more about creating shapes from images, see the [Shapes from images](/en-US/docs/Web/CSS/CSS_shapes/Shapes_from_images) guide.

## The `shape-margin` property

Expand All @@ -90,26 +94,24 @@ In the example below we have added a `shape-margin` to a basic shape. Change the

## Using Generated Content as the floated item

In the examples above, we have used images or a visible element to define the shape, meaning that you can see the shape on the page. Instead, you might want to cause some text to flow along a non-rectangular invisible line. You can do this with Shapes, however you will still need a floated item, which you can then make invisible. That could be a redundant element inserted into the document, an empty {{htmlelement("div")}} or {{htmlelement("span")}} perhaps, but our preference is to use generated content. This means we can keep things used for styling inside the CSS.
In the examples above, we have used images or a visible element to define the shape, meaning that you can see the shape on the page. Instead, you might want to flow some text along a non-rectangular invisible line. We could, for example, add an empty floated {{htmlelement("div")}} or {{htmlelement("span")}} element to our DOM and make it invisible. However, we can create a shape with only CSS using [generated content](/en-US/docs/Learn/CSS/Howto/Generated_content) and keep all our styling functionality inside the CSS.

In this next example, we use generated content to insert an element with height and width of 150px. We can then use Basic Shapes, Box Values or even the Alpha Channel of an image to create a shape for the text to wrap around.
In this example, we use generated content to insert an element with a height and width of 150px. We can then use basic Sshapes, box values, or even the alpha channel of an image to create a shape for the text to wrap around.

{{EmbedGHLiveSample("css-examples/shapes/overview/generated-content.html", '100%', 850)}}

## Relationship to `clip-path`

The Basic Shapes and Box values used to create Shapes are the same as those used as values for {{cssxref("clip-path")}}. Therefore if you want to create a shape using an image, and also clip away part of that image, you can use the same values.
The basic shapes and box values used to create shapes are the same as those used as values for {{cssxref("clip-path")}}. Therefore, if you want to create a shape using an image, and also clip away part of that image, you can use the same values.

The image below is a square image with a blue background. We have defined a shape using `shape-outside: ellipse(40% 50%);` and also used `clip-path: ellipse(40% 50%);` to clip away the same area that we have used to define the shape.
The image below is a square image with a blue background. We have defined a shape using `shape-outside: ellipse(40% 50%);` and also used `clip-path: ellipse(40% 50%);` to clip away the same area that we used to define the shape.

{{EmbedGHLiveSample("css-examples/shapes/overview/clip-path.html", '100%', 800)}}

## Developer Tools for Shapes

Along with CSS Shapes support in the browser, Firefox are shipping a [Shape Path Editor](https://firefox-source-docs.mozilla.org/devtools-user/page_inspector/how_to/edit_css_shapes/index.html) in the Firefox DevTools. This tool means that you can inspect any shapes on your page, and even change the values in the live page. If your polygon isn't quite right you can use the Shapes Editor to tweak it, then copy the new value back into your CSS.
There is a [Shape Path Editor](https://firefox-source-docs.mozilla.org/devtools-user/page_inspector/how_to/edit_css_shapes/index.html) in the Firefox DevTools. This tool can be used to inspect the `circle()`, `inset()`, `ellipse()`, and `polygon()` values. If your polygon isn't quite right you can use the Shapes Editor to tweak it, then copy the new value back into your CSS.

The Shape Path Editor will be enabled by default in Firefox 60 for shapes generated via `clip-path`. You can also use it to edit shapes generated via `shape-outside`, but only when you enable it via the `layout.css.shape-outside.enabled` pref.
## More CSS Shapes Features

## Future CSS Shapes Features

The initial Shapes specification included a property `shape-inside` for creating shapes inside an element. This property, along with the possibility of creating shapes on non-floated elements, has been moved to [level 2](https://drafts.csswg.org/css-shapes-2/) of the specification. As the `shape-inside` property was initially in Level 1 of the specification, you may find tutorials on the web detailing both properties.
In this guide, we discussed wrapping text around floated shapes. See the [CSS shapes module](/en-US/docs/Web/CSS/CSS_shapes) for links to all the module features plus additional related features. This includes all the shape functions and relevant guides.