Make WordPress Core


Ignore:
Timestamp:
07/23/2026 08:59:29 PM (2 months ago)
Author:
joedolson
Message:

Administration: Use post title column as table header in post lists.

The select column has been the th with row scope for post list tables since at least 2010. This results in a row name for screen readers that is based on the checkbox input and its label, which can be an empty value when that input is not available.

Move the th to the post title column, change the select column to td, and add aria-label to the th to provide a simplified row name to supporting screen readers.

Styles are additive, to retain support for custom list table implementations.

Developed in ​https://github.com/WordPress/wordpress-develop/pull/9761

Props afercia, abcd95, ozgursar, nikunj8866, joedolson.
Fixes #32892.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-list-table.php

    r62756 r62838  
    17691769
    17701770        /**
     1771         * Returns a clean, human-readable label for the primary column's row header.
     1772         *
     1773         * Used as the `aria-label` attribute value on the `<th scope="row">` element,
     1774         * giving screen readers a concise cell name instead of computing it from
     1775         * the full cell content (which may include row action links, excerpts, etc.).
     1776         *
     1777         * Subclasses should override this method to return the item's primary
     1778         * identifier (e.g. post title, plugin name, username). Return an empty string
     1779         * to omit the attribute.
     1780         *
     1781         * @since 6.9.0
     1782         *
     1783         * @param object|array $item The current item.
     1784         * @return string The aria-label value, or an empty string.
     1785         */
     1786        protected function get_primary_column_aria_label( $item ) {
     1787                return '';
     1788        }
     1789
     1790        /**
    17711791         * Generates the columns for a single row of the table.
    17721792         *
    … …  
    17971817
    17981818                        if ( 'cb' === $column_name ) {
    1799                                 echo '<th scope="row" class="check-column">';
     1819                                echo '<td class="check-column">';
    18001820                                echo $this->column_cb( $item );
    1801                                 echo '</th>';
     1821                                echo '</td>';
    18021822                        } elseif ( method_exists( $this, '_column_' . $column_name ) ) {
    18031823                                echo call_user_func(
    … …  
    18081828                                        $primary
    18091829                                );
    1810                         } elseif ( method_exists( $this, 'column_' . $column_name ) ) {
    1811                                 echo "<td $attributes>";
    1812                                 echo call_user_func( array( $this, 'column_' . $column_name ), $item );
     1830                        } else {
     1831                                $is_primary = ( $primary === $column_name );
     1832                                $tag        = $is_primary ? 'th' : 'td';
     1833                                $scope      = $is_primary ? ' scope="row"' : '';
     1834
     1835                                $aria_label = '';
     1836                                if ( $is_primary ) {
     1837                                        $label = $this->get_primary_column_aria_label( $item );
     1838                                        if ( '' !== $label ) {
     1839                                                $aria_label = ' aria-label="' . esc_attr( $label ) . '"';
     1840                                        }
     1841                                }
     1842
     1843                                echo "<$tag $attributes$scope$aria_label>";
     1844
     1845                                if ( method_exists( $this, 'column_' . $column_name ) ) {
     1846                                        echo call_user_func( array( $this, 'column_' . $column_name ), $item );
     1847                                } else {
     1848                                        echo $this->column_default( $item, $column_name );
     1849                                }
     1850
    18131851                                echo $this->handle_row_actions( $item, $column_name, $primary );
    1814                                 echo '</td>';
    1815                         } else {
    1816                                 echo "<td $attributes>";
    1817                                 echo $this->column_default( $item, $column_name );
    1818                                 echo $this->handle_row_actions( $item, $column_name, $primary );
    1819                                 echo '</td>';
     1852                                echo "</$tag>";
    18201853                        }
    18211854                }
Note: See TracChangeset for help on using the changeset viewer.