Custom Loop for wp_list_categories() Function for Announcing "Subcategory" for Screen Reader

Currently, when using an Orca screen reader for GNOME desktop, the screen reader does not say “nested list” where the category contains subcategories. For example:

  • Computer and Information Technology
    • Computers
    • Multimedia Production
  • Entertainment
    • Movies
    • Music

Each of the categories and subcategories has a link. With this PHP code below:

<div id="areaCategories" class="module-area" role="tabpanel"
  aria-labelledby="lblTabCategories" tabindex="-1">
  <ul class="categories-list">
  <?php wp_list_categories(array(
            'title_li' => '',
            'hide_title_if_empty' => true, 
            'use_desc_for_title' => false,
            'depth' => 2
            )); ?>
  </ul> 
</div>

Orca screen reader will read as follows:

Without announcing “subcategory” for each of the subcategories, all the categories and subcategories will be treated as categories by a blind user, as a blind user has no idea which link is a subcategory. Some screen readers such as JAWS and NVDA for Windows might read nested lists and some screen readers may not read nested lists that are contained in a list, so in my case, what I want to do is have a screen reader announce subcategories within a nested list as follows:

So here’s a generated HTML code that I had in mind:

<ul>
  <li><a href="...">Computers and Information Technology</a>
    <ul>
      <li><span class="screenreader">Subcategory: </span><a href="...">Computers</a></li>
      <li><span class="screenreader">Subcategory: </span><a href="...">Multimedia Production</a></li>
    </ul>
  </li>
  <li><a href="...">Entertainment</a>
    <ul>
      <li><span class="screenreader">Subcategory: </span><a href="...">Movies</a></li>
      <li><span class="screenreader">Subcategory: </span><a href="...">Music</a></li>
    </ul>
  </li>
</ul>

Or maybe I could do something like this:

<ul>
  <li><a href="...">Computers and Information Technology</a><span class="screenreader">
    This category contains 2 subcategories.</span>
    <ul>
      <li><a href="...">Computers</a></li>
      <li><a href="...">Multimedia Production</a>
          <span class="screenreader">End of subcategories</span></li>
    </ul>
  </li>
  <li><a href="...">Entertainment</a><span class="screenreader">
    This category contains 2 subcategories.</span>
    <ul>
      <li><a href="...">Movies</a></li>
      <li><a href="...">Music</a>
          <span class="screenreader">End of subcategories</span></li>
    </ul>
  </li>
</ul>

The screenreader class is for screen reader and is controlled by CSS media query, so a sighted user won’t see "Subcategory: " but will be read by the screen reader.

With that in mind, how can I accomplish this if I have to write a PHP loop for displaying categories and subcategories?

1 Like

Try something like this:

$parent_categories = array(
    'parent' => '0' // get top level categories only
); 
$categories = get_categories( $parent_categories );

foreach( $categories as $category ) {
    $subcats = array(
        'child_of' => $category->cat_ID // get children of this parent using the $category ID variable
    );
    $subcategories = get_categories( $subcats );

    foreach( $subcategories as $subcategory ) {
2 Likes

Perfect. That’s just what I needed.

<?php
$parent_categories = array(
    'parent' => '0' // get top level categories only
);
$categories = get_categories( $parent_categories );
// Check to see if there is one or more categories to display.
if(count($categories) > 0) {
?>
<ul class="categories-list">
  <?php foreach( $categories as $category ) { ?>
  <li class="cat-item">
    <a href="/category/<?=$category->slug ?>"><?=$category->name ?></a>
    <?php  
    $subcats = array(
        'child_of' => $category->cat_ID
    );
    $subcategories = get_categories( $subcats );
    if(count($subcategories) > 0) { ?> 
    <ul class="children">
    <span class="screenreader">List of subcategories:</span>
    <?php foreach( $subcategories as $subcategory ) {?>
      <li class="cat-item">
        <a href="/category/<?=$category->slug.'/'.$subcategory->slug ?>/"><?=$subcategory->name ?></a>
      </li>
    <?php } ?>
    </ul>
    <span class="screenreader">End of subcategories for
      <?=$category->name ?>.</span>
    <?php } ?>
  </li>
  <?php } ?>
</ul>
<?php } else { ?>
<p>No categories to display.</p>
<?php } ?>

Thank you.

Update: I decided to have the span tag inside the anchor tag. For screen readers that have the ability to show the list of links, a blind user should be able to know what the subcategory link relates to the parent category, so the list of categories and subcategories should be accessible to blind users using a screen reader to browse my website.

2 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.