Question
How does this CSS triangle technique work, and why does it produce a triangle shape?
#triangle-up {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
<div id="triangle-up"></div>
I have seen many CSS shape examples, and this triangle pattern is especially confusing. I want to understand the underlying reason it works, not just copy the code.
Short Answer
By the end of this page, you will understand that CSS triangles are created by giving an element width: 0 and height: 0, then using its borders as visible angled edges. You will see why transparent side borders and one colored border form a triangle, how the browser draws it, and how to create triangles pointing in different directions.
Concept
CSS triangles are not a special built-in shape. They are a visual side effect of how borders are drawn around an element.
Normally, an element has content width and height, and borders are drawn around that rectangular box. But when you set:
width: 0;
height: 0;
the element itself has no visible rectangular area. The only thing left to render is its borders.
Each border still has thickness. When borders meet at the corners of a zero-sized box, the browser draws them as diagonal edges that meet at a single point. That creates four wedge-like triangular regions:
- top border
- right border
- bottom border
- left border
If all four borders have color, you would see a shape made of four triangles meeting in the center.
When three of those borders are transparent and one border has a visible color, only one triangular wedge remains visible.
In this example:
#triangle-up {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
what happens is:
- the left border creates a transparent triangle extending left
- the right border creates a transparent triangle extending right
- the bottom border creates a red triangle extending downward from the collapsed box
- there is no top border
Because the left and right borders are transparent and the bottom border is visible, the only visible result is a triangle.
This matters in real programming because it is a lightweight way to create arrows, tooltips, dropdown pointers, speech bubble tails, and directional indicators without images or SVG.
Mental Model
Imagine a point in the middle where four paper wedges meet:
- one wedge points up
- one wedge points right
- one wedge points down
- one wedge points left
Now imagine making three wedges invisible and leaving only one colored wedge visible. That single visible wedge looks like a triangle.
Another way to think about it:
- a normal box has a body and borders
- a zero-sized box has no body
- so only the borders remain
- the borders collapse into triangular slices around the center point
So a CSS triangle is really just one visible border slice of a box with no size.
Syntax and Examples
Core idea
.element {
width: 0;
height: 0;
}
Then use borders to create the visible triangle.
Up-pointing triangle
.up {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
This creates:
- a transparent left slant
- a transparent right slant
- a visible red bottom wedge
The visible result looks like a triangle pointing up.
Down-pointing triangle
.down {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 100px solid blue;
}
Here, the top border is visible, so the triangle points down.
Left-pointing triangle
.left {
width: 0;
height: 0;
border-top: 40px solid transparent;
border-bottom: 40px solid transparent;
border-right: 80px solid green;
}
Right-pointing triangle
.right {
width: 0;
height: 0;
border-top: 40px solid transparent;
border-bottom: 40px solid transparent;
border-left: 80px solid orange;
}
Important rule
The direction of the triangle is determined by the visible border, but the triangle appears to point toward the opposite side.
For example:
- visible
border-bottom-> triangle points up - visible
border-top-> triangle points down - visible
border-left-> triangle points right - visible
border-right-> triangle points left
Step by Step Execution
Consider this example:
.triangle {
width: 0;
height: 0;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom: 60px solid purple;
}
Step 1: The browser creates the element box
The element exists, but:
width: 0;
height: 0;
So it has no visible rectangular content area.
Step 2: Borders are still drawn
Even though the box has no area, borders can still have thickness:
- left border = 30px
- right border = 30px
- bottom border = 60px
Step 3: The borders meet at a single point
Since the box is zero-sized, the borders collapse inward and meet at the same center point.
Step 4: The browser draws angled joins
CSS border corners are drawn with diagonal joins. That means each border becomes a triangular region instead of a rectangle.
Step 5: Transparent borders become invisible
The left and right borders exist, but they are transparent:
border-left: 30px solid transparent;
border-right: 30px solid transparent;
They still take up geometric space, but you cannot see them.
Step 6: The colored border remains visible
border-bottom: 60px solid purple;
That bottom wedge is visible, so the final shape looks like a purple triangle.
Resulting dimensions
The visible triangle will have approximately:
- base width =
30px + 30px = 60px - height =
60px
So border sizes directly control triangle size.
Real World Use Cases
CSS triangles are commonly used in UI design because they are simple, fast, and require no image files.
Common uses
- Tooltip arrows: the little pointer connecting a tooltip to a button
- Speech bubble tails: a small triangle attached to a chat bubble
- Dropdown indicators: tiny arrows showing a menu can open
- Accordion icons: triangles indicating expand/collapse direction
- Callouts and popovers: small directional pointers on floating panels
- Breadcrumb separators: angled pointer-like shapes between items
Example: tooltip arrow
.tooltip-arrow {
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #333;
}
This creates a small arrow below a tooltip.
Why developers like this technique
- no external assets needed
- easy to recolor with CSS
- lightweight and fast to render
- works well for small decorative UI shapes
Real Codebase Usage
In real projects, developers usually do not leave triangle elements floating on their own. They are often attached to other components using pseudo-elements like ::before and ::after.
Common pattern: tooltip pointer with pseudo-element
.tooltip {
position: relative;
background: #333;
color: white;
padding: 8px 12px;
border-radius: 4px;
}
.tooltip::after {
content: "";
position: absolute;
left: 50%;
top: 100%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #333;
}
This is common because:
- it avoids extra HTML elements
- the arrow stays attached to the component
- the triangle can inherit component colors more easily
Other patterns in real code
- Configuration via CSS variables
.arrow {
--size: 10px;
--color: black;
width: 0;
height: 0;
border-left: var(--size) solid transparent;
border-right: var(--size) solid transparent;
border-top: var(--size) solid var(--color);
}
- State-based direction changes
For menus and accordions, developers often switch which border is visible depending on whether something is open or closed.
- Guarding layout issues
Triangles are usually absolutely positioned because they do not behave like normal rectangular boxes.
- Combining with shadows or outlines
Sometimes two triangles are layered to fake a border or outline around the arrow.
Common Mistakes
1. Forgetting width: 0 and height: 0
If the element has normal size, you will not get the clean border-only triangle effect.
Broken example:
.bad {
width: 100px;
height: 100px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
This creates a box with borders, not a simple triangle.
2. Coloring the wrong border
Beginners often expect border-top to create an upward triangle, but the visible border creates a triangle that points the opposite way.
/* Points down, not up */
border-top: 50px solid red;
3. Using transparent incorrectly
If side borders are not transparent, you will see extra wedges.
Broken example:
.bad {
width: 0;
height: 0;
border-left: 40px solid blue;
border-right: 40px solid green;
border-bottom: 80px solid red;
}
This shows multiple colored regions, not one clean triangle.
4. Expecting normal box sizing behavior
A CSS triangle has no content box, so properties like background color on the element itself will not show as expected.
.triangle {
width: 0;
height: 0;
background: red; /* not useful here */
}
5. Misunderstanding triangle size
The triangle width comes from the sum of the two side borders.
For example:
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 40px solid red;
This creates a triangle with:
- width: 40px
- height: 40px
6. Layout confusion
Because the element itself is zero-sized, spacing and positioning can be surprising. Often you will need position: absolute or margins to place it correctly.
Comparisons
| Technique | How it works | Best for | Limitations |
|---|---|---|---|
| CSS border triangle | Zero-sized box with one visible border | Small arrows, tooltip pointers, indicators | Not ideal for complex shapes |
clip-path: polygon(...) | Clips an element into a triangle | More flexible modern shapes | Slightly more advanced, may be overkill for tiny arrows |
| SVG triangle | Drawn with vector markup | Precise scalable graphics | More markup or separate asset |
| Image asset | Uses PNG/WebP/SVG file | Fixed decorative graphics | Less flexible for quick styling |
Border triangle vs clip-path
.triangle-clip {
width: 100px;
height: 100px;
background: red;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
clip-path creates a real filled shape from a normal box. The border trick creates a triangle from border geometry.
When to choose each
- Use border triangles for tiny UI arrows and pointers.
- Use clip-path when you want a triangle with normal width, height, background, or animation.
- Use SVG when you need precision, accessibility control, or more complex icons.
Cheat Sheet
/* Up */
.up {
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 40px solid red;
}
/* Down */
.down {
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 40px solid red;
}
/* Left */
.left {
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-right: 40px solid red;
}
/* Right */
.right {
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 40px solid red;
}
Rules to remember
- Set
width: 0andheight: 0 - Make unwanted borders
transparent - Keep one border colored
- The visible border determines the triangle shape
- Triangle width is usually the sum of the two adjacent transparent borders
- Triangle height is the size of the visible border
Quick direction guide
| Visible border | Triangle points |
|---|---|
border-bottom | Up |
border-top | Down |
border-left | Right |
border-right | Left |
Edge cases
backgrounddoes not create the triangle- borders still affect visual size even if the element is zero-sized
- transparent borders still matter geometrically
FAQ
Why does width: 0 and height: 0 still show something?
Because borders can still have thickness even when the content box has no size. The visible part is the border, not the element body.
Why does border-bottom create an upward triangle?
The bottom border forms the visible wedge under the collapsed center point, so the shape appears to point upward.
Can I use background-color instead of borders to make this triangle?
Not with this specific trick. The triangle comes from border geometry, not the element background.
Why are the side borders transparent instead of omitted?
They define the slanted edges and triangle width. If they are omitted, the shape will not look the same.
Can I add a border around a CSS triangle?
Not directly in the normal box sense. A common solution is to layer two triangles, one slightly larger behind the other.
Are CSS triangles responsive?
Yes. You can use relative units like em, rem, or CSS variables to scale them.
Is this still used in modern CSS?
Yes. It is still common for small arrows and pointers, even though clip-path and SVG are also popular.
Mini Project
Description
Build a small tooltip component with a text box and a CSS triangle arrow underneath it. This demonstrates how the border-based triangle technique is used in a practical interface element rather than as a standalone shape.
Goal
Create a tooltip with a centered arrow using only HTML and CSS.
Requirements
- Create a tooltip box with text inside.
- Add a triangle arrow below the box.
- Use a pseudo-element for the arrow instead of extra HTML.
- Center the arrow horizontally under the tooltip.
- Match the arrow color to the tooltip background.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
CSS :not() Selector for Elements Without a Class or Attribute
Learn how to use the CSS :not() selector to target elements that do not have a specific class or attribute, with examples and common pitfalls.
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.