In a previous article I illustrated how to clip corners on rectangular user interface elements to make them appear “futuristic” using CSS. A similar visual trope is to create UI elements as hexagons, shown in the example above. These hexagons are typically deployed as buttons: on hover, the images in the background of the buttons change. Recently, a reader asked how this kind of effect might be achieved with .

Six years ago, I would have used CSS image sprites to create this kind of UI. With some minor tweaks, that technique could still be used today, although with some drawbacks. Today, we have strong browser support for SVG, which gives us more options and better results.

Step 1: Create the basic elements

You could plot the outline of the button in an SVG document by hand, or use of vector illustration application: most developers will choose the latter, so that’s what I’ll do here. For the sake of clarity, I’ll focus on creating just one button. An illustration of a hexagon

First, I made a 500px × 500px artboard in Illustrator, placed and sized two square bitmap images to fill the space exactly, and drew a hexagon on top. You’ll want to ensure that each of these elements has an appropriate layer name. In my example, the bitmap images are both PNG files; the uppermost one has a partially transparent alpha mask.

You can add text to the button in Illustrator at this stage, but that’s easy enough to do in the next step.

Before exporting the SVG file from Illustrator, I’ll convert the hexagon into a Compound Path by right-clicking on it, as polygons cannot be used as clipping paths.

Step 2: Clip the elements

After a basic cleanup of the SVG code, we’re left with something that looks like this:

<svg xmlns="" id="moon-nav" xmlns:xlink="" viewBox="0 0 500 500">
	<path fill="#FFFFFF" stroke="#231F20" d="M127.9,458.6L5.5,246.7l122.4-212h244.8l122.4,212l-122.4,212 H127.9z" />
	<image width="500" height="500" id="hexagon-pattern" xlink:href="orange-hexagon.png" >
	<image width="500" height="500" id="luna" xlink:href="luna.png" >
An alpha masked photograph of the Saturnian moon Io

To create the clipping effect, we’re going to add a clipPath around the path and images, referencing the id of the clipping area from the images. If you haven’t added text, we’ll do that here too: note the x and y positioning information. Finally, we’ll link the button as a whole:

<svg xmlns="" id="moon-nav" xmlns:xlink="" viewBox="0 0 500 500">
	<a xlink:href="" title="Luna">
		<clipPath id="moon">
			<path fill="#FFFFFF" stroke="#231F20" d="M127.9,458.6L5.5,246.7l122.4-212h244.8l122.4,212l-122.4,212 H127.9z" />
		<image width="500" height="500" clip-path="url(#moon)" id="hexagon-pattern" xlink:href="orange-hexagon.png" >
		<image width="500" height="500" clip-path="url(#moon)" id="luna" xlink:href="luna.png" >
		<text x="150" y="250" id="lune">LUNA</text>

Step 3: Add CSS

Right now the images don’t have any interactivity. We can change that by adding some CSS to the SVG file, immediately after the opening <svg> tag:

svg#moon-nav image {
	opacity: 0;
	transition: 1s opacity;
svg#moon-nav a:hover image { 
	opacity: 1;
svg#moon-nav a text {
	font-family: Verdana, sans-serif;
	font-size: 65px; fill: #fff;

Step 4: Embed the SVG on the page

If we simply reference the SVG file as an <img>, it won’t have any interactivity. Placing the SVG code directly in our HTML is the better option. I’ve added appropriate markup and CSS to make the SVG responsive, and moved the CSS that originally existed in the SVG file for testing purposes into the HTML page’s embedded style sheet.

There are other ways to achieve the same result: we could have used CSS masks, or the clip-path property. I’d argue that the SVG approach is slightly more elegant while enjoying better browser support, but you should never consider just “one way” of doing anything.

Hexagonal background textures by Metatality, used with permission

Enjoy this piece? I invite you to follow me at to learn more.
Check out the CodePen demo for this article at