CSS Triangle Generator

Aim a triangle in any of eight directions, set the base and height in pixels, then copy the rule. The readout under the preview shows the four border values doing the work.

60 x 52 px
border-topnot set
border-rightnot set
border-bottomnot set
border-leftnot set

Point it somewhere

Up

The four corner directions build right-angle triangles from two borders instead of three.

Size and fill

Locked to the base by the proportion setting.

Start from a real use case

style.css
index.html

A dropdown caret, the little tail under a tooltip, the arrow on a breadcrumb chip. None of those need an image file. A single empty div with the right border values draws them, and this page builds those values while you watch the shape change.

How an empty box turns into a triangle

Give an element width: 0 and height: 0 and there is no content box left. The four borders still get drawn, so they meet in the middle and split the square into four trapezoids with diagonal seams between them. Color one of those four and set the other three to transparent, and the visible piece is a triangle.

Flip the Reveal the box behind the shape switch on the preview to see this happen. The three transparent borders come back as faint tints, the outline shows the square they add up to, and the triangle you were looking at sits inside as one of the four wedges. Turn the switch off and the same shape returns, minus the scaffolding.

The readout tells you which border is doing the work

Under the preview sit four cells, one per border side. Each shows the exact value the generated CSS uses, and any side the shape does not need reads not set. Pointing the triangle up puts the solid color on border-bottom, which surprises people the first time. The colored wedge always sits on the side opposite the direction the point aims at, because the wedge tapers away from its own edge toward the center of the box.

The corner directions on the pad work differently. A triangle pointing up and left uses only two borders, border-top for the fill and one horizontal border for the transparent half. Two borders give a right angle rather than the symmetrical shape the four cardinal directions produce, which is what you want for a flag tucked into the corner of a card.

Base, height, and what equilateral means here

Base is the flat edge. Height is the distance from that edge to the point. For an upward triangle, the base splits across border-left and border-right at half its value each, while the height becomes the full border-bottom width.

Plenty of triangle generators label a 50 by 50 pixel shape "equilateral". A triangle with three equal sides has a height of roughly 0.866 times its base, so a 50 by 50 box is noticeably too tall to be one. The Equilateral option here does the multiplication, so a 60 pixel base gives a 52 pixel height. Switch to Custom height when the design calls for a specific number rather than a correct shape, since a caret or tooltip tail rarely needs true geometry.

Border trick or clip-path

The switch above the preview rebuilds the same triangle with clip-path: polygon(), and the two approaches fail in different places:

Pick borders for a small solid caret or arrow. Pick clip-path when the triangle carries anything other than one flat color, or when the shape needs to stretch with its parent.

Placing the triangle once you have the CSS

A tooltip tail usually goes on a pseudo element rather than a real div. Copy the generated declarations into a ::after block, add content: "" and position: absolute, then offset it against a parent with position: relative. For a tail hanging below a tooltip, that means top: 100% with left: 50% and transform: translateX(-50%) to center it.

Where this tool stops

Border triangles have no rounded tips. border-radius on a zero-size box distorts the wedges instead of softening the point, so a rounded arrowhead needs an SVG or a clip-path built from curves. Neither method here accepts a border or stroke around the triangle outline, since a second triangle layered behind at a larger size is the usual workaround and the generator does not build layered rules.

Sub-pixel bases also matter. An odd base value splits into halves like 12.5 pixels, and browsers antialias that diagonal seam differently, which shows up as a faintly ragged edge on small carets. Even numbers avoid it. For shapes past three sides, the Border Radius Generator and the Transform Generator cover rounding and rotation that this page leaves alone.

Questions about CSS triangles

What comes up once the generated rule lands in a real stylesheet.

Why does an upward triangle use border-bottom for the color?

Each border wedge tapers from its own edge toward the middle of the box. The bottom border starts wide along the bottom edge and narrows to a point at the top, so coloring it draws a shape whose point aims upward.

Do I need width and height set to zero?

For the border method, yes. Any content box left over pushes the four border wedges apart and you get a frame with a hole in the middle instead of a triangle. The clip-path method is the opposite and needs a real width and height.

Can a border triangle have rounded corners?

No. border-radius on a zero-size element warps the wedges rather than rounding the tip. A rounded arrowhead needs an SVG path or a clip-path drawn with curves.

How do I add the triangle without an extra div?

Put the generated declarations on a ::after or ::before pseudo element, add content: "" and position: absolute, then position it against a parent set to position: relative.

Which method should I use for a tooltip arrow?

The border method. A tooltip tail is a small flat-colored shape, and the zero-size box positions cleanly against the tooltip edge without adding layout width.

Why does my small triangle look blurry along one edge?

An odd base value splits into fractional halves such as 12.5px, and browsers antialias the diagonal seam inconsistently at that scale. Round the base to an even number.

Does the generator send my settings anywhere?

No. The preview and both code blocks are built in your browser with JavaScript, so nothing reaches a server.