Adobe

decor

Web Platform Team Blog

Making the web awesome

CSS Shapes Polyfill

The CSS Shapes feature is coming soon to a browser near you. The specification has reached Candidate Recommendation and implementations are maturing in the experimental builds of WebKit and Blink. In addition to brushing up on CSS Shapes over at A List Apart or here on the Adobe Web Platform Blog, you may also want to start thinking about browser compatibility. Even after these features become available in release versions of Chrome and Safari (fingers crossed for soon), they will not yet be available in other browsers.

The CSS Shapes Polyfill is one method of achieving consistent behavior across browsers. It is a bit of JavaScript that checks to see if a browser supports CSS Shapes; if not, it approximates the behavior with a series of floats. There are simpler approaches to compatibility, such as gracefully falling back to old float behavior, or using feature detection like Modernizr to tweak styles based on shapes support. However, the polyfill allows you to use shapes, even in non-supporting browsers, and utilizes native implementations where possible.

The Basics

See the Pen CSS Shapes Polyfill Demo by Adobe Web Platform (@adobe) on CodePen.

Using the polyfill is incredibly easy. All you have to do is:

  1. Download the script from GitHub. You’ll want shapes-polyfill.js or shapes-polyfill.min.js (the minified version).
  2. Include the script in your page.
  3. Add shape-outside and shape-margin styles in linked stylesheets or <style> elements.

Example

In order to use the polyfill, the key pieces are the CSS to add the shape styles:

.shape {
    float: left;
    -webkit-shape-outside: circle(50%); /* only prefix currently supported */
    shape-outside: circle(50%);
    shape-margin: 1em;
}

and the html markup it is applied to, along with the polyfill script itself:

<div class='shape'></div>
This text will wrap around the circular contour to the left.
<script src='shapes-polyfill.js'></script>

If you are interested in seeing the full context for this code, I have created a working example.

Caveats

The polyfill will work best in simple shapes cases, and there are some limitations you may run into.

  • Shape styles must be set inside style elements or linked stylesheets. The polyfill does not monitor inline styles that are set via the style attribute.
  • The script recomputes layout only in response to a window resize event. If other events (like style changes) should cause relayout, you will have to force a layout using the ShapesPolyfill.teardown() and ShapesPolyfill.run() methods (see the documentation).
  • shape-outside: url() values respect CORS, so you should load images from the same domain as the page, or from a server that supplies the appropriate CORS headers.
  • The polyfill does not yet support shapes on stacked floats.

In addition to the above limitations, the polyfill also has a performance cost. Because of the computation required, layout using the polyfill is roughly an order of magnitude slower (10-20x depending on shape) than layout utilizing a native shapes implementation. The polyfill is also another resource that must be loaded into your page. You should weigh these performance costs when deciding whether the polyfill is the optimal approach for shapes browser compatibility on your site.

Further Tinkering

The source code is available on GitHub, and includes documentation for customizing how the polyfill runs. Please let us know if you have any feedback. You can do so through GitHub issues, here on the blog, or via twitter @adobeweb.

Comments are closed.