Search code examples
htmlcsshtml-tableaccessibility

Does using regular div tags instead of table and related tags affect accessibility?


I have a table which should show a typical table layout on larger screens and should become a column view on smaller screens. For example.

Desktop

| Name  | age |
| Bob   | 48  |
| Jane  | 50  |

Mobile (The below show up as a list)

--------
Name:Bob,
Age: 48
-------
Name:Jane,
Age: 50

Would using regular div tags instead of the usual table mark up cause issues for accessibility?

The reason why I do not prefer the usual table markup is because it isn't flexible for complex UIs. For example if you want to add add a margin after each row you have to manipulate border-collapse border-spacing and do a whole bunch of other things.

My question is. Does using regular divs with grid/flex properties cause accessibility issues ? If yes how can we overcome it? Is there a way to make the screen reader interpret the divs as table elements?


Solution

  • Yes, using divs to mark up tabular information will cause accessibility issues. Assistive technologies can easily parse tables and provide users easy and consistent ways for navigating that information. Divs have no semantic meaning that assistive tech can parse—unless you carefully add appropriate aria-role attributes.

    Tables can be responsively styled to fit the layout changes you describe. My recommendation would be to use table elements and style them differently with media queries at smaller widths.

    Table styled as a table:

    table {
      border-collapse: collapse;
    }
    table th,
    table td {
      padding: 1ch;
      border: 1px solid black;
    }
    <table>
      <tr>
        <th>Name</th>
        <th>Age</th>
      </tr>
      <tr>
        <td data-heading="Name">Bob</td>
        <td data-heading="Age">48</td>
      </tr>
      <tr>
        <td data-heading="Name">Jane</td>
        <td data-heading="Age">50</td>
      </tr>
    </table>

    Same accessible table markup styled as a list:

    table,
    tbody,
    tr,
    td {
      display: block;
    }
    tr:first-child {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      white-space: nowrap;
      border-width: 0;
    }
    tr {
      border-top: 1px solid black;
      padding: 1ch;
    }
    td:before {
      content: attr(data-heading) ": ";
      font-weight: bold;
    }
    <table>
      <tr>
        <th>Name</th>
        <th>Age</th>
      </tr>
      <tr>
        <td data-heading="Name">Bob</td>
        <td data-heading="Age">48</td>
      </tr>
      <tr>
        <td data-heading="Name">Jane</td>
        <td data-heading="Age">50</td>
      </tr>
    </table>