Herramientas · CSS · Generador de clip-path · Guías · Making a Hexagon Profile Photo With CSS clip-path
Making a Hexagon Profile Photo With CSS clip-path
A hexagon profile photo is one of the most common jobs for clip-path, and it looks like a one-liner: take the Hexagon preset from Clip-path generator, paste it onto the img, done. In practice three things go wrong in a row: the hexagon comes out squashed, the border you had disappears on four of its six sides, and the drop shadow is gone. Each has a short fix. Here is the whole job, in the order you will hit them.
The starting point
The Hexagon preset is polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%): a flat-topped hexagon whose top edge runs from a quarter to three quarters of the width. Because every point is a percentage of the element's box, the shape stretches with the box. That is useful, and it is also the first problem.
Problem 1: the hexagon is squashed
Avatars are usually square, and on a square box this point list gives a hexagon that is slightly too tall to be regular. A regular flat-topped hexagon is wider than it is tall, in the ratio 2 to the square root of 3, roughly 1.155 to 1. Profile photos also come in every shape people upload, so without a fixed ratio each avatar would be cut into a different hexagon.
Fix the box, not the points. Give the image a fixed ratio and let object-fit crop the photo to fill it:
.avatar {
width: 160px;
aspect-ratio: 2 / 1.732;
object-fit: cover;
clip-path: polygon(25% 0%, 75% 0%, 100% 50%,
75% 100%, 25% 100%, 0% 50%);
}
If a slightly tall hexagon on a square box is the look the design wants, keep it square. The point is to choose it, not to get it by accident.
Problem 2: the border only shows on two sides
A border is drawn around the rectangular box, and clip-path cuts it along with everything else. The hexagon's top and bottom edges run along the box edge, so the border survives there. The four diagonal edges cut across the box, so the border is clipped away on all of them.
Instead, wrap the image in an element with the outline colour as its background and a little padding, and clip both with the same polygon. The coloured wrapper shows around the photo on all six sides. One honest caveat: padding is measured horizontally and vertically, so the outline on the diagonal edges comes out a little thinner than on the flat ones. At a 2 or 3 pixel outline nobody will notice; at 10 pixels you might.
Problem 3: the shadow disappeared
A box-shadow is painted outside the box, and everything outside the hexagon is clipped, so the shadow vanishes completely. Moving box-shadow to the wrapper does not help either, because the wrapper is clipped too.
What works is a second, unclipped parent with filter: drop-shadow(...). A drop-shadow filter is drawn from the visible pixels of what is inside it, so it follows the hexagon's outline rather than the rectangle. That gives you three layers: an outer element for the shadow, a clipped wrapper for the outline, and the clipped image.
Two smaller things to check before shipping
If the avatar is a link, its cut corners are no longer clickable, since pointer events only register inside the visible shape. At avatar sizes that is usually fine, but on a small icon it can make the target noticeably smaller than it looks in the layout. And keep the alt text: the shape is decoration, the person in the photo is not.
If you later want the hexagon to grow or turn into a different shape on hover, keep the point count at six in both states, since polygons with different counts jump instead of animating.
For why clipping beats exporting a shaped image in the first place, see the background. For adjusting points, adding them, and the circle and inset modes, see the how-to guide. Or start from the Hexagon preset.