Adobe

decor

Web Platform Team Blog

Making the web awesome

CSS Shapes and Float Positioning: What’s Old is New Again

Note: CSS Shapes syntax has changed. For the latest information, see CSS Shapes Module Level 1.

The Adobe Web Platform Team has been working on CSS Shapes (fka CSS Exclusions and Shapes) for some time now. The CSS Shapes spec has been divided into two levels. CSS Shapes Level 1 allows authors to specify a shape-outside value for floats. The shape-outside value is a shape that defines the boundary that inline content wraps around instead of the float’s margin box. CSS Shapes Level 2 defines a shape-inside value for specifying the shape that inline content inside of a box conforms to. Level 2 also specifies a few new ways to define shapes.

We have recently been focusing on CSS Shapes Level 1. If you haven’t heard of it before, or you need a refresher, you can read my previous article on CSS Shapes for an overview of the Level 1 functionality.

Shapes and float positioning

Floats are normally positioned according to the float’s margin box. However, the first public working draft of CSS Shapes Level 1 specified that floats with a shape-outside get positioned based on the bounding box of the shape:

If a float has an outside shape, its positioning is resolved as defined in [CSS21] but the outside shape’s bounding box is used in lieu of the float’s margin box.

While this seemed pretty simple, it caused problems in practice. It was impossible to use margins to position the float (to position it halfway out of the page to get a semi-circle, for example). In addition, the behavior when positioning the shape using it’s x and y coordinates was very hard to explain and understand.

As a result of these complications, the positioning model has been changed in the latest CSS Shapes Editor’s Draft. The shape-outside shape no longer affects the positioning of floats, only of the inline content that wraps around the float. Thus, the positioning of floats with shape outside can be affected with margins the same way that unadorned floats can be.

Perhaps the only surprising outcome of this change is that the shape is now clipped to the margin box of the float:

When a shape is used to define a float area, the shape is clipped to the float’s margin box. In other words, a shape can only ever reduce a float area, not increase it. When a shape reduces a float area such that a line box that would be normally be affected by the float would not intersect the float area at all, the available space for the line box is constrained by the farthest margin edge of the float. For a left float this would be the left margin edge, and for a right float this would be the right margin edge.

Visualizing the new behavior

It might be hard to fully understand the difference from the prose alone. So here’s an example of how the same shape would work differently between the two positioning schemes. First, say we have a div with the following class:

.float {
    float: left;
    width: 100px;
    height: 100px;
    shape-outside: rectangle(10px, 10px, 50px, 50px);
}

To properly visualize this, the diagram will show some things that are usually invisible: the margin box of our div and the bounding box of our shape.

Here is what the old behavior looks like:

old-positioning

And with the new behavior, the margin box is used for positioning, not the shape’s bounding box:

new-positioning

Exploring the new behavior now

The best way to get a good understanding of the new behavior is to actually use it. You will be happy to know that support for the new positioning model is already available in both the WebKit Nightly and in Chrome Canary. If you’re not familiar with enabling CSS Shapes, you should read the instructions on enabling CSS Shapes and other experimental features in all of the supported browsers.

circle-and-ellipse

Once you have a CSS Shapes enabled browser, I’ve created an example of positioning floats with shapes to get you started. If you’re new to CSS Shapes, all of the examples from my previous article on CSS Shapes have been updated and work with the new model, so definitely take a look at that article if you feel that you need more shapes in your life.

3 Comments

  1. August 12, 2013 at 7:15 pm, Mr C said:

    In the example code the need to duplicate shape coordinates in both shape-outside and clip-path properties seems redundant.

    Is there a plan to allow shape-outside to automatically clip contents?

    • August 14, 2013 at 8:15 am, Bem Jones-Bey said:

      I agree that it is redundant. We have talked about being able to set shape-outside to the same value as clip-path and vice-versa, but a path forward on that has not been decided as of yet. It is most likely to be in a future level of the CSS Shapes specification.

      • August 14, 2013 at 5:05 pm, Mr C said:

        That would work. I initially assumed overflow:hidden on shape-outside would simply clip everything else.

        Either way, can’t wait to start using shapes and/or exclusions. So good.