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.
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
<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>
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>
<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 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:
- 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.
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("https://s.ytimg.com/yts/img/large_play_button_ringo-vfljWXIdx.png") 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.
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
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.
You must add the
titleattribute 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.
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.
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.
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
//*[@aria-label="YouTube Video Player"]
Are you trying to remove the
aria-labelbecause 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.
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` .
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?
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?
You can use
aria-labelor you can contact Joe Dolson through the plug-in support forum to ask if there is a workaround.
Hi. I am still seeing the issue on my accessibility scans:
This button element does not have a mechanism that allows an accessible name value to be calculated
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).
Sorry, forgot to add the code:
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.
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?
If you add the video name to 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).