<pre class='metadata'>
Title: CSS Shapes Module Level 2
Status: ED
Work Status: Exploring
Shortname: css-shapes
Level: 2
Group: csswg
TR: https://www.w3.org/TR/css-shapes-2/
ED: https://drafts.csswg.org/css-shapes-2/
Editor: Rossen Atanassov, Microsoft Corporation, ratan@microsoft.com, w3cid 49885
Editor: Alan Stearns, Adobe Systems&#44; Inc., stearns@adobe.com, w3cid 46659
Editor: Noam Rosenthal, Google, w3cid 121539
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: css2 (property) margin, css-display-3 (value) table
Ignore MDN Failure: funcdef-basic-shape-path
Ignore MDN Failure: funcdef-basic-shape-circle
Ignore MDN Failure: funcdef-basic-shape-ellipse
Ignore MDN Failure: funcdef-basic-shape-inset
Ignore MDN Failure: funcdef-basic-shape-polygon
</pre>

<pre class='link-defaults'>
spec:css-masking-1; type: value
	text: nonzero
	text: evenodd
spec:css-shapes-1;
	type:property;
		text:shape-margin
		text:shape-outside
	type:dfn; text: reference box
	type:function; text: path()
spec:css-writing-modes-4; type:concept; text:physical
spec:css-writing-modes-4; type:concept; text:"writing mode"
spec:svg2; type:property;
	text:fill-rule
spec:css-values-5; type:value;
	text:top;
	text:right;
	text:bottom;
	text:left;
	text:center;
	text:x-start;
	text:y-start;
	text:x-end;
	text:y-end;
</pre>

<style type="text/css">
	.singleImgExample {
		display: block;
		margin: auto;
	}

	.example-table {
		table-layout: fixed;
		width: 100%;
	}

	.example-table tr td img {
		width: 90%;
	}
</style>


<h2 id="intro">
Introduction</h2>

	<em>This section is not normative.</em>

	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.
	Finally, it defines new ways of specifying shapes for all of these applications.

<h3 id="values">
Value Definitions</h3>

	This specification follows the <a href="https://www.w3.org/TR/CSS2/about.html#property-defs">CSS property definition conventions</a> from [[!CSS2]]
	using the <a href="https://www.w3.org/TR/css-values-3/#value-defs">value definition syntax</a> from [[!CSS-VALUES-3]].
	Value types not defined in this specification are defined in CSS Values &amp; Units [[!CSS-VALUES-3]].
	Combination with other CSS modules may expand the definitions of these value types.

	In addition to the property-specific values listed in their definitions,
	all properties defined in this specification
	also accept the [=CSS-wide keywords=] as their property value.
	For readability they have not been repeated explicitly.


<h2 id="terminology">
Terminology</h2>

	: <dfn>exclusion area</dfn>
	:: 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.

	: <dfn>float area</dfn>
	:: 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.

	: <dfn>content area</dfn>
	:: The [=content area=] is normally used for layout of the inline flow content of a box.


<h2 id="shapes">
Shapes</h2>

	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.


<h2 id="basic-shape-functions">
Basic Shapes</h2>

	Add the final
	<a href="https://www.w3.org/TR/css-shapes/#basic-shape-functions">level 1</a>
	section.

	This level extends the <<basic-shape>> functions
	to include ''shape()'':

	<pre class=prod>
		<<basic-shape>> = <<basic-shape-rect>> | <<circle()>> | <<ellipse()>> |  <<polygon()>> | <<path()>> | <<shape()>>
	</pre>

<h3 id="supported-basic-shapes">
Supported Shapes</h3>

	Add the final
	<a href="https://www.w3.org/TR/css-shapes/#basic-shape-functions">level 1</a>
	sections.

<h4 id='shape-function'>
The ''shape()'' Function</h4>

	Add the final
	<a href="https://drafts.csswg.org/css-shapes-1/#shape-function">level 1</a>
	section.

<h2 id='referencing-svg-shapes'>
Referencing SVG shapes</h2>

	An SVG shape can be referenced using the <code>url()</code> syntax.
	The shape can be any
	of the <a href="https://www.w3.org/TR/SVG/shapes.html">SVG basic shapes</a>
	or a <a href="https://www.w3.org/TR/SVG/paths.html">path element</a>.

	<div class="example">
		<img src="images/svg-shape-reference.png" width="166" height="350"
		     alt="results of referencing SVG shapes"
		     style="float: right">
		<xmp highlight=html>
			<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>
		</xmp>
	</div>

<h2 id="shapes-from-image">
Shapes from Image</h2>

	Add the final
	<a href="https://www.w3.org/TR/css-shapes/#shapes-from-image">level 1</a>
	section.

	Issue: One <a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=16716">suggestion</a>
	is to define a shape based on an element's rendered content.
	This could have security implications.

	Issue: Another <a href="http://lists.w3.org/Archives/Public/www-style/2014Mar/0120.html">suggestion</a>
	is to add something to an image() function
	that determines the relevant pixels to use
	(both for defining a shape and for display).

<h2 id="fetching-external-shapes">
Fetching external shapes</h2>

	To <dfn export>fetch an external resource for a shape</dfn>, either an SVG or an image, given a
		[=CSS declaration block=] |declaration|,
		[=fetch a style resource=] given a <<url>> value,
		with ruleOrDeclaration being |declaration|,
		destination "image",
		CORS mode "cors",
		and processResponse being the following steps given [=/response=] |res| and null, failure or
		a byte stream |byteStream|:
			If |byteStream| is a byte stream,
			apply the image or SVG to the appropriate shape-accepting property.

		Note: shapes require CORS mode as their effect is detected by the document.


<h2 id="shapes-from-box-values">
Shapes from Box Values</h2>

	Add the final
	<a href="https://www.w3.org/TR/css-shapes/#shapes-from-box-values">level 1</a>
	section.

<h2 id="declaring-shapes">
Declaring Shapes</h2>

	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.

	<div class="example">
		The red box illustrates an exclusion element's content box,
		which is unmodified and subject to normal CSS positioning
		(here absolute positioning).

		<xmp highlight=html>
			<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>
		</xmp>
		<img src="images/shapes_CSS2.1_MBP.png" width="381" height="335"
		     alt="Example rendering of circle shape and box model."
		     class="singleImgExample"
		     style="max-width:40%">
	</div>

<h3 id="shape-outside-property">
The 'shape-outside' Property</h3>

	Add the final <a href="https://www.w3.org/TR/css-shapes/#shape-outside-property">level 1</a> section
	with the change that shape-outside applies to block-level elements
	and has an effect if the element is an exclusion.

<h3 id="shape-inside-property">
The 'shape-inside' Property</h3>

	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.

	<pre class='propdef'>
		Name: shape-inside
		Value: auto | outside-shape | [ <<basic-shape>> || shape-box ] | <<image>> | display
		Initial: auto
		Applies To: block-level elements
		Inherited: no
		Computed Value: computed lengths for <<basic-shape>>, the absolute URL for <<url>>, otherwise as specified
		Animation type: as defined for <<basic-shape>>, otherwise discrete
	</pre>

	The values of this property have the following meanings:

	<dl dfn-type=value dfn-for=shape-inside>
		<dt><dfn>auto</dfn>
		<dd>
			The shape is computed based on the content box of the element.

		<dt><dfn>outside-shape</dfn>
		<dd>
			The shape is computed based on
			the shape defined by the shape-outside
			and shape-margin properties.

		<dt><dfn><<basic-shape>></dfn>
		<dd>
			The shape is computed based
			on the values of one of
			the <<basic-shape>> functions.

		<dt><dfn><<url>></dfn>
		<dd>
			If the &lt;uri&gt; references an SVG shape element,
			that element defines the shape.
			Otherwise, if the &lt;uri&gt; references an image,
			the shape is extracted and computed
			based on the alpha channel
			of the specified image.

			If the &lt;uri&gt; does not reference
			an SVG shape element or an image,
			the effect is as if the value ''auto'' had been specified.

		<dt><dfn>display</dfn>
		<dd>
			The shape is computed based on the shape of the display
			as described in <a href="https://drafts.csswg.org/css-round-display">css-round-display</a>.
	</dl>

	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''.

	<figure>
		<img src="images/shape-inside-content.png" width="743" height="349"
		     alt="Content flowing with and without a shape-inside">
		<figcaption>Effect of shape-inside on inline content.</figcaption>
	</figure>

	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.

	<figure>
		<img src="images/rounded-rect-overflow.png" width="311" height="297"
		     alt="Overflow interacting with rounded rect"
		     style="display:inline-block;vertical-align:top">
		<img src="images/ellipse-overflow.png" width="311" height="297"
		     alt="Overflow interacting with ellipse"
		     style="display:inline-block;vertical-align:top">
		<figcaption>
			Overflow interacting with exclusion areas
			defined by 'shape-inside' and 'shape-padding'.
		</figcaption>
	</figure>

	Issue: improve the illustration above,
	using text to show overflow instead of grey 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.


<h3 id="shape-image-threshold-property">
The 'shape-image-threshold' Property</h3>

	Add the final
	<a href="https://www.w3.org/TR/css-shapes/#shape-image-threshold-property">level 1</a>
	section with the change that
	it applies to both 'shape-inside'
	and 'shape-outside'.

<h3 id="shape-image-source-type-property">
The <css>shape-image-source-type</css> Property</h3>

	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.

<h3 id="shape-margin-property">
The 'shape-margin' property</h3>

	Add the final
	<a href="https://www.w3.org/TR/css-shapes/#shape-margin-property">level 1</a>
	section with the change that it applies to exclusions.

<h3 id="shape-padding-property">
The 'shape-padding' Property</h3>

	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.

	<pre class='propdef'>
		Name: shape-padding
		Value: <<length-percentage [0,∞]>>
		Initial: 0
		Applies To: block-level elements
		Inherited: no
		Percentages: refer to the <a>inline size</a> of the containing block
		Computed Value: computed <<length-percentage>> value
		Animation type: by computed value
	</pre>

	<dl dfn-type="value" dfn-for="shape-padding">
		<dt><dfn><<length-percentage [0,∞]>></dfn></dt>
		<dd>
			Sets the padding of the shape to the specified value.
	</dl>

	<div class="example">
		<figure>
			<img src="images/shape-padding.png" width="222" height="222"
			     alt="Example of a shape-padding offset">
			<figcaption>
				A 'shape-padding' creating an offset from a circular 'shape-inside'.
				The light blue rectangles represent inline content
				affected by the shape created by the padding.
			</figcaption>
		</figure>
	</div>

	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.

<h2 class=no-num id=privacy>Privacy Considerations</h2>

No new privacy considerations have been reported on this specification.

<h2 class=no-num id=security>Security Considerations</h2>

No new security considerations have been reported on this specification.
