Recently I’ve been thinking about how pages might start to break out of the “boxes inside boxes” trope that’s built up in web design over the past few years. One way to break through limitations is to merge two different creative possibilities: in this case, CSS clip-path
and the Shapes module.
The New Clip
clip-path
, inherited from SVG, is used to mask content on web pages. The old clip
syntax had several significant limitations - clipped elements had to be absolutely positioned, and could only be clipped into rectangular shapes - and has been superseded by this new specification. clip-path
opens the specification to arbitrary shapes (including circles, ellipses, and free curves), and places no restrictions on the size, flexibility, or position of content.
The easiest way to start playing with clip-path
is by using Bennett Feely’s excellent “Clippy” tool. One restriction is that you cannot upload images to the app; instead, you must provide an external URL. I’ve provided a copy of the image used in the example above.
There’s an infinite number of possible clipping areas; for this image, I chose “Triangle” in Bennett’s tool and moved the points around to the positions shown in Figure 1.
The complete code for the effect is shown at the bottom of the app window. Note that it provides a -webkit-
vendor prefix; right now, clip-path
is only supported in Webkit-derived browsers, and Safari still requires prefixes. We’ll get to making the clip effect work in Firefox and other browsers in a moment.
Adding the image to a page, we can apply an id
attribute, together with some filler text:
<img src="vapor-cone.jpg" alt id="penetrator">
<h1>The Need For Speed</h1>
<p>The urge to go faster than the speed of sound is probably as old as Kitty Hawk, as old as mankind’s first realization that there was a barrier to break.
And then some CSS:
img#penetrator {
width: 50%;
float: left;
-webkit-clip-path: polygon(24% 0, 24% 100%, 100% 54%);
clip-path: polygon(24% 0, 24% 100%, 100% 54%);
}
Note that the points of the clip-path are specified in a counter-clockwise direction from the top point, and are measured in percentages. (Pixels are also a possibility, but using percentages means that this effect will scale with the fluid image).
shape-outside
Contrary to expectations, clip-path
does not alter an element’s relationship to the rest of the page; the clipping area affects only the image, and the filler text wraps around it as if it’s still its original shape. To fix that, we need to use a separate CSS module.
Shaping The Wave
In previous articles I’ve shown how to use CSS Shapes to wrap text around circular elements, as well as curved images. In this case, we’re using a polygon shape: and, in a burst of logic, the shape-outside
property takes exactly the same values as clip-path
to map a polygonal area:
img#penetrator {
width: 50%;
float: left;
-webkit-clip-path: polygon(24% 0, 24% 100%, 100% 54%);
clip-path: polygon(24% 0, 24% 100%, 100% 54%);
shape-outside: polygon(24% 0, 24% 100%, 100% 54%);
}
The result matches the clipping path to the shape wrap, but clings the text very closely to the image; the shape itself also looks a little strange just hanging out on the page. In the example, I’ve fixed this by adding a negative margin-left
value to the image. This brings the clip-path
out of alignment with the wrapping shape, but the result works in this case.
Making The Effect Work Across Browsers
shape-outside
can be polyfilled, as discussed in a previous article. To support the clip-path
in other browsers, we turn to the SVG standard it was derived from. On the same page, write a small inline SVG:
<svg id="svgpath">
<defs>
<clipPath id="delta" clipPathUnits="objectBoundingBox">
<polygon points=".24,0 .24,1 1,.54" />
</clipPath>
</defs>
</svg>
I’ve talked about clipPath
previously; in this case, we want to make the SVG clipping path responsive, so we use clipPathUnits="objectBoundingBox"
. The SVG thinks of itself as a 1 × 1 box, so the clipping polygon takes the same value as clip-path
, divided by 100.
This SVG method is a fallback for clip-path
, but it goes first in the CSS declaration for the image:
img#penetrator {
width: 50%;
margin-left: -12%;
float: left;
clip-path: url(#delta);
-webkit-clip-path: polygon(24% 0, 24% 100%, 100% 54%);
clip-path: polygon(24% 0, 24% 100%, 100% 54%);
shape-outside: polygon(24% 0, 24% 100%, 100% 54%);
}
The result - a combination of two different CSS modules - breaks text out of boxes, making for the possibility of powerful and unique art-directed pages.
Photograph from Wikipedia Commons, used under a Creative Commons Attribution-Share Alike 3.0 Unported license.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/XJOOzv