---
title: a11y/positive-tabindex · 正の tabindex
description: 0 より大きい tabindex はその要素をページ内の自然順のすべての要素より前に置き、たった1つの tabindex="1" がページ全体のキーボードナビゲーション順を組み替えてしまいます。
---

**重大度:** warning · **カテゴリ:** a11y

## チェック内容

リテラルの `tabindex` 属性の値が 0 より大きい有限数にパースされる要素を検出します。

```svelte
<div tabindex="1">Jumps the tab queue</div>
```

検出しないもの:

- `tabindex="0"`。要素は自然なタブ順に加わります。
- `tabindex="-1"`。プログラムからのみフォーカス可能になります。
- 式による `tabindex={expr}`。描画される値は静的に判定できません。
- 空の `tabindex`。不正な HTML で、ブラウザに無視されます。
- `Number()` でパースできない値、たとえば `tabindex="1abc"`。ブラウザは先頭の整数をパースします(その要素の `tabIndex` は実際に 1 になります)が、Svelte コンパイラ自身のチェックも同じ形でスキップします。ルールがコンパイラに従う理由は下の重複の節を参照してください。

## なぜ重要か

正の `tabindex` を持つ要素は、ページ内の自然順のすべての要素より前に来ます。そのためたった1つの `tabindex="1"` がドキュメント全体のキーボードナビゲーションを組み替えてしまい、被害は膨らみ続けます: 後から追加された正の `tabindex` を持たない要素は、視覚上どこにあってもすべてその後ろに並びます。タブ順は視覚上の順序から乖離しえて、WCAG 2.4.3 (Focus Order) が求める意味のあるフォーカス順が壊れます。安全な値は `0` と `-1` だけというのが広く合意されたガイダンスで、正の値が意図的かつ正しいことはまずありません。

## 修正方法

要素を DOM 順に配置して自然なタブ順に任せます。`tabindex="0"` はキーボードで到達させたい非インタラクティブ要素（たとえばスクロール領域）に限って使います。

```svelte
<div tabindex="0" role="region" aria-label="Release notes" class="scroll-box">…</div>
```

(クリックできるものにはネイティブの `<button>` を使ってください。それ自体でタブ順に加わります。)

プログラムからフォーカスする要素（スキップリンクのターゲットやダイアログなど）には `tabindex="-1"` を使います。

```svelte
<div tabindex="-1" bind:this={panel}>Focused from code</div>
```

## 制限事項

対象になるのは静的に名前が決まる要素のリテラルな `tabindex` 値だけで、カスタム要素も含まれるため、`<my-widget tabindex="1">` も検出されます。式による `tabindex`、それを供給しうるスプレッド属性、`<svelte:element>` による動的タグは静的解析の範囲外のため検出されません。

## Svelte コンパイラとの重複

コンパイラは同じマークアップに `a11y_positive_tabindex` を警告します。この重複は意図的です: コンパイラの警告はビルドログに流れるだけで、スコアもゲートも抑制もしません。一方このルールはヘルススコアに反映され、`svelte-vitals-disable-next-line` を尊重し、`--fail-on` で CI を失敗させられます。

2つのチェックは値のパース(`Number()` ベース)を共有しており、この整合の維持こそが、ルールが HTML の先頭整数パースを実装しない理由です。意図的な相違点が2つ残っており、どちらもこのルールはブラウザ側に付きます: 素の `<div tabindex>` はコンパイラが警告しますがこのルールは沈黙します(ブラウザはその要素に `tabIndex` -1 を与えます)。また `tabindex="Infinity"` のような非有限値やオーバーフローする数値もコンパイラは警告しますがこのルールは沈黙します(ブラウザはその値を無視します)。

## モードによる違い

ありません。このルールが読むのは同じ `.svelte` / `.ts` のソースファイルなので、CLI、Vite プラグインのビルド、ライブダッシュボードの静的ベースラインのいずれでも結果は同一で、レンダリング済み HTML の解析で再評価されることもありません。`--route` で実行範囲を絞ると、このルールは動きません。コンポーネントスコープのルールには、検出を紐づけるルートが無いためです。

## 無効化

正の値が本当に意図したものなら、`<!-- svelte-vitals-disable-next-line a11y/positive-tabindex -->` で個別の要素を黙らせるか、ルールを無効化します。

```js svelte-vitals.config.js
export default {
  rules: {
    'a11y/positive-tabindex': 'off'
  }
};
```
