CSS Shapes

Shape Boxes and Images

The CSS box model is based on the use of four different areas for a markup element. A box has a content area and enfolding padding, border and margin areas. Dimensions of each area can be delineated by detailing a range of box-related CSS properties:

<style type="text/css">
 img {
  border: 6px groove #CB3131;
  margin: 21px;
  padding: 21px;
 }
</style>

Visual representation of box areas is shown below:

---------------margin-box
------------border-box
---------padding-box
------content-box

CSS Shape Boxes

A CSS shape can be created as a reference to a box area: this approach seems to be a more straightforward alternative to using geometric calculations. The shape-outside property gets one of the following values: margin-box, border-box, padding-box or content-box. Let's consider an example combining the floating image above with inline content represented as a series of images depicting maple leaves. The CSS rule below is forming a rectangular shape along the contour of the image's margin box:

<style type="text/css">
 #apple {
  border: 6px groove #CB3131;
  float: left;
  margin: 21px;
  padding: 21px;
  shape-outside: margin-box;
 }
</style>

It should be noted that setting the border radius of a floating element affects the corner radii of the resultant shape: if the example above had been declared the border-radius property with a non-zero value, the shape would have been built as a rectangle with rounded corners.

A shape based on the border-box value hugs the outside border edge of the image's box:

shape-outside: border-box;

The padding-box and content-box values cause the leaves to traverse the border of the image:

shape-outside: padding-box;

shape-outside: content-box;

CSS Shapes and Images

The most convenient way to create a complex polygonal shape is to use an image URL as a value of the shape-outside property:

<style type="text/css">
 img[src="red-rose.png"] {
  float: left;
  shape-margin: 12px;
  shape-outside: url(red-rose.png);
 }
 img[src="white-rose.png"] {
  float: right;
  shape-margin: 12px;
  shape-outside: url(white-rose.png);
 }
</style>

The example renders a chapter from The Black Arrow by R. L. Stevenson: the text is flowing around the non-transparent areas of two floating images. Note the use of the shape-margin property: it produces a 12-pixel offset from the edge of each shape.

Image adjustment is provided by the shape-image-threshold property: it is employed to define the area extracted from an image to create a shape. Default value of shape-image-threshold is 0.0: it means that all non-transparent pixels will be used to mould a shape. Allowed values must be in the range [0.0 . . 1.0]. The resultant shape is formed by the pixels with alpha values greater than the threshold.

The example below combines a large logo of Android with transparent background with inline content represented by icons symbolizing Android applications. If the alpha channel threshold is 0.0 (default), inline content is flowing along the contour of non-transparent Android figure:

<style type="text/css">
 #android {
  float: left;
  shape-outside: url(android-logo-with-transparent-background.png);
 }
</style>

Let's modify the logo of Android by creating the white background with the alpha value of 0.5. If the alpha channel remains the same (0.0), icons will be aligned along the boundaries of the image's rectangular box:

<style type="text/css">
 #android {
  float: left;
  shape-outside: url(android-logo-with-white-background.png);
 }
</style>

To return to the previous shape, the alpha channel threshold should be defined as a value greater than 0.5: as a result, all pixels of semi-transparent white background will be discarded while forming the shape.

<style type="text/css">
 #android {
  float: left;
  shape-outside: url(android-logo-with-white-background.png);
  shape-image-threshold: 0.6;
 }
</style>