Search code examples
accessibilitywai-ariascreen-readersw3c-validationuiaccessibility

Convert read only fields for accessibility purposes


I'm converting an application to be compliant with the W3 accessibility guidelines.

I need to have the screen reader to read the title and the value together, only using <p> tags.

This website has several forms which are displayed as read only and if the user wishes to edit the fields he must click an "Edit" button that will open a modal.

My problem with the read only fields is that this website is structured such that the titles are presented on the left and the respective values on the right. Something like this:

<div class="form-group" id="-serviceName">
  <p id="-title" class="col-sm-4 form-control-title">Some text</p>
  <p id="-value" class="col-sm-8 form-control-static">Some value</p>
</div>

Initially I was using <label> but as my value is not an input when I open the page WAVE evaluation tool was giving me an alert:

"Orphaned form label: A form label is present, but it is not correctly associated with a form control."

<div class="form-group" id="-serviceName">
  <label class="col-sm-4 control-label" id="-label">Some text</label>
  <div class="col-sm-8 col-md-6 col-lg-4">
    <p class="form-control-static" id="-value">Some value</p>
  </div>
</div>

I have tried to use aria-labeledby and aria-describedby, but using the arrow keys, the screen reader always presents the information independently. First it reads "Some text" and then I have to click again on the arrow keys and it read "Some value".

I want to have the screen reader to read both values together as: "Some text Some value"


Solution

  • There shouldn’t be a major issue with the code you already have in terms of use by screen readers.

    They can very well access the key-value pairs and it will read them in order, which will read first title and then value (when reading downwards).

    When it comes to WCAG Criterion Info and Relationships, using <p> might not sufficiently explain that the second text is a user input, and that the first is a static label that the user cannot change.

    There are probably several valid ways to fix that.

    Recommended solution

    If this is form data, users could expect (depending on your use case) to navigate in form rather than reading mode. So they might use Tab keys to jump from form field to form field.

    Currently, there are no form fields in the “form”. The solution I’d recommend would be a real readonly form:

    <form aria-labelledby="form-title">
      <h2 id="form-title">Your form data</h2>
      <p>
        <label>Some text
              <input readonly type="text" value="Some value">
            </label>
      </p>
      <p><button>Edit</button></p>
    </form>

    This would also clearly communicate to any assistive technology that we’re dealing with form data, but that it cannot be changed in the current state. Forms must have an accessible name, that’s why I’m referring to the visible title with aria-labelledby.

    The <label> element MUST be associated with a form input, either via the for attribute or by wrapping the input.

    Alternative solutions

    Putting both pieces in one <p> strengthens their relationship, and when reading with a screen reader, there is less of a pause between title and value

    <p class="form-group" id="a2ba84-serviceName">
      <div id="a2ba84-title" class="col-sm-4 form-control-title">Some text</div>
      <div id="a2ba84-value" class="col-sm-8 form-control-static">Some value</div>
    </p>
    

    The <dl> description list is meant to form a grouping of keys and values, and is often used in this context

    <dl>
      <div class="form-group" id="a2ba84-serviceName">
        <dt id="a2ba84-title" class="col-sm-4 form-control-title">Some text</dt>
        <dd id="a2ba84-value" class="col-sm-8 form-control-static">Some value</dd>
      </div>
    </dl>
    

    Additional clarifications

    aria-labelledby and aria-describedby cannot be used on just any element. They are used for ARIA roles that can have an accessible name, mainly interactive controls, landmarks and table elements.