Making Sense of Clip Path


Originally posted on Medium

One of the great parts about teaching, is that students come in with the freshest ideas. Those of us in the industry, tend to over think how we would accomplish a task, and thus, miss out on all the cool new techniques available.

Enter the first week project from our Bootcamp. A single page website that demonstrates comprehension of HTML and CSS: semantic usage of markup and CSS to achieve presentational styling. One of our students, Heather Banks, who had previously taken the part-time HTML/CSS as my student wanted to replicate an effect seen on the Squarespace site.

Clip Path background

Knowing that with her previous experience, the HTML and CSS of the site was completely within her skill level, I embarked on helping to achieve the effect. Making it appear that the nav is being clipped is no easy task, and my first instinct was to have a create an image that matches the portion of the background being cropped and set it as an after element. Problem is that it’s the least responsive fix out there and not entirely manageable.

Enter the CSS property clip-path.

This little used guy is part of a working draft that provides tools to hide portions of elements via masking and clipping. While clip-path is still not widely supported by all major browsers (c’mon Firefox and IE), it is a great little tool to achieve stylish effects on Webkit browsers.

Note, we need to use -webkit in order to use within these browsers currently.

Simply, the way it works is to provide a series of X and Y values to create a path. These values, when used to create a full path, clip the image inside to the dimensions of the path.

A Simple Triangle Clip

See the Pen Showing the use of clip-path by Drew Minns (@drewminns) on CodePen.

The above effect is achieved by simply using one element and applying a clip-path to it.

.clipClass {
  -webkit-clip-path: polygon(0 100%, 50% 0, 100% 100%);
}

Whoa, Let’s break this down

Much like the positioning property, we need to think in X and Y values. X:0 and Y:0 starts in the top left corner of the element and moves from there. X:100% refers to the right side and Y:100% refers to the bottom of the element.

Got it, cool. So the path we created above creates the following points.

x: 0, y:100%
x: 50%, y: 0
x: 100%, y: 100%

A simple path that starts in the bottom left, moves horizontally 50% and heads to the top, then goes 100% of the way through the element horizontally and sticks back to the bottom. Three points! A triangle!

So anything outside of those boundaries is simply clipped out and do not appear. The element itself still maintains the footprint of it’s dimensions, however it’s presentational layer is changed.

Shapes

In the above example, we used a polygon to create a shape and defined a path by creating x and y pairs that were comma separated. However, we can work with different shapes that take differing values.

Circles

See the Pen azVYmq by Drew Minns (@drewminns) on CodePen.

To create circles, we pass in three values to the circle shape. The x-axis and y-axis coordinates of the center of the circle, and the radius of the circle. When you define the radius of the circle, we use the keyword ‘at’ to define the x and y coordinates.

.clipClass {
  -webkit-clip-path: circle(50% at 50% 50%);
}

Ellipses

Often you may not want a simple circle, but an oblong shape. Enter the ellipse shape.

See the Pen qEVoaK by Drew Minns (@drewminns) on CodePen.

With ellipsis, you provide four values, the x-axis and y-axis of the radius (or shape) of the ellipse, followed by the ‘at’ keyword that separates the x and y coordinates at which to position the ellipse.

Inset

(May be super buggy in older versions in of Chrome)

Perhaps you want to create rounded rectangles and the sharp edges of the polygon aren’t what you are searching for, enter the inset value. Inset takes four values that equate to Top, Right, Bottom, Left and allows a radius to be set for all four of those values.

See the Pen myqxrg by Drew Minns (@drewminns) on CodePen.

.clipClass {
  -webkit-clip-path: inset(25% 0 25% 0 round 0 25% 0 25%);
}

The above reads as

inset(<top> <right> <bottom> <left> round <top-radius> <right-radius> <bottom-radius> <left-radius>)

Whoa, confusing. Great news, there is a short hand version

.clipClass {
  -webkit-clip-path: inset(25% 0 round 0 25%);
}

Quick Reference

Circle

circle(radius at x-axis y-axis)

Ellipse

ellipse(x-rad y-rad at x-axis y-axis)

Polygon

polygon(x-axis y-axis, x-axis y-axis, ... );

Inset

inset(top right bottom left round top-radius right-radius bottom-radius left-radius)

Creating Shapes

Seeing as the circle and radius shapes are limited by only a few values, Polygons are often the best choice for creating complex shapes. Having the ability to define multiple points helps to give us the ability to clip our elements in a variety of ways.

Comic Textbox

See the Pen WbXzbb by Drew Minns (@drewminns) on CodePen.

.clipClass {
  -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
}

Star

See the Pen zxPWxd by Drew Minns (@drewminns) on CodePen.

.clipClass {
  -webkit-clip-path: polygon(50% 0%, 63% 38%, 100% 38%, 69% 59%, 82% 100%, 50% 75%, 18% 100%, 31% 59%, 0 38%, 37% 38%);
}

Animation

So now that we have a grasp on shapes and how to produce them, how about we use them to create effects.

We can have a shape applied on hover, and use a transition property to create a smooth effect, however we need to keep in mind that we have to create an initial default state with all the same coordinates that we are using in our hover state.

Clip-path Animation

View on Codepen

.animateClass {
  -webkit-clip-path: polygon(20% 0%, 0% 0%, 0% 50%, 0% 80%, 0% 100%, 50% 100%, 80% 100%, 100% 100%, 100% 50%, 100% 0, 80% 0, 50% 0);
}
.animateClass:hover {
  -webkit-clip-path: polygon(50% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%);
}

Using it in production

Being that support for clip-path shapes is limited to webkit browsers at the moment, there are obvious limitations when moving to Firefox and IE. Firefox does have other options such as SVG masking, but the transition between two states may not be possible on certain computers.

All in all, if you want to explore recreate certain effects though, Chrome and other webkit browsers, such as Safari are widely supported.

Back to the original task though

Since this all came up while attempting to recreate the effect of the Squarespace navigation. By utilizing positioning to overlay an element on another, and then using clip-path to the mask the image, we can now just simply show the background image without any fancy image replacement techniques.

See the Pen vEZOeq by Drew Minns (@drewminns) on CodePen.

I don’t know about you, but the future is looking more and more geometric.

Related Posts

CSS Supply and Demand

Managing presentational content ordering using CSS quantity queries

An inline-block intervention

In an effort to explain why whitespace dependent elements are bad for your structural layout.