diff --git a/plugin/src/svg/serialize.ts b/plugin/src/svg/serialize.ts index eced28e..895d484 100644 --- a/plugin/src/svg/serialize.ts +++ b/plugin/src/svg/serialize.ts @@ -36,14 +36,18 @@ export function createSymbol(symbolId: string, data: SvgData): LosslessEntry { * Assembles a complete sprite sheet SVG from an array of `` entries. * * The sprite is an `` element with `xmlns` and `xmlns:xlink` attributes, - * hidden via `style="display:none"`, containing all the symbols. + * hidden via `aria-hidden` and `position:absolute;width:0;height:0;overflow:hidden` + * so it occupies no space and is invisible to assistive technology. + * `display:none` is intentionally avoided — Firefox has a bug where `` + * content such as `` and `` does not render correctly + * when referenced via `` from a sprite container with `display:none`. * * @param symbols Array of `` lossless entries (from `createSymbol`). * @returns The sprite SVG as a string. * * @example * const sprite = assembleSprite([symbol1, symbol2]); - * // → '......' + * // → '' */ export function assembleSprite(symbols: LosslessEntry[]): string { const entries: LosslessEntry[] = [ @@ -53,7 +57,8 @@ export function assembleSprite(symbols: LosslessEntry[]): string { $attr: { xmlns: 'http://www.w3.org/2000/svg', 'xmlns:xlink': 'http://www.w3.org/1999/xlink', - style: 'display:none', + 'aria-hidden': 'true', + style: 'position:absolute;width:0;height:0;overflow:hidden', }, }, ...symbols, diff --git a/plugin/test/e2e/vanilla.spec.ts b/plugin/test/e2e/vanilla.spec.ts index 7540686..940a74d 100644 --- a/plugin/test/e2e/vanilla.spec.ts +++ b/plugin/test/e2e/vanilla.spec.ts @@ -184,7 +184,7 @@ test.describe('Vanilla DOM — embedded sprite (animations page)', () => { test('animated sprite is inlined in animations.html', () => { const html = readDistFile('vanilla', 'animations.html'); expect(html).toContain(' { expect(sprite).toContain('xmlns:xlink="http://www.w3.org/1999/xlink"'); }); - it('hides the sprite with display:none', () => { + it('hides the sprite container without display:none', () => { const data = parseSvg(readFixture('simple.svg')); const symbol = createSymbol('abc123', data); const sprite = assembleSprite([symbol]); - expect(sprite).toContain('style="display:none"'); + expect(sprite).toContain('aria-hidden="true"'); + expect(sprite).toContain('position:absolute'); + expect(sprite).not.toContain('display:none'); }); it('includes multiple symbols', () => {