USE CSS SHAPES TO CREATE STRIKING EFFECTS
Daniel Crisp explains how to use the clip-path property to create some text effects that will leave visitors to your site mightily impressed
As front-end developers, we tend to think in rectangles. Rectangles inside rectangles inside rectangles inside rectangles. We might employ tricks with borders to make circles or triangles, but really they’re still just rectangular boxes in disguise. Well this is about to change with CSS Shapes, a W3C Candidate Recommendation, which will change the way you think.
CSS Shapes allow you to create geometric shapes using shape functions: circle(), ellipsis(), inset() and polygon(), and apply them to elements or effects such as clipping and filters. What’s more, the shapes can affect the flow of the content, allowing you to wrap text neatly around features like circular avatars. Perhaps the most powerful shape function is polygon() as it lets you create complex arbitrary shapes using unlimited points defined using coordinate pairs. If you’ve used SVG, this will be familiar to you.
In this tutorial, we’ll be utilising polygons with the clip-path property to cut a geometric shape out of our text so that only the area enclosed within the polygon is visible. We’ll also add some simple transitions to bring the effect to life.
Time for some code
You can grab the code for each step in this repo from here: http://netm.ag/298-demo
St ep 1
First, let’s get our HTML ready. We just need a <div>, our .clip class and our text, but as we’ll be using pseudo-elements for this effect, we’ll also add an attribute with the same value as the text so we can read it into the CSS rather than hard-coding it. <div class=”clip” data-content=”A clipping demo”> A clipping demo </div> Next, we want to make it fill the screen and align the text dead centre – we can use some Flexbox magic for this. Let’s also style and size the text.
Now we can style the ::before and ::after pseudoelements, with each becoming a layer on top of the text. By default, ::after will have the highest z-index. The handy attr() selector will read the value of our
data-content attribute. The pseudo-elements will share the position and Flexbox properties, so we can refactor our CSS slightly and leverage the power of SCSS to keep our stylesheet tidy. The font styling will be inherited. We’re using ... to denote the properties we’ve already covered.
CSS Shapes allow you to create geometric shapes using shape functions, and apply them
The result in the browser should look identical, because the pseudo-elements are sitting directly on top of the text. You can modify their styles in DevTools to see how they are layered.
St ep 3
Time to give each layer a different colour and background – let’s go for some bold, on-trend, neon colours that we’ve predefined as variables. We can also force the text to wrap onto multiple lines using a CSS padding trick rather than adding these in the HTML. This is helpful as otherwise we’d have to use two different types of line breaks: <br> inside the
<div> and the more obscure \A in the attribute. The padding trick works by giving the text zero horizontal width, forcing the browser to wrap each word to a new line.
St ep 4
Time for the interesting bit – we’re ready to start clipping our text. We’re going to create a diagonal clip, slicing the screen into two triangles from the bottom left to top right. The ::before pseudo-element will only be visible in the top-left triangle, and ::after pseudo-element will only be visible in the bottomright triangle. Here’s the code to achieve that:
This creates polygons with four points. Each point is described by a coordinate pair; simply an X (left to right) and Y (top to bottom) value. The value can be absolute (for example: px) or relative (for example: %). The points are referenced to the top left, so the points at 100% 100% are in the bottom right.
Imagine lines connecting each of the points in the order that they are listed to form the shapes. In the ::before polygon it starts in the top left (0 0), moves across the screen to the top right (100% 0), and then down to the bottom left (0 100%).
Hopefully you will be seeing your clipped text now. Resize the browser and you will see the clipping react accordingly.
If you are using Chrome, you will probably see some repaint issues while resizing, caused by Chrome’s Composite Layers. Unfortunately, because the demo is full screen, the recommended will-change:
transform property and transform: translateZ(0) hack don’t rectify this. However, if you switch .clip to
position: fixed; it works! Bear in mind that Chrome is trying to be helpful, and this workaround will have an impact on performance. Be sure to profile performance when doing things like this in production.
St ep 5
Now that we have got our clipped text, let’s bring it to life with some transitions. The good news is that you can simply transition the clip-path property so that the browser does all of the hard work. Let’s enable transitions on the pseudoelements, and then define four different states to transition between. State 1: This is the initial state, so let’s create three others Add each block at the bottom of your CSS as you go, so you can see what it looks like. State 2: Move the triangles apart slightly to reveal the background This will look a bit like Congo’s flag – if you don’t have to Google that I’ll be very impressed! Removing 20 per cent from the tip of each polygon triangle will do the trick. State 3: Morph the triangles into rectangles This is similar to the French Tricolour, in reverse. What about that fourth coordinate pair? Well, this is where it comes in useful. It turns out that transitioning clip-path only works if the shape function used is the same (so polygon > polygon) and the number of points used is the same – the browser will transition each individual point. That’s why we have that fourth hidden point – it allows us to seamlessly transition from a triangle to a rectangle, we just reveal that fourth point when we need it. State 4: Twist those polygons Sticking to our flag theme, this would resemble ‘I require a tug’ in the world of maritime flag signalling. Google time?
Here we’re twisting the polygons so they cross in the centre and form two triangles each. This is when transitions can help you to understand the coordinate pairs. By really slowing down the transition, you can see how each point moves across the screen to its new position, and you start to understand how the ordering of the pairs affects the transition. It actually gives you quite a lot of control over the transition.
Transitions When we start playing with transitions we can really bring the effect to life