The shortest version: aria-hidden="true" is correct on a CSS triangle only when the shape is purely decorative and conveys no information the user actually needs. Once the triangle signals state, direction, validation, navigation, or any other meaning, or stands in for a control, hiding it from assistive technology removes exactly the signal that was missing. The border-triangle technique paints the entire shape with one colored CSS border against transparent borders on a zero-size content box, and the snippet copy-paste generators emit includes a single div with aria-hidden="true" and no inner text. That output is appropriate for a separator, a decorative chevron, or a visual flourish, and not appropriate for a meaningful glyph. The general rule, applied consistently across accessibility guidance for web UI, is straightforward: an element that is present only for visual treatment can be removed from the accessibility tree, while an element that communicates or triggers something must stay reachable through visible text, an accessible name, or a wrapping semantic control.

What aria-hidden Does, and What It Does Not
aria-hidden is one of the simplest ARIA states: a boolean value that removes an element and its descendants from the accessibility tree when set to "true", and leaves them visible to assistive technology when set to "false" or omitted. The attribute does not hide the element visually, does not stop pointer or keyboard interaction, and does not detach the element from the DOM. A screen reader user perceives aria-hidden="true" the same way a sighted user would if the element happened to be transparent or covered, without any announcement at all.
The hiding is also unforgiving in one direction: putting aria-hidden="true" on a parent removes every descendant too, which makes the attribute a clean way to drop whole decorative groups from the assistive layer. Putting the attribute on a control that already has an accessible name does not strip that name, because the accessible name is computed from the visible label, an aria-label, or aria-labelledby, not from the element's own text content. That is why a CSS triangle hidden inside a labelled button is genuinely safe: the announcement comes from the button, not from the triangle.
When aria-hidden Fits a CSS Triangle
The CSS Triangle Generator ships a single div with no inner text and the attribute aria-hidden="true". That pattern is the right one for any triangle that adds visual flavor without communicating anything the user would miss without it. Concrete examples include a small chevron drawn next to a heading that is already self-describing, a separator triangle between two unrelated card layouts, a decorative arrow at the start of an empty-state illustration, or a purely visual continuation of a colorful ribbon inside a hero banner. As long as a sighted user and a screen reader user get the same information from the surrounding text alone, the triangle can stay silent.
Removing aria-hidden in those cases would not improve the experience. It would inject stray "triangle" announcements into the screen reader output and force the user to skip past a meaningless fragment. The generator's default snippet is built for this exact use case, so the practical advice is to leave it untouched when the triangle is a visual ornament and reach for the upgrade steps only when the shape starts carrying meaning.
When aria-hidden on a Triangle Is the Wrong Call
The rule flips immediately the moment the triangle carries meaning. If the shape points to a directional cue that no other element expresses, paired with a "Continue" button, alongside a labeled step in a wizard, or pointing toward a "Next" affordance, hiding it discards the only signal. If the triangle is part of a validation message, like a red exclamation under a form field, it becomes part of that error message and must reach assistive technology. If the triangle replaces a control entirely, such as a tiny expand or collapse caret that is not wrapped in a button, the div needs to become the trigger, not the decoration.
In each of those cases the fix is to keep the visual triangle but stop hiding it from accessibility. The standard moves are: add an accessible name on the wrapping button or link, attach aria-describedby that points to the same text the triangle was visually emphasizing, or promote the triangle to its own interactive element with type="button", an aria-label, and keyboard handling in your script. The JS-free HTML the generator outputs cannot act as a control on its own; that upgrade is the developer's responsibility, and the snippet's aria-hidden attribute should be removed in the same edit so the new accessible name actually reaches assistive technology.
How to Generate a CSS Triangle With the Right Accessibility Treatment
The order below produces a border triangle and verifies which accessibility treatment fits the snippet the tool gives you. Working in a modern Chromium, Firefox, or Safari tab is enough; nothing leaves the browser tab.
- Open the CSS Triangle Generator in your browser tab and pick the triangle direction — up, down, left, or right — from the direction control.
- Type integer width and height values between 10 and 300 pixels; the form rejects decimals and out-of-range numbers without silently clamping.
- Enter a six-digit HEX color in the form "#rrggbb". The preview paints that color into the colored border immediately, while the two perpendicular transparent borders stay transparent.
- Inspect the live preview at roughly the size and on the background where the triangle will live. Adjust the surrounding padding or page zoom if you need to confirm the perceived size.
- Click Copy CSS to put the longhand border declarations on your clipboard, then click Copy HTML to copy the matching div with its generated class name and the aria-hidden="true" attribute.
- Decide whether the snippet's aria-hidden is correct for the destination. For a purely decorative triangle, paste the HTML verbatim. For a meaningful triangle, delete the aria-hidden attribute, wrap the div in a semantic control — button, link, or labelled container — with an accessible name, and update the CSS class name in both paste blocks so the stylesheet and the markup stay in sync.
- If your existing stylesheet already uses the default class (lizely-triangle), search for collisions and rename it consistently across both pasted blocks before shipping.
The Geometry Behind the Border-Triangle Snippet
The reason the copied HTML looks unusual is that the triangle's content width and content height are both zero, so nothing inside the element paints directly. The shape itself is drawn by CSS borders that meet at a point: two transparent borders form the two sloping sides, while the remaining border is filled with your chosen HEX color and points in the selected direction. The longhand is intentional and matches what the tool emits.
| Direction | Colored border | Transparent borders |
|---|---|---|
| Up | bottom | left, right |
| Down | top | left, right |
| Left | right | top, bottom |
| Right | left | top, bottom |
For vertical triangles (up or down), the two transparent side borders add up to the requested width and the colored border equals the requested height. For horizontal triangles (left or right), the transparent top and bottom borders add up to the requested height and the colored border equals the requested width. Even dimensions split the perpendicular base into two equal halves; odd totals are split with floor and ceiling values, such as 20px and 21px for a 41px base, because Chromium can otherwise quantize two equal 20.5px borders down to 20px each and silently lose a pixel of painted geometry. For broader background on how transparent borders behave in CSS, the MDN CSS backgrounds and borders guide documents the relevant properties, and the wider walkthrough of why the element starts at zero size lives in the CSS create triangle with border: the zero-size trick guide.
Accessibility Checks Before You Ship the Triangle
The generator preview confirms only the visual geometry; it does not exercise accessibility or layout behavior, so a short verification pass belongs in your workflow regardless of which accessibility treatment you chose.
| Check | Why it matters | What you are testing for |
|---|---|---|
| 200% browser zoom | Tests text and CSS scaling in real layouts | Triangle stays positioned and proportionate |
| Forced colors mode | Confirms Windows high contrast interpretation | Triangle remains visible against system colors |
| Light and dark themes | Surfaces inherited contrast assumptions | Decorative triangle does not disappear or clash |
| Keyboard focus plus screen reader | Confirms labelled use for non-decorative shapes | Wrapping control announces meaning, triangle stays aria-hidden when decorative |
If the triangle is purely decorative, leave the aria-hidden attribute intact and run the same checks; you are mainly confirming that it does not break with zoom or theme changes. If the triangle carries meaning, the relevant check is whether the surrounding control's accessible name fully captures the role the triangle was visually implying, so that removing the visual triangle would not change what a screen reader user hears. Border triangles are compact and inexpensive, but hundreds of decorative elements can still inflate DOM and paint work, so prefer one semantic control with a decorative shape over duplicated hidden controls wherever the design allows.
For a deeper look, see CMYK Color Chart with Codes: Look Up CSS HEX.