October 1st, 2019
Different website designs often call for a shape other than a square or rectangle to respond to a click event. Perhaps your site has some kind of tilted or curved banner where the click area would be awkwardly large as a straight rectangle. Or you have a large uniquely shaped logo where you only want that unique shape to be clickable. Or you have an interactive image that responds differently when different regions of it are clicked.
You can surround those assets with an un-styled
<a> tag to get a clickable rectangle that’s approximately the right size. However, you can also control the shape of that region with different techniques, making sure the target for your click area exactly matches what’s visible on the screen.
If your click target is an image or a portion of an image, and you have the ability to choose SVG as its format, you already have a great deal of control over how that element will behave on your page. The simplest way to make a portion of an SVG clickable is to add an an SVG hyperlink element to the markup. This is as easy as wrapping the target with an
<a> tag, just as you would a nested html element. Your
<a> tag can surround a simple shape or more complex paths. It can surround a group of SVG elements or just one. In this example the link for the bullseye wraps a single circle element, but the more complex arrow shape is made up of two polygons and a path element.
Note that I’ve used the deprecated
xlink:href property in this demo to ensure that the link will work on Safari. The
href alone would have worked in Internet Explorer, Chrome, and Firefox.
The only trick here is to make sure the
<a> tag is inside the SVG markup and that the tag wraps the shape you want to be clickable. The viewbox for this SVG is still a rectangle, so wrapping the entire SVG element wouldn’t have the same effect.
Let’s say you don’t have control over the SVG markup, or that you need to add a clickable area to a raster image instead. It’s possible to apply a clickable target to a portion of an
<img> tag using an image map.
W3 Schools has an excellent example of an image map using a picture of the solar system where the sun and planets are linked to close-up images of those targets — everywhere else in the image is un-clickable. That’s because the coordinates of the areas defined in their image map match the locations of the sun and planets in the base image.
Here’s another example from Derek Fogge that uses uses maps to create more interesting click targets. It does use jQuery to style the areas on click, but notice the way a map overlays the image and coordinates are used to create the targets.
You can implement image maps on even more complex shapes too. In fact, let’s go back to the same target shape from the SVG example but using a raster image instead. We still want to link up the arrow and the bullseye but this time do not have SVG elements to help us out. For the bullseye, we know the X and Y coordinates and its radius in the underlying image, so it’s fairly easy to define a circle for the region. The arrow shape is more complicated. I used https://www.image-map.net to plot out the shape and generate the area for the image map — it’s made up of one polygon and one circle for the rounded edge at the top.
clip-path property provides considerable flexibility for defining and styling target areas on any HTML element.
Here we have a click area in the shape of a five-pointed star. The star is technically a polygon, so we could use a star-shaped base image and an image map with corresponding coordinates like we did in the previous image map example. However, let’s put
clip-path to use. The following example shows the same
clip-path applied to both a JPG image and an absolutely positioned hyperlink element.
Browser support for
clip-path has gotten much better, but it can still be inconsistent for some values. Be sure to check support and vendor prefixes before relying on it.
We can also mix and match different approaches depending on what best suits the shape of a particular click target. Here, I’ve combined the “close” shape using Bennet Freely’s clippy with an SVG hyperlink element to build the start of a clickable tic-tac-toe game. SVG is useful here to make sure the “hole” in the middle of the “O” shape isn’t clickable. For the “X” though, which is a polygon, a single
clip-path can style it.
Again, beware of browser support especially when mixing and matching techniques. The demo above will not be supported everywhere.
CSS shapes without transparent borders
clip-path property allowed us to apply a predefined shape to an HTML element of our choice, including hyperlink elements. There are plenty of other options for creating elements HTML and CSS that aren’t squares and rectangles — you can see some of them in The Shapes of CSS. However, not all techniques will effect the shape of the click area as you might expect. Most of the examples in the Shapes of CSS rely on transparent borders, which the DOM will still recognize as part of your click target even if your users can’t see them. Other tricks like positioning, transform, and pseudo-elements like
::after will keep your styled hyperlink aligned with its visible shape.
Here’s a CSS heart shape that does not rely on transparent borders. You can see how the the red heart shape is the only clickable area of the element.
Here’s another example that creates a CSS triangle shape using transparent borders. You can see how the click area winds up being outside the actual shape. Hover over the element and you’ll be able to see the true size of the click area.