[{"data":1,"prerenderedAt":10},["ShallowReactive",2],{"guide-accessible-icon-buttons":3},{"slug":4,"title":5,"description":6,"date":7,"order":8,"html":9},"accessible-icon-buttons","Accessible icon buttons with SVG icons","How to label icon-only buttons, hide decorative icons from screen readers, keep touch targets large enough, and meet contrast requirements.","2026-09-23",6,"\u003Cp>Icons make interfaces compact, but an icon on its own tells a screen reader nothing, and a tiny icon is hard to tap. Accessibility problems with icons come down to four things, and each has a small, reliable fix.\u003C\u002Fp>\n\u003Ch2>1. Decide: decorative or meaningful?\u003C\u002Fh2>\n\u003Cp>Every icon is one or the other.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Decorative:\u003C\u002Fstrong> the icon repeats information that&#39;s already in visible text. For example, a trash icon next to the word &quot;Delete&quot;. Screen readers should skip it.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Meaningful:\u003C\u002Fstrong> the icon is the only way the information is shown. For example, an icon-only button, or a warning icon with no text. Screen readers need a text alternative.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>2. Hide decorative icons\u003C\u002Fh2>\n\u003Cp>For inline SVG, add \u003Ccode>aria-hidden=&quot;true&quot;\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-html\">&lt;button type=&quot;button&quot;&gt;\n  &lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; …&gt;…&lt;\u002Fsvg&gt;\n  Delete\n&lt;\u002Fbutton&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>focusable=&quot;false&quot;\u003C\u002Fcode> stops older versions of Internet Explorer and legacy Edge from putting the SVG in the tab order. It&#39;s harmless to keep.\u003C\u002Fp>\n\u003Cp>For \u003Ccode>&lt;img&gt;\u003C\u002Fcode>, use an empty \u003Ccode>alt\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-html\">&lt;img src=&quot;\u002Ficons\u002Fic_fluent_delete_24_regular.svg&quot; alt=&quot;&quot;&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>An empty \u003Ccode>alt\u003C\u002Fcode> is not the same as a missing one. Without \u003Ccode>alt\u003C\u002Fcode>, some screen readers read out the file name, &quot;ic fluent delete 24 regular&quot;, which is worse than nothing.\u003C\u002Fp>\n\u003Ch2>3. Label icon-only controls\u003C\u002Fh2>\n\u003Cp>Put the accessible name on the \u003Cstrong>interactive element\u003C\u002Fstrong>, not the icon:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-html\">&lt;button type=&quot;button&quot; aria-label=&quot;Delete file&quot;&gt;\n  &lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; …&gt;…&lt;\u002Fsvg&gt;\n&lt;\u002Fbutton&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Guidelines for good labels:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Describe the action, not the picture.\u003C\u002Fstrong> &quot;Delete file&quot;, not &quot;Trash can&quot;.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Be specific when there are several.\u003C\u002Fstrong> On a list of files, &quot;Delete report.pdf&quot; is clearer than five buttons all called &quot;Delete&quot;.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Match any tooltip.\u003C\u002Fstrong> If you show a tooltip, its text should match the label, so sighted and non-sighted users hear the same name.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>For toggle buttons, add state:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-html\">&lt;button type=&quot;button&quot; aria-label=&quot;Favorite&quot; aria-pressed=&quot;true&quot;&gt;…&lt;\u002Fbutton&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Screen readers announce &quot;Favorite, toggle button, pressed&quot;. The filled\u002Fregular icon swap covers the visual side. See \u003Ca href=\"\u002Fguides\u002Ffilled-vs-regular-icons\u002F\">filled vs. regular icons\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2>4. Make targets big enough\u003C\u002Fh2>\n\u003Cp>A 24&nbsp;px icon is a comfortable size to \u003Cem>see\u003C\u002Fem>, but a small target to tap. WCAG 2.2 sets a minimum target size of 24&nbsp;×&nbsp;24 CSS pixels, with some exceptions. Many design systems aim for 40–48&nbsp;px on touch devices. You don&#39;t need a bigger icon, just more padding:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-css\">.icon-button {\n  display: inline-grid;\n  place-items: center;\n  min-width: 44px;\n  min-height: 44px;\n  padding: 10px;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>5. Check contrast\u003C\u002Fh2>\n\u003Cp>Icons that convey meaning need enough contrast against their background. WCAG asks for at least \u003Cstrong>3:1\u003C\u002Fstrong> for graphical objects needed to understand the content. The default Fluent gray, \u003Ccode>#212121\u003C\u002Fcode>, easily passes on white. Light grays often don&#39;t: \u003Ccode>#a0a0a0\u003C\u002Fcode> on white is below 3:1. If you use \u003Ccode>currentColor\u003C\u002Fcode>, the icon inherits the text color, and text colors are usually chosen with contrast in mind already.\u003C\u002Fp>\n\u003Ch2>6. Don&#39;t forget focus styles\u003C\u002Fh2>\n\u003Cp>Icon buttons need a visible focus indicator, just like text buttons. Avoid \u003Ccode>outline: none\u003C\u002Fcode> unless you replace it:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-css\">.icon-button:focus-visible {\n  outline: 2px solid #0f6cbd;\n  outline-offset: 2px;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>Quick checklist\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Decorative icons have \u003Ccode>aria-hidden=&quot;true&quot;\u003C\u002Fcode> or \u003Ccode>alt=&quot;&quot;\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Icon-only buttons and links have an \u003Ccode>aria-label\u003C\u002Fcode> that describes the action\u003C\u002Fli>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Toggles use \u003Ccode>aria-pressed\u003C\u002Fcode> (or \u003Ccode>aria-current\u003C\u002Fcode> for navigation)\u003C\u002Fli>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Targets are at least 24&nbsp;×&nbsp;24&nbsp;px, ideally 44&nbsp;px on touch\u003C\u002Fli>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Meaningful icons have 3:1 contrast or better\u003C\u002Fli>\n\u003Cli>\u003Cinput disabled=\"\" type=\"checkbox\"> Focus is clearly visible\u003C\u002Fli>\n\u003C\u002Ful>\n",1790215639598]