発生した現象
FontAwesomeIcon にツールチップを表示させるために data-tooltip-id と data-tooltip-content を指定したところ、アイコンがフォーカス可能になってしまい、また、Blocked aria-hidden on an element because its descendant retained focus というエラーが発生してしまいました。
ブラウザは Chrome 138 を使用しました。Firefox 141 ではこのような現象は発生しませんでした。
このように、フォーカス可能になり、また、開発者ツールに警告が表示されています。
import React from 'react';
import { Tooltip } from 'react-tooltip';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faUser } from "@fortawesome/free-solid-svg-icons";
export function App() {
return (
<div>
This is icon:
<FontAwesomeIcon
data-tooltip-id="my-tooltip"
data-tooltip-content="Hello!"
icon={faUser}
/>
<Tooltip id="my-tooltip" />
</div>);
}
解決策
- FontAwesomeIcon を span で囲む
- span 側に
data-tooltip-idとdata-tooltip-contentを指定する
import React from 'react';
import { Tooltip } from 'react-tooltip';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faUser } from "@fortawesome/free-solid-svg-icons";
export function App() {
return (
<div>
This is icon:
<span
data-tooltip-id="my-tooltip"
data-tooltip-content="Hello!"
>
<FontAwesomeIcon
icon={faUser}
/>
</span>
<Tooltip id="my-tooltip" />
</div>);
}
直接の原因(詳しく知りたい人向け)
なぜこのような問題が発生してしまったのでしょうか。詳しく見ていきたいと思います。
FontAwesomeIcon を配置すると、svg 要素に以下の属性が指定されます。
<svg
aria-hidden="true"
focusable="false"
>
まず、 focusable="false" によって画像がフォーカス可能ではないということが明示されます。また、 aria-hidden="true" が指定されることで、スクリーンリーダーなどによる読み上げが避けられます。装飾目的でアイコンを使用する場合は、このようにすることで、冗長な読み上げを回避できるようになります。
しかし、その svg 要素対して react-tooltip が addEventListener('focus', ...) を呼び出すと、Chrome がその要素をフォーカス可能であると認識してしまいます。
// svg 要素に focus イベントリスナを追加
svgElement.addEventListener('focus', someHandler);
これによって、矛盾が発生し、ブラウザは警告を出すようになります。
具体的には以下のようなコードで現象を再現することができます。
import { useRef, useEffect } from "react";
export function App() {
const ref = useRef();
useEffect(() => {
if (ref.current != null) {
ref.current.addEventListener('focus', () => {
console.log("focus!");
});
}
}, [ref]);
return (
<div>
This is svg:
<svg
ref={ref}
viewBox="0 0 100 100"
aria-hidden="true"
>
<path fill="red" d="M10 10L90 10L90 90L10 90" />
</svg>
</div>
);
}
Chorome でこのコードを実行し、SVG 画像をクリックすると、以下のようなエラーが発生します。
Blocked aria-hidden on an element because its descendant retained focus.
The focus must not be hidden from assistive technology users.
Avoid using aria-hidden on a focused element or its ancestor.
Consider using the inert attribute instead, which will also prevent focus. For more details,
see the aria-hidden section of the WAI-ARIA specification at
https://w3c.github.io/aria/#aria-hidden.
Element with focus: <svg>
Ancestor with aria-hidden: <svg>
では、なぜ svg の場合だけ addEventListener でフォーカス可能になるのか【未解決】
では、なぜフォーカス可能になったのでしょうか。
たとえば、 div などの要素でも、 tabIndex= を明示的に指定すればフォーカス可能になります。しかし、Chrome 138 において、svg に対してはそのようなことをしなくても、 addEventListener('focus', ...) を指定するだけでフォーカス可能になりました。これはなぜなのでしょうか。
この点については調べましたがよく分かりませんでした! そういうブラウザの仕様なのかもしれません。いかがでしたか?
Which HTML elements can receive focus?
There isn't a definite list, it's up to the browser.


