How to rtl svg mirroring: which icons to mirror and which to keep
- Step 1Find your icon's category — Locate the icon type in the tables below. Each row gives the classification (mirror / keep / redesign) and the reason. When in doubt, ask: does this icon's meaning depend on reading direction? If yes, mirror; if it's a fixed real-world object or brand, keep.
- Step 2Record the decision in a manifest — Add the icon to a manifest with its bucket. This becomes your allowlist — the flip tool has no auto-detect, so this manifest is the only thing that decides what gets flipped.
- Step 3Flip only the mirror bucket — Run mirror-bucket icons through svg-rtl-mirror. It applies the
scale(-1,1) translate(-W,0)group and leaves keep/redesign icons alone (because you never send them). - Step 4Route redesign icons to a designer — Redesign-bucket icons (text-align, locale-specific symbols) need a new glyph, not a flip. Flag them for manual design and fail the build if a required RTL redesign is missing rather than shipping a wrong flip.
- Step 5Pre-process text-bearing icons — Any icon with live
<text>will mirror into reversed letters. Outline it with svg-font-to-path first, or (more often) keep it LTR and re-typeset the label per locale. - Step 6Verify in an RTL context — Render flipped icons inside a
dir="rtl"container and confirm directional shapes now read correctly for right-to-left order — not just that pixels moved. A back arrow should point right in RTL.
Mirror — flip these
Icons whose meaning is tied to reading direction. Send these to the flip tool.
| Icon | Why it mirrors |
|---|---|
| Back / forward arrows | 'Back' is leftward in LTR, rightward in RTL — must follow reading order |
| Chevrons (‹ ›) | Directional disclosure / pagination follows reading flow |
| Reply / forward (mail) | Reply curves back toward the start of reading; flips with direction |
| Undo / redo | Map to before/after in reading order |
| Progress / step indicators | Progress advances along the reading direction |
| Sliders / range with a leading edge | The 'start' side mirrors to the right in RTL |
| List item with a directional caret | The disclosure caret follows reading order |
Keep — never flip these
Icons with no left-right reading meaning, or with a fixed real-world orientation.
| Icon | Why it stays |
|---|---|
| Logos / brand marks | Fixed orientation; a mirror looks counterfeit |
| Clocks / watches | Run clockwise regardless of reading direction |
| Checkmarks, stars, hearts | Symmetric in meaning; no direction |
| Gears / settings | Rotationally symmetric; no left-right sense |
| Search (magnifier) | Universal symbol; handle position is conventional, not directional |
| Share / upload / download | Vertical-axis intent ('outward', 'up', 'down'), not reading-order |
| State icons (spinner, radio, toggle) | No directional meaning |
Redesign — a flip is wrong
Icons whose RTL form is a different glyph, not a mirror of the same one.
| Icon | Correct RTL behaviour |
|---|---|
| Text-align (left/right/center) | Swap to the direction-appropriate glyph, don't mirror |
| Indent / outdent | Becomes the opposite-direction glyph in RTL |
| Numbered / bulleted list with text | Re-typeset; mirroring reverses any embedded labels |
| Locale-specific symbols (currency, hands) | May need a culturally correct alternative |
Cookbook
Turn the classification into something a build can act on, and apply the flip only where it belongs.
Classification as a manifest
The reference becomes machine-readable. This is the allowlist the flip tool can't generate for you.
manifest.json
{
"arrow-back": "mirror",
"chevron-right":"mirror",
"reply": "mirror",
"logo": "keep",
"clock": "keep",
"search": "keep",
"format-align-left": "redesign"
}A correctly mirrored chevron
Geometry reflects; the path string is identical. This is what 'mirror' produces.
Input (chevron-right.svg): <svg viewBox="0 0 24 24"><path d="M9 6l6 6-6 6"/></svg> Output (chevron-right-rtl.svg): <svg viewBox="0 0 24 24"><g transform="scale(-1,1) translate(-24,0)"> <path d="M9 6l6 6-6 6"/> </g></svg> Points left in RTL → correct for 'next' in right-to-left flow.
The classic wrong flip: text-align
Mirroring align-left doesn't produce align-right cleanly — and the meaning is a swap, not a reflection. This is a redesign, not a mirror.
Wrong:
format-align-left.svg → svg-rtl-mirror
→ lines now hug the right, but it's a reflected align-left,
not the canonical align-right glyph your users expect.
Right:
In RTL, use the format-align-right SVG as the default-align icon.
Mark format-align-left as "redesign" and swap, don't flip.Don't flip the logo (the tool won't stop you)
The flip has no brand guard. Your allowlist is the guardrail.
Iterate only over mirror entries:
for (const [name, bucket] of Object.entries(manifest))
if (bucket === "mirror") flip(name); // logo skipped
Never: fs.readdirSync("icons").forEach(flip) // would flip logo!Share icon: keep, don't mirror
A frequent mis-call. The share arrow points up/out, which isn't a reading-direction concept.
share.svg → bucket: keep Reasoning: the arrow's intent is 'send outward', a vertical/ radial concept, not left↔right reading order. Mirroring it just makes a subtly different — and wrong — asset. Same logic: upload, download, expand, fullscreen.
Edge cases and what actually happens
Back arrow
MirrorPoints left in LTR (toward the start of reading); in RTL the start is on the right, so it must point right. Always mirror navigation arrows to match reading order.
Share / upload / download icons
KeepTheir arrows express 'outward / up / down', not reading direction. Mirroring produces a subtly wrong asset for no benefit. Leave share, upload, download, expand and fullscreen unflipped.
Settings / gear icon
KeepRotationally symmetric with no left-right meaning. Same for spinners, checkmarks, radio buttons and toggles — all stay as the single LTR file.
Text-alignment icons
Redesignalign-left should become the direction-appropriate alignment glyph in RTL — a swap to a different icon, not a reflection of the same one. Mirroring yields a misleading asset. Bucket as redesign.
Media play / pause
Usually keepContested. Many systems leave transport controls unmirrored because they map to a physical timeline, not reading order. Pick a convention and apply it consistently; the tool won't decide for you.
Clock / watch
KeepClocks run clockwise everywhere. Mirroring a clock makes it run anticlockwise — visibly wrong. Same for compasses and most measurement dials.
Logo or brand mark
AvoidFixed orientation; a mirror reads as counterfeit. The flip tool has no brand detection, so keep logos out of the mirror bucket and out of any batch run.
Icon with an embedded label
Renders reversedLive <text> mirrors into backwards letters. Outline with svg-font-to-path first, or keep the icon LTR and re-typeset the label per locale. Most text-bearing icons belong in keep or redesign.
Icon without a viewBox
Fallback W=24Even when an icon is correctly classified as mirror, a missing viewBox makes the flip default to W = 24, which can push a non-24-grid icon off-frame. Normalise viewBoxes (e.g. svg-viewbox-fixer) before flipping.
Frequently asked questions
Should a back arrow be mirrored?
Yes. In LTR it points left (toward where reading begins); in RTL reading begins on the right, so the back arrow must point right. Navigation arrows always follow reading direction — mirror them.
Should the share icon (box with up-arrow) be mirrored?
No. Its arrow points up/outward — a vertical concept, not a reading-direction one. Keep share, upload, download, expand and fullscreen unflipped. Mirroring them just creates a subtly wrong asset.
Should a settings / gear icon be mirrored?
No. Gears are rotationally symmetric with no left-right meaning. The same goes for spinners, checkmarks, radio buttons, and toggles — they stay as the single LTR file.
Should a text-alignment icon be mirrored?
No — it should be swapped, not flipped. In RTL, align-right becomes the default-alignment glyph. Mirroring align-left gives a reflected version that isn't the canonical glyph users expect. Treat text-align as a redesign case.
Should I mirror a clock icon?
No. Clocks run clockwise regardless of reading direction; mirroring makes them run backwards. Same logic applies to compasses, dials, musical notes and scientific diagrams.
Does the tool tell me whether an icon should be mirrored?
No. It has no classifier or auto-detect — it flips exactly what you send it. Use this reference to build an allowlist, and feed the tool only the mirror-bucket icons.
What does 'mirror' actually do to the file?
It wraps the content in <g transform="scale(-1,1) translate(-W,0)"> (W from the viewBox, default 24) and closes it before </svg>. The geometry reflects across the vertical axis and slides back into frame; your path data is left byte-for-byte unchanged.
What about media play/pause controls?
It's genuinely contested. Many design systems keep transport controls unmirrored because they map to a left-to-right timeline rather than reading order. Choose one convention, document it, and apply it across the whole set.
How do I align with Material Design and Apple HIG?
Material ships a per-icon RTL flag and flips flagged icons automatically in RTL; Apple's HIG gives directional guidance per symbol. Use both as a tie-breaker for ambiguous icons, and mirror your own classifications onto them.
What if my icon has text in it?
Mirroring reverses live <text> into unreadable glyphs. Outline it with svg-font-to-path before flipping, or keep it LTR and re-typeset per locale. Text-bearing icons usually belong in the keep or redesign bucket.
Is the flip tool free to use?
It's a Pro-tier tool; free accounts see an upgrade prompt. Once you have Pro, the flip runs in your browser (or locally via the runner) and nothing is uploaded.
Should I mirror an icon that's symmetric, just to be safe?
No need — a horizontally symmetric icon (a plus, a circle, a centred star) looks identical after scale(-1,1), so flipping it only adds a redundant <g transform> wrapper. Bucket symmetric icons as keep so they single-source from the LTR set rather than carrying a pointless flipped duplicate.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.