kenwheeler / slick

the last carousel you'll ever need
kenwheeler.github.io/slick
MIT License
28.53k stars 5.88k forks source link

Accessibility Issue(ISO VoiceOver, Android TalkBack) #2139

Open GrayYoung opened 8 years ago

GrayYoung commented 8 years ago

Screenshot for slick Accessibility Issue

  1. When VoiceOver or TalkBack is on, only the first item of the carousel cant be focused, if the previous or next button has be clicked, the items current presented can't be focus.
  2. And there is weirder thing that some links of the items is not clickable.
  3. If item div only include img with tabindex="0", when item be focused, then Slick recalculates position, but not update Prev and Next arrows. (Add this on 2/24/2016)
<div class="carousel">
    <div class="item">
        <img tabindex="0" src="" alt="Uploaded try-on image">
    <div>
    <div class="item">
        <img tabindex="0" src="" alt="Uploaded try-on image">
    <div>
    ...
</div>

(4). (Suggestion:) When the arrow button is disabled, the element should add tabindex="-1", so the keyboard is not able to focus it. (Add this on 2/24/2016)

ahmadalfy commented 8 years ago

OK can you explain what the correct behavior should be cause I don't know?

GrayYoung commented 8 years ago

The correct behavior should be: Condition: Turn device accessibility on, like VoiceOver and TalkBack.

  1. Every links in the items of the carousel should be clickable, double click link then forward another page.
  2. When user select a item, the box of selected item should be appear correct area.

Actually not all presented items can be selected, and the box apprear correct area, after clicked the previous or next button, the items current presented have be updated, them cannot be selected.

The demo of SLICK http://kenwheeler.github.io/slick/ also have the same problem, you can test it via iPhone or iPad, turn on SETTING > General > ACCESSIBILITY > VOICEOVER.

This screenshots is from Chrome browser in Nexus 5 that its OS is Android 6 to support the second description. issue 2 screentshot

leggomuhgreggo commented 8 years ago

Here's a link to the live view of a codepen where the slides have nested links, so that the link issue could be tested.

Wish I had more expertise on the matter. Wonder if its related to tab focus attributes. Might try to test later.

GrayYoung commented 8 years ago

Hi guys, I have resolve my unclickable links on iPhone and iPad problem. I found only links include a img with empty src are not clickable, so I use canvas instead of img with empty src. But it is still strange problem, and I don't fixed it on Android.

<c:choose>
    <c:when test="${not empty product.image30Degree}">
        <img width="240" height="90" src="${product.image30Degree}" alt="" />
    </c:when>
    <c:otherwise>
       <canvas class="img-responsive center-block" width="240" height="90" aria-hidden="true"> 
</canvas>
    </c:otherwise>
</c:choose>
bfrable commented 7 years ago

So I encountered this issue and came across whats causing it.

    _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) {
        $(this).attr({
            // 'role': 'option',
            // 'aria-describedby': 'slick-slide' + _.instanceUid + i + ''
        });
    });

If I comment out those two lines, everything works as expected. I'm not an accessibility expert, but I think screenreaders read role=option as a combo / select box and is making the slider as a whole clickable.

https://www.w3.org/TR/wai-aria/roles#option

@leggomuhgreggo slicktrack is getting a role of listbox and then each slide is getting a role of option. This is whats giving the "broken" experience. It might be a good idea to make these options so developers can achieve the experience they're looking for.

Making each slide a tabpanel and giving slicktrack a role of region should be suffice though.

bfrable commented 7 years ago

@leggomuhgreggo

        _.$slideTrack.attr('role', 'presentation');

        _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) {
            $(this).attr('role', 'tabpanel');

            //Evenly distribute aria-describedby tags through available dots.
            var describedBySlideId = _.options.centerMode ? i : Math.floor(i / _.options.slidesToShow);

            if (_.options.dots === true) {
                $(this).attr('aria-describedby', 'slick-slide' + _.instanceUid + describedBySlideId + '');
            }
        });

changing role from listbox to region and role from option to tabpanel fixes this.