We always find rectangles inside rectangles in our common website layouts. 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.
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.
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.
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.
Shapes can be created using one of the following functions:
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:
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.