CSS Shapes Module Level 2

Status: ED
Work Status: Exploring
Shortname: css-shapes
Level: 2
Group: csswg
TR: http://www.w3.org/TR/css-shapes-2/
ED: http://dev.w3.org/csswg/css-shapes-2/
Editor: Rossen Atanassov, Microsoft Corporation, ratan@microsoft.com
Editor: Alan Stearns, Adobe Systems, Inc., stearns@adobe.com
!Issues list: In Bugzilla
Abstract: This draft contains the features of CSS relating to wrapping content around and inside shapes. It (implicitly for now) includes and extends the functionality of CSS Shapes Level 1 [[CSS-SHAPES]]. The main points of extension compared to level 1 include additional ways of defining shapes, defining an exclusion area using a shape, and restricting an element's content area using a shape.
Link Defaults: css21 (property) margin, css-display-3 (value) table

Introduction

This section is not normative. Level 1 of this specification defined properties to control the geometry of an element's float area. This level defines how shapes apply to exclusions. It also includes a 'shape-inside' property for applying a shape to an element's content area. And finally it defines new ways of specifying shapes for all of these applications.

Terminology

Exclusion area The area used for excluding inline flow content around an exclusion box. The exclusion area is equivalent to the border box for an exclusion box. This specification's 'shape-outside' property can be used to define arbitrary, non-rectangular exclusion areas. The 'shape-inside' property also defines an exclusion area, but in this case it is the area outside the shape that inline content avoids. Float area The area used for wrapping content around a float element. By default, the float area is the float element's margin box. This specification's 'shape-outside' property can be used to define arbitrary, non-rectangular float areas. Content area The content area is normally used for layout of the inline flow content of a box.
Issue-15089

shrink-to-fit circle / shape

Shapes

Shapes define arbitrary geometric contours around which inline content flows. The shape-outside property defines the float area for a float, and the exclusion area for an exclusion.

Basic Shapes

Add the final level 1 section.

Supported Shapes

Add the final level 1 section, with the following integrated.
path() = path( [<>,]? <> )
Issue-16448

Should we revisit the decision to not allow SVG path syntax in the shape-inside, shape-outside properties

Referencing SVG shapes

An SVG shape can be referenced using the url() syntax. The shape can be any of the SVG basic shapes or a path element.
results of referencing SVG shapes
<style>
div {
	height: 400px;
	width: 400px;
}
.in-a-circle {
	shape-outside: url(#circle_shape);
}

.in-a-path {
	shape-outside: url(#path-shape);
}

</style>

<svg ...>
<circle id="circle_shape" cx="50%" cy="50%" r="50%" />
<path id="path-shape" d="M 100 100 L 300 100 L 200 300 z" />
</svg>

<div class="around-a-circle">...</div>
<div class="around-a-path">...</div>

Shapes from Image

Add the final level 1 section. Issue: One suggestion is to define a shape based on an element's rendered content. This could have security implications. Issue: Another suggestion is to add something to an image() function that determines the relevant pixels to use (both for defining a shape and for display).

Shapes from Box Values

Add the final level 1 section.

Declaring Shapes

A shape can be declared with the 'shape-outside' property, with possible modifications from the 'shape-margin' property. The shape defined by the 'shape-outside' and 'shape-margin' properties changes the geometry of a float element's float area and an exclusion element's exclusion area. A shape can be declared with the 'shape-inside' property, with possible modifications from the 'shape-padding' property. The shape defined by the 'shape-inside' and 'shape-padding' properties defines an exclusion area that contributes to the element's wrapping context. The 'shape-inside' property applies to all block-level elements.
The red box illustrates an exclusion element's content box, which is unmodified and subject to normal CSS positioning (here absolute positioning).

	<style type="text/css">
	.exclusion	{
			wrap-flow: both;
			position: absolute;
			top: 25%;
			left: 25%;
			width: 50%;
			height: 50%;
			shape-outside: circle(50% at 50% 50%);
			border: 1px solid red;
	}
	</style>

	<div style=”position: relative;”>
	<div class=”exclusion”></div>
	Lorem ipsum dolor sit amet...
	</div>
	
Example rendering of circle shape and box model.

The 'shape-outside' Property

Add the final level 1 section with the change that shape-outside applies to block-level elements and has an effect if the element is an exclusion.

The 'shape-inside' Property

The 'shape-inside' property adds one or more exclusion areas to the element's wrapping context. This modifies the normal rectangular shape of the content area to a possibly non-rectangular wrapping area. The exclusion areas are defined by subtracting the shape from the element's content area. Any part of the shape outside the element's content area has no effect.
		Name: shape-inside
		Value: auto | outside-shape | [ <> || shape-box ] | <> | display
		Initial: auto
		Applies To: block-level elements
		Inherited: no
		Computed Value: computed lengths for <>, the absolute URI for <>, otherwise as specified
		Media: visual
		Animatable: as specified for <>, otherwise no
	
The values of this property have the following meanings:
''auto''
The shape is computed based on the content box of the element.
''outside-shape''
The shape is computed based on the shape defined by the shape-outside and shape-margin properties.
<basic-shape>
The shape is computed based on the values of one of ''inset()'', ''circle()'', ''ellipse()'' or ''polygon()''.
<uri>
If the <uri> references an SVG shape element, that element defines the shape. Otherwise, if the <uri> references an image, the shape is extracted and computed based on the alpha channel of the specified image. If the <uri> does not reference an SVG shape element or an image, the effect is as if the value ''auto'' had been specified.
''display''
The shape is computed based on the shape of the display as described in css-round-display.
The 'shape-inside' property applies to floats. The 'shape-inside' property may not apply on some elements such as elements with a computed 'display' value of ''display/table''.
Content flowing with and without a shape-inside

Effect of shape-inside on inline content.

Overflow content avoids the exclusion area(s) added by 'shape-inside' and 'shape-padding' (as well as any other exclusion areas in the element's wrapping context). In other words, overflow continues outside the rectangular bounds of the element.

Overflow interacting with rounded rect Overflow interacting with ellipse

Overflow interacting with exclusion areas defined by 'shape-inside' and 'shape-padding'.

Issue: improve the illustration above, using text to show overflow instead of greeked boxes. When a shape-inside has a definite size (no percentages used in the shape's definition) an auto-sized element should use the shape as a constraint in determining its maximum size.

The shape-image-threshold Property

Add the final level 1 section with the change that it applies to both shape-inside and shape-outside.

The shape-image-source-type Property

Should we add an alpha/luminance switch to determine which values we use from the shape-image source? This could just be a keyword on the shape-image-threshold property. Whatever we go with should be compatible with the alpha/luminance switch from mask sources.

The 'shape-margin' property

Add the final level 1 section with the change that it applies to exclusions.

The 'shape-padding' Property

The 'shape-padding' property adds padding to a shape-inside. This defines a new shape where every point is the specified distance from the shape-inside. This property takes on positive values only.
		Name: shape-padding
		Value: <>
		Initial: none
		Applies To: block-level elements
		Inherited: no
		Computed Value: the absolute length
		Media: visual
		Animatable: as length, percentage, or calc
	

A 'shape-padding' creating an offset from a circlular shape-inside. The light blue rectangles represent inline content affected by the shape created by the padding.

Example of a shape-padding offset
Note: The 'shape-padding' property only affects layout of content inside the element it applies to while the 'shape-margin' property only affects layout of content outside the element.