Skip to content
ColorKit

Free CSS triangle generator

Make a triangle out of four borders

Pick a direction, set a width and a height in pixels, and this generator writes the three to five declarations that draw the shape — free, no signup, and the rule is on your clipboard in one click. A CSS triangle is never drawn: an element with width: 0 and height: 0 still paints its borders, and where two borders meet the browser cuts the joint diagonally, leaving four triangular wedges that tile the element. Color one, set the other three to transparent, and what is left is your triangle — 131 bytes at the 48 × 40 px default, with no image request and no SVG markup.

  • 100% free
  • No signup
  • 8 directions
  • 3-5 declarations
  • No SVG, no image
Direction the point faces

Press Ctrl+V anywhere on the page to drop in a hex code or any CSS color — no need to click the field first.

At 1:1, exactly as the rule renders it
Border box
48 × 40 px
Longest edge
46.65 px
Interior angles
apex 61.9° · base 59.0° and 59.0°

The rule

.triangle {
  width: 0;
  height: 0;
  border-right: 24px solid transparent;
  border-bottom: 40px solid #4f46e5;
  border-left: 24px solid transparent;
}

5 declarations, 131 bytes minified. The solid border is always the one opposite the point, so a triangle facing up carries its color on the bottom edge.

How to make a triangle in CSS

Three moves: the direction, the two dimensions, and where the element is going to sit.

  1. Choose which way the point faces

    The eight buttons cover the four cardinal directions plus the four corner wedges, which are right-angled triangles that fill a corner instead of pointing out of one. Notice which border ends up carrying the color: it is always the one opposite the way the point faces, so an upward triangle is colored on its bottom border. That inversion is the single thing that catches people out when they write the rule from memory.

  2. Set the base and the altitude

    Width and height are the dimensions of the whole element, not of one border — an upward triangle 48px wide is made from two 24px transparent side borders. Equilateral sets the height to base × 0.8660, 90° apex halves it, and the apex-offset slider takes width from one transparent wedge and gives it to the other, which puts the point off to one side. The angle readout under the previews recalculates as you drag, so you can hit a slope on purpose rather than by eye.

  3. Copy the rule, then give the element somewhere to stand

    The element measures 0 × 0 in the box model, so it does not sit in a flow layout the way a real box does; in practice it is either absolutely positioned against something or inline-block with a margin. Check that nothing in your reset adds padding or a min-width to it, and keep border-style: solid — dashed and dotted break the diagonal joint into gaps and the triangle falls apart.

Technical specifications

Directions8 — up, down, left, right, plus the four right-angled corner wedges
Rule size3 declarations for a corner wedge, 5 for a cardinal triangle; 131 bytes minified at the 48 × 40 px default
Dimensions1-400 px on each axis in 1 px steps, with presets for equilateral (base × 0.8660), a 90° apex (base ÷ 2) and a long spike (base × 2)
Apex offset−50% to +50% of the base, moving the split between the two transparent wedges to produce a scalene triangle
ReadoutsBorder-box size, longest edge and all three interior angles, taken from arctangents of the border widths
Color inputHex in 3, 4, 6 and 8 digits, rgb() and hsl() in both syntaxes, and any of the 148 CSS color keywords
Browser supportEvery engine that honours border-color: transparent — IE7 onwards, and every version of Chrome, Firefox, Safari and Edge
RunsIn the tab you are reading; the page issues no request after it has loaded

Frequently asked questions

Why is the colored border the opposite one from the way the triangle points?

Because each border wedge is widest along its own outer edge and tapers to a point at the centre of the element. An upward-pointing triangle is therefore the bottom border: that wedge spans the full width at the bottom and narrows to nothing in the middle, and once the left and right wedges are transparent, the narrow end is the apex. Read the rule as “the colored side is the base” and you stop guessing wrong.

Why did my triangle come out as a rectangle with a colored stripe?

Something is giving the element a content box. The usual culprits are padding inherited from a reset, a min-width or min-height from a utility class, or a line-height acting on stray whitespace inside the tag. Inspect the computed content box: anything other than 0 × 0 stops the four mitre lines meeting in the middle, and each border renders as a trapezium instead of a triangle. The other classic is display: inline, where width and height are ignored outright, so the element needs block, inline-block or absolute positioning.

How do I make an exactly equilateral triangle?

Set the height to the base times 0.8660254, which is √3 ⁄ 2 and what the Equilateral button applies. At a 48px base that is 41.57px, and fractional border widths are fine — they resolve against device pixels, so on a 2× display the value lands on 83.14 physical pixels rather than rounding at CSS-pixel granularity. Rounding to a flat 42px moves the apex from 60° to 59.49° and the base angles to 60.26°, which nobody is going to notice.

Can I put a border, an outline or a rounded tip on one?

Not on the element itself: the borders are the shape, so there is nothing left over to draw a border with, and outline traces the rectangular border box rather than the visible wedge. An outlined triangle is two triangles, a larger one in the outline color sitting behind a smaller one in the fill color. border-radius does have an effect, but not the one you want — it rounds the outer corners of the border box, so on an upward triangle it softens the two base corners and leaves the apex needle-sharp, because the apex is an inner corner of the mitre and radii never apply there.

Why do the slanted edges look stepped at large sizes?

Because the diagonal is a boundary between two painted regions rather than a stroked line, and engines antialias that boundary less carefully than they antialias a path. Chrome and Firefox smooth it well at ordinary sizes, but above roughly 100px on a fractional device pixel ratio — the 1.25 and 1.5 that Windows scaling produces — a staircase becomes visible. Below about 50px there is nothing to see. If a large flat triangle really is the design, a clipped box or an SVG polygon holds its edge better, because both are rasterized as paths.

Should the other three borders be transparent or the page background color?

Transparent, always. The keyword resolves to rgba(0, 0, 0, 0) and composites over anything, so one triangle works on a white card, over a photograph and in a dark theme; borders painted #ffffff to fake the effect turn into two visible white wings the moment the surface behind them changes. The one historical exception is IE6, which painted transparent borders black and needed a chroma filter to hide them — every engine from IE7 onwards handles the keyword correctly.

Can a CSS triangle contain text or an icon?

Not usefully — its content box is 0 × 0 and overflow is visible, so a child starts at a point in the centre of the element and spills out across the borders in both directions. The normal arrangement is the other way round: a real box holds the text and the triangle is a ::before or ::after pinned to it, which has the side benefit of keeping the extra element out of your markup entirely.

About the border-triangle trick

Borders in CSS do not butt up against each other; they mitre. When the top border is red and the right border is blue, something has to decide which pixel belongs to which, and the rule is a straight line drawn from the outer corner of the box to the inner corner — the same joint a picture frame has. On an ordinary box that joint is a 45° nick nobody ever notices. Shrink the content box to nothing and there is no inner corner left to run to: all four mitre lines collapse onto the centre of the element, and the borders become four triangles that tile it completely. Turning three of them transparent leaves exactly one.

What that buys you is a shape with no path data and no extra request. What it costs is any relationship between the shape and the box model. Hit testing still uses the rectangle, so a pointer in a transparent corner is still over the element and an interactive triangle usually needs a smaller, honest target behind it. A background-image never appears, because a zero-size content box has nothing to paint on. And the three shadow properties disagree about what they are shadowing: box-shadow traces the border box and hands you a rectangular shadow behind a triangular shape, text-shadow has no glyphs to work with, and only filter: drop-shadow() reads the alpha channel and follows the point — which is why it is the one you want here and why the filter generator is where to tune it.

Reach for clip-path the moment the triangle needs to be more than a flat color. border-color takes a color and only a color, so a shape built this way can never carry a gradient or an image, and it cannot be tweened into a different outline. A clipped box keeps its real width and height, accepts any background, and animates between polygons that share a vertex count, which the clip-path generator will draw for you. The trade runs the other way for the commonest triangle on the web, a tooltip pointer: there the shape has to be outlined in the bubble’s border color, which takes two triangles stacked and is something only the border form can do. The CSS arrow generator handles that stacking and the positioning arithmetic that goes with it.

Where the border maths happens

Every number on this page is worked out by JavaScript running in the tab you are reading it in. Nothing you type, paste or open is uploaded, logged or kept, which is also why the tools carry on working after you disconnect from the network.

Nothing is remembered between visits either. This page keeps no local storage, so a reload puts you back on the 48 × 40 px upward triangle in #4f46e5 that it starts with.