a11y/permitted-contents · 許可されたコンテンツ
すべての要素は、HTML のコンテンツモデル上、親要素に許可されたコンテンツでなければなりません。
Severity: warning(構造の破壊)/ info(カテゴリ不一致)。下記参照
チェック内容
リテラルな子要素はすべて、リテラルな親要素の許可コンテンツ集合のメンバーでなければなりません。判定は
HTML のコンテンツモデル(他の要素系ルールと同じ vendored spec データ)に基づきます。判定するのは
メンバーシップのみです。順序や個数は、コンポーネントや {#if}/{#each} ブロックがあると
静的には判定できないため対象外です。制御フローブロック内の子も、囲んでいる要素の子として
数えます。transparent な要素
(<a>、<ins>、<del> など)は問いを上に渡します: <ul><a href="…"><strong> の <strong> は
<ul> のモデルで判定されます。dl > div のスタイリングラッパーをはじめ、spec が定義する条件付き
モデルはすべて尊重します。
重大度は帰結で分かれます。
- warning。支援技術が頼る構造を壊す違反です: 親が特定の要素しか許可しない場合(
<ul>、<ol>、<table>、<select>、<hgroup>など)、見出しがどちらかの向きで境界を跨ぐ場合 (<button><h5>、<h2><div>)、構造に束縛されたタグが容れ物の外にある場合(<div><li>)。 - info。カテゴリ不一致(
<button><div>、<label><div>)で、 spec 違反ですが、ブラウザは レンダリングし、実害は小さいクラスです。
意図的に報告しないもの:
<option>/<optgroup>の子。Svelte コンパイラは<option>内のリッチなコンテンツを意図的に 許可しており、コンパイラと spec データが食い違う場所ではコンパイラが勝ちます。- インタラクティブ要素のネスト(
<a href><button>、リンク内のどこかにある<button>)。a11y/interactive-nestingがその判定を持ちます。この ルールはコンテンツモデル側の半分だけを報告するので、1 つの欠陥が 2 つの検出になることは ありません。 - 静的な走査が見通せない境界を跨ぐもの: コンポーネントタグ、
<svelte:element>、<slot />、{@render}、{@html}。{#snippet}の本体は宣言を囲む要素とは無関係に、それ自体で判定されます。 - カスタム要素(ダッシュを含むタグ)、未知のタグ、SVG サブツリー、テキストの子。
なぜ重要か
親の許可コンテンツの外にある要素は、支援技術が誤って読み上げるマークアップです: 子が <div> の
<ul> は「項目のないリスト」として、リストの外の <li> は意味を失って読み上げられ、<button> 内の
見出しはアウトライン上の役割を失うか汚染します。Svelte コンパイラがエラーにするのはブラウザが修復
してしまうサブセット(直接書かれた <p><div>)だけで、このルールが報告するものはすべて静かに
コンパイルされます。
修正方法
子を親が許可する要素に移すか、容れ物を変えます。
<!-- before -->
<ul>
<div>Item one</div>
</ul>
<!-- after -->
<ul>
<li>Item one</li>
</ul>
ブロックレイアウトが必要な <button> では、<div> をネストせず <span> にスタイルを当てます
(phrasing コンテンツに display: block を指定するのは問題ありません)。
モードによる違い
ありません。このルールが読むのは同じ .svelte / .ts のソースファイルなので、CLI、Vite
プラグインのビルド、ライブダッシュボードの静的ベースラインのいずれでも結果は同一で、レンダリング済み
HTML の解析で再評価されることもありません。--route で実行範囲を絞ると、このルールは動きません。
コンポーネントスコープのルールには、検出を紐づけるルートが無いためです。
無効化
検出された行の直上にインラインの svelte-vitals-disable-next-line コメントを置けば、その 1 件を
抑制できます。既存の検出を suppressions ファイルに記録する(npx svelte-vitals --update-suppressions)、overrides でルートやパスごとに範囲を絞る、または次のように無効化します。
export default {
rules: {
'a11y/permitted-contents': 'off'
}
};