By Tim King · Updated
CSS Shapes Generator
Hearts, Diamonds and Pills in CSS
OneTask is free, with no sign-up, and built by one person.
If this tool saved you time, a coffee helps keep new ones coming.
How the CSS Shapes Generator works
This CSS shapes generator draws hearts, diamonds, pills and more in pure CSS. Before clip-path, every shape on the web was a trick with borders, radius and pseudo-elements, and
those tricks still have the widest browser support and the fewest surprises. This tool collects the
twelve shapes worth knowing, each drawn from a single div, and writes them at the size and colour you
choose.
CSS shapes generator: borders, radius and clip-path
A block element is a rectangle, but a rectangle has more knobs than it looks. Its corners can be rounded independently, its borders can each be a different colour and width, it can be rotated and skewed, and it comes with two free pseudo-elements. Combine those and you can draw a surprising range of shapes without an image, an SVG or a clip path.
Radius shapes. Circle, oval, pill and egg are border-radius alone. A circle is a square with
50%; an oval is a rectangle with 50%; a pill is a rectangle with a radius larger than half its
height; an egg uses the slash syntax to give different horizontal and vertical radii per corner. The
moon is a circle with no background and an offset box-shadow that paints the crescent.
Border shapes. Trapezoid and Pac-Man use the border trick that also draws CSS triangles: a zero-size box with thick borders, where each border meets its neighbours at a 45° join. Make some borders transparent and the coloured one becomes a wedge. The trapezoid is a bottom border with transparent left and right borders; Pac-Man is four thick borders with a radius of 50% and one border transparent.
Transform shapes. Diamond and parallelogram are a square and a rectangle with rotate(45deg) and
skewX(-20deg) respectively. The transform does not change the element's layout box, so a diamond
still occupies a square in the flow and its rotated corners poke out; the generated diamond is scaled
down slightly so it fits inside its own box.
Pseudo-element shapes. Cross and heart use ::before and ::after as extra boxes. The cross is
two overlapping bars. The heart is two rectangles with rounded tops, rotated ±45° around their bottom
corners so they overlap into a point — it is the best-known single-element shape and a reliable
interview question.
Shapes versus clip-path. Clip-path is the modern answer for arbitrary polygons and scales with
percentages, but it clips borders and shadows and needs a wrapper for an outline. These classic shapes
keep their box-shadow and can take a real border in most cases, and they work in browsers where
clip-path is patchy. Use whichever fits: a hexagon is easier with clip-path, a heart or a pill is
easier this way.
Sizing. Every shape is written in pixels because the border trick needs absolute border widths.
Swap the pixel values for em to have the shape scale with the font size, or for a CSS custom
property if the same shape appears at several sizes.
Content inside shapes. The radius and transform shapes can hold text normally, though text in a diamond or parallelogram is rotated or skewed with it — counter-transform a child to fix that. The border shapes have zero content area and cannot hold anything; put the content in a sibling positioned on top.
FAQ
Why does the trapezoid have no content area?
Because it is drawn entirely from borders on a zero-height box. The width you set is the top edge and
the borders draw the rest. Any text inside would have no room. Overlay a positioned sibling or use
clip-path on a normal box if you need content within the shape.
Why does the diamond overflow its space?
A rotated square's corners extend beyond the original box by about 41%. The generated rule scales it
by 0.72 so it fits; if you remove the scale, give the element enough margin or use clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%) instead, which stays inside the box.
Can I add a border or shadow to these shapes?
The radius and transform shapes take border and box-shadow normally, which is their main advantage
over clip-path. The border-trick shapes cannot take an extra border since they are made of borders,
and the heart needs the shadow on both pseudo-elements with filter: drop-shadow on the parent for a
clean outline.
How do I make the heart or cross responsive?
Replace the pixel width and height with em or % values — the pseudo-elements are sized in
percentages of the parent so they follow automatically. The heart's border-radius: 50px 50px 0 0
can stay fixed; any value larger than half the pseudo-element width gives the same result.
Is there a performance difference between these and clip-path?
No meaningful one for static shapes. Both are painted once. Animating a border-radius or a
transform is cheap; animating border widths forces layout and is slower, so prefer transforms or
clip-path for shape animations.
See also: all Shapes & SVG tools, Layout & Spacing, Shadows & Motion, UI Components, Forms & Inputs, Colour.
Related tools
Blob Generator
Make organic blob shapes with border-radius.
CSS Divider Generator
Slanted, curved, zigzag and wave section dividers in pure CSS.
CSS Transform Generator
Compose translate, rotate, scale and skew into one transform value.
Floating Shapes
Add slowly rising, spinning shapes behind a hero section.
Torn Paper Edge
A ripped, jagged paper edge on a card or section.