CSS Arrow Generator
Generate CSS chevron arrows pointing in any of 8 directions. Pure CSS using border-top + border-right + transform.
CSS generated is free to use — no attribution required.
How do CSS arrows work?
A chevron arrow is a square element with only two borders — say border-top and border-right — rotated with transform: rotate(). The two borders form a right angle, and rotating that angle points it wherever you need.
Because it is built from borders on an empty element, it needs no markup beyond a single span, or no markup at all if you build it on a ::after pseudo-element.
What are the CSS arrow direction rotation angles?
With border-top and border-right set, the angle bracket points up-right at rest. Rotate 45 degrees to point right, 135 to point down, 225 to point left and 315 to point up.
Leave the rotation at 0, 90, 180 or 270 degrees instead and you get the diagonal arrows, which are what you want for corner indicators and expand controls.
How do you size a CSS arrow correctly?
Two values control it independently: the element’s width and height set the arm length, and border-width sets the stroke thickness. A 10px square with a 2px border gives a small, light chevron; the same square with a 4px border reads as bold.
Keep the element square unless you deliberately want an asymmetric arrow, and use whole pixels — fractional border widths on a rotated element land off the pixel grid and render soft.
How do you center an arrow after rotating it?
Rotation happens around the element’s center by default, but the visible chevron is not centered inside its own box — it occupies the top-right corner. So an arrow that looks centered before rotation drifts afterwards.
The fix is to nudge it back with a translate in the same transform, as in transform: rotate(45deg) translate(-2px, 2px), or to position it with flexbox on the parent and accept a small optical offset. Setting transform-origin is rarely the right lever here — it changes the pivot, not the imbalance.
How do you style a CSS arrow?
The arrow inherits everything a border can do: border-color sets the color, and because the default is currentColor it will follow the text color if you leave it alone. Adding border-radius: 2px softens the tip into a modern rounded chevron.
For a hover or state change, transition transform rather than swapping classes with different border sides — rotating from 135 to 315 degrees animates an accordion caret smoothly, where changing borders would jump.
How do you create filled CSS arrow shapes with clip-path?
For filled arrow shapes rather than outlines, use clip-path: polygon(). See the clip path generator for arrow and chevron polygon presets.
The advantage over the border technique is that a clipped element keeps a real box, so it can carry a background gradient or an image. The border chevron can only ever be a solid color, since it is made of borders.
How do you make an arrow accessible?
An arrow is almost always decoration, and decoration should be invisible to assistive technology. If it lives in its own element, mark it aria-hidden="true"; if it is a pseudo-element it is already ignored, which is a good reason to prefer that approach.
The important part is that the arrow must not be the only thing conveying meaning. An accordion trigger needs aria-expanded so the state is announced, not just a caret that visually rotates.
What is the browser compatibility for CSS arrows?
Both techniques are safe. Borders and transform: rotate() are universally supported without prefixes, and clip-path with polygon() works in all current browsers. There is nothing here that needs a fallback.