Problem/Motivation
This modules fixes the header problem in CK5 but it would be nice if it focuses on all accessibility issues. I have a custom module with a filter that fixes:
- scope in th
- changing the first th (top left cell) in thead into a tr when it is empty ( ). Sure its better to not leave it empty but when it happens this is better.
- wrap the table in a div to make it scrollable over the x-axes
- add tabindex=0 to the table to make it focussable. in some browsers necesary to make table accessible for keyboard users
One other thing that would be nice to be able to do is to make the top left cell not scope col but scope row while being inside the thead. For example see attached image. The top left cells explains what A B C D are. But A B C and D should be a th aswell for the columns.
Ps. asking for this because I feel you can do this better than I can, I'm not a developing wizard so adding my code so you can see what I did.
class A11yCkeFix extends FilterBase {
public function process($text, $langcode) {
// Change the first <th> in <thead> when its content is without creating a new <th>
$pattern = '/(<thead><tr>)<th> <\/th>/';
$replacement = '$1<td> </td>';
$text = preg_replace($pattern, $replacement, $text);
// Find all theads's
preg_match_all('/(<thead>.*?<\/thead>)/s', $text, $matches);
$thead_sections = $matches[0];
foreach ($thead_sections as $thead) {
// Add col scope to th in thead
$modified_thead = preg_replace('/(<th\b(?![^>]*\bscope="col\b)[^>]*)(>)/', '$1 scope="col"$2', $thead);
$text = str_replace($thead, $modified_thead, $text);
}
// Find all tbody's
preg_match_all('/(<tbody>.*?<\/tbody>)/s', $text, $matches);
$tbody_sections = $matches[0];
foreach ($tbody_sections as $tbody) {
// Add row scope to th in tbody
$modified_tbody = preg_replace('/(<th\b(?![^>]*\bscope="row\b)[^>]*)(>)/', '$1 scope="row"$2', $tbody);
$text = str_replace($tbody, $modified_tbody, $text);
}
// Wrap div around table and make table focusable
$text = preg_replace('/<table>/', '<div class="table-responsive"><table tabindex="0">', $text);
$text = preg_replace('/<\/table>/', '</table></div>', $text);
$result = new FilterProcessResult($text);
return $result;
}
}
| Comment | File | Size | Author |
|---|---|---|---|
| Screenshot 2024-09-19 at 15.07.20.png | 37.65 KB | zebda |
Issue fork table_header_scope_attribute-3475552
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
zebda commentedComment #3
zebda commentedComment #4
zebda commentedComment #5
watergate commentedComment #6
watergate commentedComment #8
watergate commented@zebda, thanks for creating this issue and sharing accessibility improvements.
I've created a merge request that ensures empty
<th>elements don't receive ascopeattribute and that any existingscopeattributes aren't overwritten, so manual adjustments remain possible. This MR also includes additional test coverage for these cases. Any feedback is welcome.To replace empty
<th>elements with<td>elements, I've opened a separate issue to handle it as a new/additional text filter. This allows administrators to choose whether they want to apply this functionality. See #3554443: Add a filter plugin to replace empty <th> elements with <td>Regarding wrapping tables in a scrollable container and adding
tabindex=0, that functionality is already provided by the Responsive Table Filter module. To improve table accessibility, both modules can be installed together on a site, as they complement each other.As for allowing the top-left header cell in the
<thead>to usescope="row", that’s an interesting (edge) case. At this moment, I don't see an easy way to do this automatically. Still, with the currently suggested changes, you can set it manually (by modifying the table's source directly for that cell).Comment #10
watergate commentedI've applied the suggested changes to the 2.x version of this module. Please reopen this ticket if a backport of this functionality is desired (ideally, provide a merge request).