--- title: 'ARIA: grid ロール' slug: Web/Accessibility/ARIA/Roles/Grid_Role tags: - ARIA - ARIA Role - Accessibility translation_of: Web/Accessibility/ARIA/Roles/Grid_Role ---

\{{ariaref}}

grid ロールは、1つ以上のセルの行を含むウィジェット用です。 各セルの位置は重要であり、キーボード入力を使用してフォーカスすることができます。

<table role="grid" aria-labelledby="select-your-seat">
  <caption>座席を選んでください</caption>
  <tbody role="presentation">
    <tr role="presentation">
      <td></td>
      <th>列 A</th>
      <th>列 B</th>
    </tr>
    <tr>
      <th scope="row">島 1</th>
      <td tabindex="0">
        <button id="1a" tabindex="-1">1A</button>
      </td>
      <td tabindex="-1">
        <button id="1b" tabindex="-1">1B</button>
      </td>
      <!-- More Columns -->
    </tr>
    <tr>
      <th scope="row">島 2</th>
      <td tabindex="-1">
        <button id="2a" tabindex="-1">2A</button>
      </td>
      <td tabindex="-1">
        <button id="2b" tabindex="-1">2B</button>
      </td>
      <!-- More Columns -->
    </tr>
  </tbody>
</table>

(オプション)上記の例の簡単な説明を含めます。

説明

グリッドウィジェットには、テーマに関連するインタラクティブなコンテンツの1つ以上のセルを持つ1つ以上の行が含まれています。 それは特定の視覚的プレゼンテーションを意味するわけではありませんが、要素間の関係を意味します。 これは、チェックボックスやナビゲーションリンクなどのような単純なグループ化に使用します。 複雑なスプレッドシートアプリケーションにも使用できます。

セル要素には、行ヘッダーや列ヘッダーでない限り、gridcell ロールがあります。 ヘッダー要素ではそれぞれ rowheader ロールと columnheader ロールです。 セル要素は、row ロールを持つ要素によって所有される必要があります。 行は rowgroup を使用してグループ化できます。

グリッドをインタラクティブなウィジェットとして使用する場合は、{{anch("Keyboard interactions","キーボードインタラクション")}}を実装する必要があります。

 

関連する ARIA のロール、ステート、プロパティ

ロール

treegrid(サブクラス)
展開や折りたたみができる列を持つグリッドには、ツリーグリッドを使用できます。
row
グリッド内の行。
rowgroup
1つ以上の row を含むグループ。

ステートとプロパティ

aria-level
他の構造内のグリッドの階層レベルを示します。
aria-multiselectable
aria-multiselectabletrue に設定されている場合、グリッド内の複数の項目を選択できます。 デフォルト値は false です。
aria-readonly
ユーザーがグリッドをナビゲートできるが、グリッドの値を変更できない場合は、aria-readonlytrue に設定するべきです。 デフォルト値は false です。

多くのユースケースでは、HTML の table 要素で十分であり、その要素にはすでに多くの ARIA ロールが含まれています。

キーボードインタラクション

キーボードユーザーはグリッドに出会うと、のキーを使用して行と列をナビゲートします。 インタラクティブなコンポーネントをアクティブにするには、リターンキーとスペースキーを使用します。

キー 動作
1セル右にフォーカスを移動します。 フォーカスが行の右端のセルにある場合、フォーカスは移動しません。
1セル左にフォーカスを移動します。 フォーカスが行の左端のセルにある場合、フォーカスは移動しません。
1セル下にフォーカスを移動します。 フォーカスが列の最下部のセルにある場合、フォーカスは移動しません。
1セル上にフォーカスを移動します。 フォーカスが列の最上部のセルにある場合、フォーカスは移動しません。
Page Down 作成者が決定した行数だけ下にフォーカスを移動します。 通常、現在表示されている行セットの一番下の行が最初に表示される行の1つになるようにスクロールします。 フォーカスがグリッドの最後の行にある場合、フォーカスは移動しません。
Page Up 作成者が決定した行数だけ上にフォーカスを移動します。通常、現在表示されている行セットの一番上の行が最後に表示される行の1つになるようにスクロールします。 フォーカスがグリッドの最初の行にある場合、フォーカスは移動しません。
Home フォーカスを含む行の最初のセルにフォーカスを移動します。
End フォーカスを含む行の最後のセルにフォーカスを移動します。
ctrl + Home 最初の行の最初のセルにフォーカスを移動します。
ctrl + End 最後の行の最後のセルにフォーカスを移動します。

セル、行、列を複数選択できる場合は、次のキーの組み合わせが一般的に使用されます。

キーの組み合わせ 動作
ctrl + Space フォーカスを含む列を選択します。
shift + Space フォーカスを含む行を選択します。 グリッドに行を選択するためのチェックボックス付きの列が含まれている場合、このキーの組み合わせを使用して、フォーカスがチェックボックスにない場合でもそのボックスをチェックできます。
ctrl + A すべてのセルを選択します。
shift + 選択範囲を1セル右側に拡張します。
shift + 選択範囲を1セル左側に拡張します。
shift + 選択範囲を1セル下側に拡張します。
shift + 選択範囲を1セル上側に拡張します。

カレンダーの例

{{EmbedLiveSample("Calendar_example", "100%", "300")}}

 

HTML

<table role="grid" aria-labelledby="calendarheader">
  <caption id="calendarheader">September 2018</caption>
  <thead role="rowgroup">
    <tr role="row">
      <td></td>
      <th role="columnheader" aria-label="Sunday">S</th>
      <th role="columnheader" aria-label="Monday">M</th>
      <th role="columnheader" aria-label="Tuesday">T</th>
      <th role="columnheader" aria-label="Wednesday">W</th>
      <th role="columnheader" aria-label="Thursday">T</th>
      <th role="columnheader" aria-label="Friday">F</th>
      <th role="columnheader" aria-label="Saturday">T</th>
    </tr>
  </thead>
  <tbody role="rowgroup">
    <tr role="row">
      <th scope="row" role="rowheader">Week 35</th>
      <td>26</td>
      <td>27</td>
      <td>28</td>
      <td>29</td>
      <td>30</td>
      <td>31</td>
      <td role="gridcell" tabindex="-1">1</td>
    </tr>
    <tr role="row">
      <th scope="row" role="rowheader">Week 36</th>
      <td role="gridcell" tabindex="-1">
        2
      </td>
      <td role="gridcell" tabindex="-1">
        3
      </td>
      <td role="gridcell" tabindex="-1">
        4
      </td>
      <td role="gridcell" tabindex="-1">
        5
      </td>
      <td role="gridcell" tabindex="-1">
        6
      </td>
      <td role="gridcell" tabindex="-1">
        7
      </td>
      <td role="gridcell" tabindex="-1">
        8
      </td>
    </tr>
    <!-- … Additional Rows … -->
  </tbody>
</table>

CSS

table {
  margin: 0;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

tbody th, tbody td {
  padding: 5px;
}

tbody td {
  border: 1px solid #000;
  text-align: right;
  color: #767676;
}

tbody td[role="gridcell"] {
  color: #000;
}

tbody td[role="gridcell"]:hover, tbody td[role="gridcell"]:focus {
  background-color: #f6f6f6; outline: 3px solid blue;
}

JavaScript

var selectables = document.querySelectorAll('table td[role="gridcell"]');

selectables[0].setAttribute('tabindex', 0);

var trs = document.querySelectorAll('table tbody tr'),
    row = 0,
    col = 0,
    maxrow = trs.length - 1,
    maxcol = 0;

Array.prototype.forEach.call(trs, function(gridrow, i){
  Array.prototype.forEach.call(gridrow.querySelectorAll('td'), function(el, i){
    el.dataset.row = row;
    el.dataset.col = col;
    col = col + 1;
  });
  if (col>maxcol) { maxcol = col - 1; }
  col = 0;
  row = row + 1;
});

function moveto(newrow, newcol) {
  var tgt = document.querySelector('[data-row="' + newrow + '"][data-col="' + newcol + '"]');
  if (tgt && (tgt.getAttribute('role')==='gridcell') ) {
    Array.prototype.forEach.call(document.querySelectorAll('[role=gridcell]'), function(el, i){
      el.setAttribute('tabindex', '-1');
    });
    tgt.setAttribute('tabindex', '0');
    tgt.focus();
    return true;
  } else {
    return false;
  }
}

document.querySelector('table').addEventListener("keydown", function(event) {
  switch (event.key) {
    case "ArrowRight":
      moveto(parseInt(event.target.dataset.row, 10), parseInt(event.target.dataset.col, 10) + 1);
      break;
    case "ArrowLeft":
      moveto(parseInt(event.target.dataset.row, 10), parseInt(event.target.dataset.col, 10) - 1);
      break;
    case "ArrowDown":
      moveto(parseInt(event.target.dataset.row, 10) + 1, parseInt(event.target.dataset.col, 10));
      break;
    case "ArrowUp":
      moveto(parseInt(event.target.dataset.row, 10) - 1, parseInt(event.target.dataset.col, 10));
      break;
    case "Home":
      if (event.ctrlKey) {
        var i = 0;
        var result;
        do {
          var j = 0;
          var result;
          do {
            result = moveto(i, j);
            j++;
          } while (result == false);
          i++;
        } while (result == false);
      } else {
        moveto(parseInt(event.target.dataset.row, 10), 0);
      }
      break;
    case "End":
      if (event.ctrlKey) {
        var i = maxrow;
        var result;
        do {
          var j = maxcol;
          do {
            result = moveto(i, j);
            j--;
          } while (result == false);
          i--;
        } while (result == false);
      } else {
        moveto(parseInt(event.target.dataset.row, 10), document.querySelector('[data-row="' + event.target.dataset.row + '"]:last-of-type').dataset.col);
      }
      break;
    case "PageUp":
      var i = 0;
      var result;
      do {
        result = moveto(i, event.target.dataset.col);
        i++;
      } while (result == false);
      break;
    case "PageDown":
      var i = maxrow;
      var result;
      do {
        result = moveto(i, event.target.dataset.col);
        i--;
      } while (result == false);
      break;
    case "Enter":
      alert(event.target.textContent);
      break;
  }
  event.preventDefault();
});

 

より多くの例

他の例を以下で見つけることができます。

アクセシビリティに関する懸念

{{anch("Keyboard interactions","キーボードインタラクション")}}が適切に実装されていても、矢印キーを使用する必要があることに気づかないユーザーもいます。 grid ロールを使用して、必要な機能とインタラクションが最善にアーカイブできることを確認してください。

仕様

仕様 状態
{{SpecName("ARIA","#grid","Role Grid")}} {{Spec2('ARIA')}}
{{SpecName("ARIA Authoring Practices","#grid","Role Grid")}} {{Spec2('ARIA Authoring Practices')}}

スクリーンリーダーのサポート

TBD

関連情報