Safari VoiceOver problem reading input labels

While drafting a sample web form, I found a problem with how VoiceOver was reading the labels for some of the inputs. For example, a text field was labeled "First Name" but on the text field VoiceOver was saying "First Nameand one more item, edit text" with the word "Name" mispronounced and smooshed with the word "and." If I navigated to the <label> element itself, VoiceOver read it correctly, it was only wrong when it was read as the accessible name of the input field. Other inputs in the form didn't have this problem but then I wrote another input example that I thought was very different but it ended up having the same problem. After a lot of trial and error, I figured out the problem was triggered by use of the CSS display property and required two things to be true:

  1. <label> changed to display:block
  2. <label> has at least one display:block child element but not all children with display:block

Here are two examples of code that will have the problem:


<!-- VoiceOver is saying "First Nameand one more item, edit text" -->
<!-- implicit -->
<label style="display:block">
  <span style="display:block">First Name</span>
  <input type="text">
</label>
<!-- VoiceOver is saying "Firstand one more item, edit text" -->
<!-- explicit -->
<div>
  <label for="firstname" style="display:block">
    First
    <span style="display:block">Name</span>
  </label>
  <input id="firstname" type="text">
</div>

By default, label elements are inline and the child elements I tested with were either inline (span) or inline-block (input) by default and CSS was used to change that. I did not do exhaustive testing to see if the problem occurred with other display property values but I suspect block is not the only value that would cause the problem.

The workaround is to avoid having one of the two criteria be true. Having all the elements within the label be display:block should do the trick:


<!-- workaround applied, VoiceOver is saying "First Name, edit text" -->
<!-- implicit -->
<label style="display:block">
  <span style="display:block">First Name</span>
  <input type="text" style="display:block">
</label>
<!-- explicit -->
<div>
  <label for="firstname" style="display:block">
    <span style="display:block">First</span>
    <span style="display:block">Name</span>
  </label>
  <input id="firstname" type="text">
</div>

The problem appears to be with Safari for Mac (Safari 13.0.5 on macOS 13.15.3, Safari 13.1 on macOS 13.15.4, and even Safari Technology Preview Release 104 Safari 13.2 on macOS 13.15.3), I could not reproduce the problem in Safari for iOS (13.3.1) or in other Mac browsers (Chrome 80 or 81, Firefox 74 or 75). Safari's display of the accessibility tree (Web Inspector > Elements > Node > Accessibility) doesn't show a problem, it says the label is simply "First Name."