What is the most "Semantic" way of adding svg's inside button elements?

Like this
<button class="btn__nav hamburger"
value="<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='1' stroke-linecap='round' stroke-linejoin='round' class='feather feather-menu'><line x1='3' y1='12' x2='21' y2='12'></line><line x1='3' y1='6' x2='21' y2='6'></line><line x1='3' y1='18' x2='21' y2='18'></line></svg>">
Menu
</button>
<button class="btn__nav hamburger"
value="<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='1' stroke-linecap='round' stroke-linejoin='round' class='feather feather-menu'><line x1='3' y1='12' x2='21' y2='12'></line><line x1='3' y1='6' x2='21' y2='6'></line><line x1='3' y1='18' x2='21' y2='18'></line></svg>">
Menu
</button>
Or like this
<button class="btn__nav hamburger">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</button>
<button class="btn__nav hamburger">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</button>
8 Replies
Zakum
Zakum9mo ago
Definitely the 2nd option, the first one is harder to read through and may be an XSS vulnerability, and I'm not sure if you can even do that?
Zakum
Zakum9mo ago
that being said this article might be an interesting read on SVG accessibility https://www.smashingmagazine.com/2021/05/accessible-svg-patterns-comparison/
Smashing Magazine
Accessible SVGs: Perfect Patterns For Screen Reader Users — Smashin...
Discover which SVG patterns we should avoid and which patterns are the most inclusive when comparing different combinations of OSs, browsers, and screen readers.
Zoë
Zoë9mo ago
Neither. <use href="..."/> is better. I have an example of it in this pen https://codepen.io/z-/pen/bvpprw (warning, it's old) At the top of the file I declare an SVG with various symbols and then inside the buttons I have
<svg>
<use href="#tennisball"/>
</svg>
<svg>
<use href="#tennisball"/>
</svg>
ἔρως
ἔρως9mo ago
don't forget to set the "global" svg as role="none" and with tabindex="-1" and completely hidden you just need to add a <symbol> into that svg, and the id needs to match the href in the <use> additionally, set a width and height on your svg a little trick: set stroke="currentColor" to have the svg match the color of the text
dysbulic 🐙
dysbulic 🐙9mo ago
I almost never set a fixed width or height on my SVGs. If the viewBox="<x-start> <y-start> <width> <height>" i.e. viewBox="0 0 150 100" is set and the width and height are not browsers will resize them to fit their container.
ἔρως
ἔρως9mo ago
that's awful if the css takes a bit too long to load, you see a MASSIVE svg always set a width and height on your svgs that also can have SEO implications, as google measures the content layout shift, and having a massive svg that takes the entire screen can cause huge amounts of layout shifting a viewbox is not a substitute for a width and height, but both should be used together, when it makes sense
dysbulic 🐙
dysbulic 🐙9mo ago
You can have other containing boxes than the SVG. If you've omitted width and height (or set them to 100%), you can choose the size of your box via attributes or CSS. If you fix the size in the image, you can only ever use that image at one resolution despite its inherent lossless scalability. SVGs without a width and height are known as "responsive". Inkscape preserves them and outputs them from its optimizer. Illustrator CC reportedly outputs them by default. I've done literally hundreds of SVG-based pages (a placeholder for ship.via.autos was this week's) and I never fix the size of the image in the source file. A good asset will often be reused in dozens of places & to have it be set to one size is just silly. That said, maybe if you've got an inline SVG that'll never be referenced from somewhere else and that has no containing block, maybe you'd consider setting dimensions on the image. For doing standalone art, however, always only set the viewBox.
ἔρως
ἔρως9mo ago
if you're using icons and stuff, always set the width and height not of the original svg, if you use <use>, but of the svg with <use> in it if you're doing "art" or a placeholder and the parent has a size defined in a critical/above-the-fold css style, then you can do whatever you want a viewbox doesn't control the width and height, and will flash in whatever width and height it decides it wants to be, until the css kicks in, if it is in an external file