Why is this an issue?

The scope attribute tells assistive technology which cells a table header labels: it associates a th cell with the row(s) or column(s) it applies to, so a screen reader can announce the correct header when a user navigates through the data cells.

The HTML specification only defines scope on the th element: it is, in the words of the specification itself, "only conforming for th elements". Placing it on any other element does not associate that cell with anything, so users relying on assistive technology get no benefit from it, and the markup becomes invalid.

The td element is a special case: HTML4 allowed scope on a data cell, but HTML5 deprecated that usage, keeping scope valid only on th. Code that still carries scope on a td is most likely leftover from that older practice.

Move the scope attribute to the th element that acts as the header for the row, column, row group, or column group, or remove the attribute if the element is not a table header.

This rule does not flag scope on tags that don’t exactly match a native HTML element name: custom JSX components (e.g. <CustomCell scope="row">), kebab-case custom elements (e.g. <my-element scope="row">), and even native-looking tags in the wrong case (e.g. <TH scope="row">), since JSX treats these as component references that static analysis cannot resolve to a DOM element.

Code examples

Noncompliant code example

function Row() {
  return <div scope="row">Total</div>;
}

Compliant solution

function Row() {
  return <th scope="row">Total</th>;
}

Resources

Documentation