Fixed: Inaccessible YouTube Embeds

Most of us in the accessibility biz (do we call it that? I think we call it that…) already know that YouTube’s default embed code is problematic. Specifically, the fact that the <iframe> does not have a title attribute is an automatic WCAG 2.0 AA failure.

The Existing title Issue

There has been some debate on the merit of this WCAG failure, but you would likely see it flagged as a failure nonetheless. Drupal addressed this a couple years ago, though that means a separate call to YouTube for every embed. WordPress is working to address it, perhaps in 4.9. Neither of these, however, is a panacea since users can embed YouTube into these platforms in ways that are not caught by these updates, and users can embed YouTube in all the other platforms that exist. Thankfully, there is a report open with Google in the non-bug-tracker Google Group.

For those who are not familiar with HTML but still have to stuff YouTube into pages, here is an example of the standard embed code with the title highlighted.

<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ?rel=0" frameborder="0" allowfullscreen title="YouTube embedded video of Rick Astley.">&tl;/iframe>

A New <button> Issue

I found a new one this week that cannot be so easily remedied by the user when pasting the code into the page. Specifically this is about a control with no accessible name — the play button. Bear with me on the following embedded video. You do not need to play it to see the problem.

When that code is rendered, prior to playing it, there is a big button in the middle of the video placeholder that acts as the play button. Pressing this loads the video and loads the video player controls at the bottom of the video (which uses a different play button). Here is the code for the big play button:

<div class="ytp-cued-thumbnail-overlay" data-layer="4" style="">
  <div class="ytp-cued-thumbnail-overlay-image" style="background-image: url("https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg");"></div>
  <button class="ytp-large-play-button ytp-button">
    <svg height="100%" version="1.1" viewBox="0 0 68 48" width="100%">
      <path class="ytp-large-play-button-bg" d="m .66,37.62 c 0,0 .66,4.70 2.70,6.77 2.58,2.71 5.98,2.63 7.49,2.91 5.43,.52 23.10,.68 23.12,.68 .00,-1.3e-5 14.29,-0.02 23.81,-0.71 1.32,-0.15 4.22,-0.17 6.81,-2.89 2.03,-2.07 2.70,-6.77 2.70,-6.77 0,0 .67,-5.52 .67,-11.04 l 0,-5.17 c 0,-5.52 -0.67,-11.04 -0.67,-11.04 0,0 -0.66,-4.70 -2.70,-6.77 C 62.03,.86 59.13,.84 57.80,.69 48.28,0 34.00,0 34.00,0 33.97,0 19.69,0 10.18,.69 8.85,.84 5.95,.86 3.36,3.58 1.32,5.65 .66,10.35 .66,10.35 c 0,0 -0.55,4.50 -0.66,9.45 l 0,8.36 c .10,4.94 .66,9.45 .66,9.45 z" fill="#1f1f1e" fill-opacity="0.81"></path>
      <path d="m 26.96,13.67 18.37,9.62 -18.37,9.55 -0.00,-19.17 z" fill="#fff"></path>
      <path d="M 45.02,23.46 45.32,23.28 26.96,13.67 43.32,24.34 45.02,23.46 z" fill="#ccc"></path>
    </svg>
  </button>
</div>

Neither the <button>, its nested SVG, nor its parent <div> has an accessible name. There is no plain text equivalent to what we are seeing on the screen.

Screen Reader Demo

So what does it mean to have no accessible name? A piece of assistive technology, such as a screen reader, cannot identify it to users as anything other than what element it is (in this case a <button>). A screen reader user familiar with YouTube embeds will likely already know this issue and may have already worked around it and forgotten that it is a problem. That does not make it ok, though.

The first video shows how NVDA / Firefox announces the embedded YouTube video. The second video shows how JAWS / IE11 does it.

The source for the example videos is a CodePen I made to test the issue (and ask for input on the Twitters). To spare you the hassle of having to listen to them, here is what each of my two examples says:

NVDA / Firefox:
Button
JAWS / IE11:
Unlabeled one button

Don’t Confuse This One

If you dig around the code and look for an aria-label (after exhausting all the other ways to provide an accessible name) you may find this play button, but it only appears after the video has started playing and does not help a user trying to start a video:

<button class="ytp-play-button ytp-button" aria-label="Play">
  <svg height="100%" version="1.1" viewBox="0 0 36 36" width="100%">
    <use class="ytp-svg-shadow" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#ytp-id-11"></use>
    <path class="ytp-svg-fill" d="M 12,26 18.5,22 18.5,14 12,10 z M 18.5,22 25,18 25,18 18.5,14 z" id="ytp-id-11"></path>
  </svg>
</button>

In short, that just tells me that the developers at YouTube know how to address this already, they just missed the big button.

A Blog Post Is Not a Bug Report

I am writing this post at the same time I write the report. I figured if I was going to report it I might as well flag it as an issue for others to be aware of today. You can see it in the Accessible Google Group (per instructions from the Google Accessibility Twitter account). The group is moderated, so it went live a day after this post.

A Workaround?

Normally I like to be able to offer a fix. Sadly, as this code is rendered after the calling page, there is no way to just drop an accessible name into it (as with the title workaround above). I plan to write a script to parse the <button> and add an aria-label (easiest option) and when I do I will drop it here. I have just run out of time this weekend (Game of Thrones is on later and I still have to pack for GenCon).

Update: September 5, 2017

I was checking a page today that has a YouTube embed and was surprised to hear the play button get announced. I popped into the code and found this for the play button:

<button class="ytp-large-play-button ytp-button ytp-red2" aria-label="Play" style="background: rgba(0, 0, 0, 0) url(&quot;https://s.ytimg.com/yts/img/large_play_button_ringo-vfljWXIdx.png&quot;) no-repeat scroll center center / 100% auto;"></button>

I highlighted the new aria-label attribute. So perhaps this is fixed? Or perhaps there is some A/B testing going on. I have asked as a follow-up to my bug report and will update here when I have some confirmation. So far I have one confirmation on Twitter that this is not limited to me, but I am happy to hear from others.

Note that the SVG for the red box / white arrow of the play button is now a PNG. While it is unfair to call that a regression, it does make me wonder if this is old code coming up (perhaps as a short-term fix?).

Update: September 7, 2017

I have received confirmation that the play button issue I reported has been resolved:

Unfortunately I don’t have a public tracker to provide for you, however, as you mentioned this has been fixed with the new UI recently pushed.

Cool.

16 Comments

Reply

Adrian, thank you for taking the time to log the Play button bug to Google and for writing up this blog. I love to see the enthusiasm for Accessibility across all web platforms. – Cheers, Lisa Conrey, Product Manager of Accessibility at Comcast

Lisa Conrey; . Permalink
Reply

Maybe I’m doing something wrong, but I’m trying to get a “title” for a Youtube embed in Webflow. The inspector reveals

<iframe src="https://www.youtube.com/embed/st-qoZeA0_w?rel=0&controls=1&autoplay=0&mute=0&start=0" frameborder="0" style="position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:auto" allow="autoplay; encrypted-media" allowfullscreen=""> </iframe>

No sign of a title there.

Jonathan Holden; . Permalink
In response to Jonathan Holden. Reply

You must add the title attribute manually. YouTube does not put it in there, as noted above. I do not use Webflow, so I cannot help you there, but if it has a code editor view then that is where you would add it.

Reply

Right, I misunderstood the title and opening paragraph of this post then, which suggested that this was “fixed” in 2017. It actually means “how to fix”. I’ve also added a comment on the “iframe title attribute not available on oembed iframe” post on Google Groups about the error from the Lighthouse accessibility audit.

jd Holden; . Permalink
Reply

What I’ve run into is an aria-label element being added to a non-Interactive Element, throwing an error for a YouTube embedded video. This code appears in a div with about 10 classes, including .html5-video-player:

aria-label=”YouTube Video Player”

I originally thought the problem originated with the Divi Video module, so tore into the video module’s code to try to find it. No luck. And it doesn’t appear in the code, either. In fact, it doesn’t show up until the page renders.

Anyone else have this problem? I’ve been tearing my hair out for a week trying to get rid of the aria-label, or add a role for the aria attribute, but I can’t get to the code.

Help!!

Cindy Conlin; . Permalink
In response to Cindy Conlin. Reply

To confirm what you are seeing, if you inspect this page, which has an embedded YouTube video, you can search the following XPath to get to the offending <div>:

//*[@aria-label="YouTube Video Player"]

Are you trying to remove the aria-label because of a validation error, or because a testing has shown it is a problem for users? If the former, I suggest filing a bug (and maybe looking at a lazy load option). If the latter, then filing a bug and scripting it away seem like your best options.

In response to Adrian Roselli. Reply

It’s been a while since this has been active, but curious if anyone ever filed a bug for the embedded Youtube video issue with `[aria-label=”YouTube Video Player”]` being added to a `div` within the `iframe`? It continues to be flagged as an accessibility violation, since `aria-label` is not supported on a `div` .

george; . Permalink
In response to george. Reply

No idea. I was mostly trying to get the button working. This post details some of what I went through to report it using YouTube’s arcane methods, so maybe try that?

Reply

Is there an accessible option for embedding a YouTube video without the title attribute? I am using a WordPress accessibility plugin (WP-Accessibility) and it strips out all title attributes from content. (because they can be redundant). But Axe still flags YouTube embeds if I use the aria-label attribute. Any suggestions?

In response to CJAK. Reply

You can use aria-label or you can contact Joe Dolson through the plug-in support forum to ask if there is a workaround.

Reply

Hi. I am still seeing the issue on my accessibility scans:

Description

This button element does not have a mechanism that allows an accessible name value to be calculated

In response to Jim. Reply

Jim, it is not uncommon with Google products for there to be regressions and new issues. This post details how I went about getting it addressed, so you should be able to follow the same process (unless Google has changed it).

Reply

Sorry, forgot to add the code:

Fatih; . Permalink
In response to Fatih. Reply

Fatih, see my response to Jim above (who I know is you because of the email and IP and assume this was just autocomplete weirdness on your machine). Also note that any code you paste has to be escaped. It is a security precaution. Which is why it did make it into the comments.

Reply

This is such a helpful post! On our site, we sometimes have lots and lots of YouTube videos embedded on a single page –– the screenreader reading “Play” for each one is not super helpful. It would be great if the screenreader would read something like “Play video about ____” for each video. We could add a custom aria-label to do this, but I don’t know how to do that with iFrames containing a YouTube video. Any ideas on how to do this?

In response to Meg Crenshaw. Reply

If you add the video name to the title on the <iframe> then screen reader users should get context from that container. The embedded Rick Astley video above uses that approach (though I might front-load the unique bits).

Leave a Reply to Adrian Roselli Cancel response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>