CSS Triangle Generator
Generate pure CSS triangles — 8 directions, custom size and color, copy-ready CSS
Selected: Up
100px wide × 100px tall
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid #3B82F6;
}How it works
CSS triangles use the border rendering model: when width and height are both 0, each border edge forms a triangle. Adjacent borders set to transparent hide two of the four triangles, leaving the desired shape. No images, no SVG, no JavaScript — pure CSS.
Open any classic CSS tutorial and you will eventually hit the border trick — the technique where setting width: 0 and height: 0 on an element turns its borders into geometric shapes. It is elegant, it works in every browser released in the last fifteen years, and it requires zero images or SVG. But remembering which border to color and which to set transparent, across eight possible directions, is a small mental tax every time. This generator removes that tax.
How the CSS Border Trick Creates Triangles
Every HTML element renders its borders as four trapezoids that share corners. When the element has zero width and zero height, those trapezoids collapse into four triangles meeting at a center point. Setting three of the four borders to transparent hides all but one triangle, leaving the visible shape you want.
For an upward-pointing triangle, for example, the bottom border becomes the visible face and the left and right borders form the two hidden sides:
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid #3B82F6;
}
The half-width of the triangle equals the border-left and border-right values. The full height equals the border-bottom value.
All 8 Directions Explained
Cardinal directions (up, down, left, right) use two transparent borders on the perpendicular axis and one colored border on the opposite side of the pointing direction:
| Direction | Colored border | Transparent borders |
|---|---|---|
| Up | border-bottom | border-left, border-right |
| Down | border-top | border-left, border-right |
| Left | border-right | border-top, border-bottom |
| Right | border-left | border-top, border-bottom |
Diagonal directions (top-left, top-right, bottom-left, bottom-right) use only two borders instead of three — one colored, one transparent — which produces a right-angle triangle in the chosen corner:
/* Top-left corner triangle */
.triangle {
width: 0;
height: 0;
border-top: 100px solid #3B82F6;
border-right: 100px solid transparent;
}
The generator handles the border assignments automatically for all eight directions. You set the size and color; it writes the CSS.
When to Use CSS Triangles vs. SVG
Use CSS triangles when:
- You need a simple decorative arrow, tooltip pointer, or speech bubble tail
- The shape is a standard triangle (right-angle or isosceles)
- You want zero additional HTTP requests or dependencies
- The shape needs to inherit or respond to CSS custom properties and transitions
Use SVG when:
- The triangle has rounded corners or complex geometry
- You need the shape to scale in non-uniform ways (e.g., very wide and very short)
- You need to animate individual path points
- The shape is part of a data visualization
For most UI components — dropdown arrows, breadcrumb separators, card corner accents, tooltip carets — CSS triangles are the lighter, simpler choice.
Responsive Considerations
CSS triangles do not scale automatically with font-size or viewport units the same way text does. For triangles that need to grow with their container, two approaches work well:
Use em units based on a parent font-size:
.tooltip-caret {
border-left: 0.5em solid transparent;
border-right: 0.5em solid transparent;
border-top: 0.75em solid #1e293b;
}
Scale with CSS custom properties:
:root { --caret-size: 8px; }
.caret {
border-left: var(--caret-size) solid transparent;
border-right: var(--caret-size) solid transparent;
border-top: calc(var(--caret-size) * 1.5) solid currentColor;
}
Using currentColor for the colored border is especially useful — the triangle automatically matches the text color of its parent, which simplifies theming and dark mode support.
Practical Code Examples
Dropdown chevron (downward triangle):
.dropdown-arrow {
display: inline-block;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 6px solid currentColor;
vertical-align: middle;
}
Tooltip pointer (upward triangle below a box):
.tooltip::after {
content: "";
display: block;
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #1e293b;
margin: 0 auto;
}
Corner ribbon accent (top-right diagonal):
.corner-ribbon {
position: absolute;
top: 0;
right: 0;
width: 0;
height: 0;
border-top: 60px solid #ef4444;
border-left: 60px solid transparent;
}
Frequently Asked Questions
Why does my triangle look wrong in Firefox?
Sub-pixel rendering differences between browsers can cause tiny gaps at the corners of CSS triangles. Add transform: rotate(0.001deg) to trigger GPU compositing, which often smooths the edges. Alternatively, switch to an SVG triangle for pixel-perfect control across all rendering engines.
Can I animate a CSS triangle?
You can animate properties like border-color (for color transitions), opacity, and transform (scale, rotate, translate) without issues. Animating the border-width values that define the shape itself is technically possible with transition, but the result can look uneven because the width and height change at different rates.
How do I center a triangle horizontally?
Wrap it in a flex or grid container with align-items: center and justify-content: center. The triangle itself has no width or height, so margin-based centering requires knowing the effective visual width, which equals the sum of the two perpendicular border values.
Can I add a border stroke to a CSS triangle?
Not directly — the CSS border property is consumed by the triangle technique itself. The standard workaround is to layer two triangles, with the larger one in the border color sitting behind the smaller one in the fill color, offset by the desired stroke width.
Does this technique work with CSS Grid and Flexbox?
Yes. A width: 0; height: 0 element participates in normal flow. Inside a flex container it takes up a layout slot based on its border extents. Use flex-shrink: 0 to prevent flexbox from collapsing it.