Create a TRIANGLE (.triangle) file directly in your browser and download it instantly—no installation required.
width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 50px solid #6366f1;
#3b82f6), or paste an rgb() / rgba() / named color. Transparent borders stay invisible — only the named-side color renders.width:0; height:0; border-{three sides}:Npx solid transparent; border-{one side}:Mpx solid #color;. Paste into your stylesheet — no build step, no library.The CSS "border triangle" exploits how browsers render the diagonal miters where two borders meet on a zero-dimension element. When width: 0; height: 0 collapses the box, each of the four borders renders as an isosceles triangle wedge — color three of them transparent and you're left with a single triangle pointing toward the colored side. The technique has worked in every browser since IE6 (~2001) and remains the most efficient way to draw a small, solid-fill arrow.
<select> replacement or expandable panel. Rotating it 180 degrees with transform: rotate(180deg) flips it for the open state.list-style-type for branded bulleted lists.| Triangle Direction | Colored Border | Transparent Borders | Tip Position |
|---|---|---|---|
| Up (▲) | border-bottom-color |
left, right | top of box |
| Down (▼) | border-top-color |
left, right | bottom of box |
| Left (◀) | border-right-color |
top, bottom | left of box |
| Right (▶) | border-left-color |
top, bottom | right of box |
| Top-left corner | border-top-color + border-left-color (same color) |
right, bottom | top-left wedge |
| Top-right corner | border-top-color + border-right-color |
left, bottom | top-right wedge |
| Bottom-left corner | border-bottom-color + border-left-color |
top, right | bottom-left wedge |
| Bottom-right corner | border-bottom-color + border-right-color |
top, left | bottom-right wedge |
For straight (non-diagonal) triangles, the two perpendicular borders share equal width and control the base; the third (colored) border controls the height. For an equilateral triangle, set the colored border to roughly 0.866 times the transparent border width.
| Property | Border trick | clip-path: polygon() |
Inline SVG <polygon> |
|---|---|---|---|
| Browser support | Universal (IE6+) | 95%+ globally; Chrome/Edge, Firefox 54+, Safari 7+ partial | Universal (modern); IE 9+ |
| Markup overhead | One element, zero children | One element, zero children | One element + <svg> + <polygon> |
| Gradient fill | No (solid color only) | Yes (any CSS background) | Yes (SVG gradients) |
| Stroke / outline | No (border is the fill) | Workaround via two stacked elements | Native stroke, stroke-width |
| Animate vertices | No (only size/color) | Yes (@keyframes on polygon points) |
Yes (SMIL or CSS) |
| Antialiasing | Subpixel artifacts at small sizes | Clean | Clean (vector) |
| Pointer events outside shape | Hits the bounding box | Respects clipped shape | Respects path |
| Typical use | Tooltip arrows, dropdown carets | Modern hero shapes, animated polygons | Logos, icons, complex paths |
The border trick wins on universal support and minimal markup; clip-path wins when you need a gradient, outline-friendly hit-testing, or animated points; inline SVG wins when the shape is complex or needs a stroke.
A CSS triangle is part of the DOM — it scales with em units, inherits text color via currentColor, animates with transition, and never blurs at high-DPI zoom. There's no extra HTTP request, no sprite sheet, and no <img> tag to align. For a 20px arrow next to a button, it's lighter than even a 100-byte PNG.
This is the classic transparent-border antialiasing artifact. The keyword transparent is computed as rgba(0,0,0,0) — transparent black — and some renderers blend that black against the colored border at subpixel boundaries, leaving a faint dark fringe. Workarounds include using rgba(255,255,255,0) instead of transparent (so the antialias blends with white), or matching the transparent color to the parent background. Modern Chrome and Firefox handle this cleanly in most cases; the artifact is most visible on Retina displays at half-pixel sizes.
The base equals two transparent borders side by side; the height of an equilateral triangle is base * sin(60°) = base * 0.866. So if your transparent borders are 50px each (giving a 100px base), the colored border should be 100 * 0.866 ≈ 87px. The xconvert generator includes an equilateral preset that does this math for you.
Not directly — the border itself is the fill, so there's nothing left to stroke. The two common workarounds are: (1) stack two triangles, a slightly smaller background-colored one on top of a larger outline-colored one, both absolutely positioned; or (2) skip borders entirely and use SVG <polygon> with fill="none" and stroke="...", which gives you a true outline that scales and supports stroke-linejoin for crisp corners.
Yes, but the technique limits what you can animate cleanly. transform: rotate(), transform: scale(), opacity, and border-width are all GPU-accelerated and animate at 60fps. Animating border color works but triggers a paint. If you want to morph the triangle's shape (e.g., make it sharper or wider over time), you'll generally want clip-path: polygon() with animated point coordinates — that's what enables hero-section shape morphing.
It's been bulletproof since roughly 2001. Every shipping browser — Chrome, Firefox, Safari, Edge, Opera, and historically IE 6+ — renders zero-dimension border miters as triangles. There is no known browser, mobile or desktop, where this fails today. If your project doesn't need gradient fills or stroke outlines, the border trick is the safest geometric primitive in CSS.
clip-path instead?Reach for clip-path: polygon() when you need a gradient or image fill (the border trick is solid-color only), when the shape isn't a simple triangle (pentagons, parallelograms, chevrons), when you need precise pointer-event hit-testing (clicks outside the visible shape don't register), or when you want to animate the vertices. The tradeoff is browser support: clip-path is at roughly 96% global coverage in 2026, and older Safari versions had partial-support quirks. For tooltip arrows and dropdown carets, the border trick is still the right call.
Yes — wrap any straight triangle with transform: rotate(45deg) (or any angle) and CSS will pivot it around its center by default. Combine with transform-origin to rotate around a corner. For a chevron that flips when an accordion opens, animate transform: rotate(0deg) → rotate(180deg) with a transition and you get a smooth open/close indicator with no JavaScript.
The down-arrow inside native <select> replacements, the "more" carets on dropdown menus, the pointers on Bootstrap and Tailwind tooltips, the tail on iMessage / WhatsApp chat bubbles, breadcrumb separators on e-commerce sites, the play button on video thumbnails, and the diagonal corner ribbons on pricing cards labelled "Most popular." Once you know the trick, you'll spot it on nearly every site you visit.
Need to ship the snippet alongside other CSS? Pipe it through the CSS minifier for production or the CSS formatter for readability. Working in a design system? Pair the triangle with palette values from the color converter so the hex matches your token set exactly.