I have created a slideshow for a website using W3Schools HTML code (from here: https://www.w3schools.com/w3css/w3css_slideshow.asp)
It all works fine except that I cannot get NVDA to read any title or aria-label attached to the previous and next arrows on hover. It only reads on click, which is too late for someone using a screen reader.
I've changed the W3Schools code from actual buttons to this:
<div class="direction prev" tabindex="0" onclick="plusSlides(-1)" role="button" aria-label="previous">❮</div>
<div class="direction next" tabindex="0" onclick="plusSlides(1)" role="button" aria-label="next">❯</div>
and tried several combinations including:
adding ids to a span with text and then referencing it with aria-labelledby in the button div
using title="Previous Slide"
using a special class="visually-hidden" using the clip method to hide the text (already used in the menu, but it doesn't read that, either)
various other similar options, to no avail.
What can I do to make NVDA read the label/text on hover? JavaScript is ok, but no jQuery, please. Thanks.
I think you have to use aria-describedby="previous" or "next" So NVDA can read it. More information here: https://www.powermapper.com/tests/screen-readers/labelling/a-aria-describedby/
If it does not work I am sorry. Let me know so I can delete
The following code works. I haven't included the JavaScript as it's not relevant to this post.
.gallery /*code for this demo only */ {
width: 100%;
margin: 1rem 0;
border: 1px solid red;
height: 50px;
}
.prev,
.next {
background-color: rgba(0,0,0,0.2);
cursor: pointer;
position: absolute;
top: 30px;
width: 10px;
padding: 15px;
margin-top: 22px;
color: var(--dark-green);
font-weight: bold;
font-size: 1.25rem;
transition: 0.6s ease;
border: none;
user-select: none;
left: 1rem;
}
.next {
left: unset;
right: 1rem;
border-radius: 3px 0 0 3px;
}
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute;
height: 1px;
width: 1px;
overflow: hidden;
white-space: nowrap;
}
<div class="direction prev" tabindex="0" onclick="plusSlides(-1)" role="button">❮<span class="visually-hidden">Previous slide</span></div>
<div class="direction next" tabindex="0" onclick="plusSlides(1)" role="button">❯<span class="visually-hidden">Next slide</span></div>
I was facing the issue where nvda did not read the aria-label assigned to Icon or IconButton on hover. I wrapped the icon with span, set the role as img and assigned aria-label to span.
Previous:
<IconButton
aria-label="Some icon"
role="button"
>
<TodayIcon aria-label="Today"/>
</IconButton>
Current:
<IconButton
role="button"
>
<span role="img" aria-label="Today">
<TodayIcon />
</span>
</IconButton>
I got there in the end. I needed to move the forward and back symbols inside the spans and, as #robariissa01 said, I need to use the 'aria-label'. The code for the buttons is now this:
<div id="dp" class="direction prev" tabindex="0" onclick="plusSlides(-1)" role="button" aria-labelledby="ps"><span id="ps" for="dp" aria-label="Previous slide">❮</span></div>
<div id="dn" class="direction next" tabindex="0" onclick="plusSlides(1)" role="button" aria-labelledby="ns"><span id="ns" for="dn" aria-lable="Next slide">❯</span></div>
Related
I have the button which the code I show below, it works well when not active, but when I click on it, it changes its color from grey to green as supposed to, but it stops being clickable.
I am no longer able to click on it in order to go back to not active and to its color grey. How can I fix this issue?
$("#TmpFBtn").click(function() {
if ($("#TmpFBtn").hasClass("active")) {
$("#TmpFBtn").removeClass('active');
} else {
$("#TmpFBtn").addClass('active');
}
});
.button {
text-decoration: none;
width: 14%;
float: left;
background-color: #5e6472;
border: none;
color: white;
padding: 5px 12px;
text-align: center;
font-size: 16px;
cursor: pointer;
margin: 0;
}
.button:hover {
background-color: #2a9d8f;
}
.button.active {
background-color: #2a9d8f;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="featuresCB">
<button class="button pksOnsets" style="width: 100%;" id="TmpFBtn" name="TmpFBtn"> Temporal Features <i class="fa fa-caret-down" aria-hidden="true"></i></button>
</div>
$("#TmpFBtn").click(function() {
if ($("#TmpFBtn").hasClass("active")) {
$("#TmpFBtn").removeClass('active');
} else {
$("#TmpFBtn").addClass('active');
}
});
.button {
text-decoration: none;
width: 14%;
float: left;
background-color: #5e6472;
border: none;
color: white;
padding: 5px 12px;
text-align: center;
font-size: 16px;
cursor: pointer;
margin: 0;
}
.button.active {
background-color: #2a9d8f;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="featuresCB">
<button class="button pksOnsets" style="width: 100%;" id="TmpFBtn" name="TmpFBtn"> Temporal Features <i class="fa fa-caret-down" aria-hidden="true"></i></button>
</div>
The problem was mostly with the hover part.As even after 2nd click it remains in the hover state which shows the background green.
It is working but not visible to you because when you hover on it to click :hover is already applied and the background color is applied.
If you inspect and open dev tools you see the active class is being added to it.
So, just remove the :hover state to notice the change.
If you still want to have :hover state, try changing the background color at hover state.
Btw,
A better jQuery for you:
$("#TmpFBtn").click(function() {
$(this).toggleClass("active");
}
It does the same job, but with a lesser number of lines.
I have a simple HTML, CSS website that is also making use of JavaScript for animated navigation for a mobile only site.
Current Naviation
The HTML for the button:
<div class="navigations">
<div class="left">
<div class="leftinner" id="left">
<i class="fas fa-arrow-left"></i>
<span id="lefttext">CONTACT</span>
</div>
</div>
<div class="right">
<div class="rightinner" id="right">
<i class="fas fa-arrow-right"></i>
<span id="righttext">WEBSITE</span>
</div>
</div>
</div>
When the user clicks on the contact button it triggers a JS function that runs the following:
document.getElementById('main').classList.add('slideright');
document.getElementById('left').style.display = 'none';
The issue I am having is when the user clicks the CONTACT button it triggers the WEBSITE button as well, almost as if the WEBSITE button has a hidden overlap over the CONTACT button. I have attempted using Flex Box, Float left, Float left and right, Display inline block, Display table with table-cell, column etc. The issue only persists on Chrome for Android, but works fine on iPhone and other browsers.
What would be the best way to fix this issue?
Apologies I can't share more than just the screenshot due to NDA reasons.
Edit
Here is the CSS for the navigation buttons, this uses the float left and right attempt.
.navigations .left {
width: 50%;
height: 100%;
z-index: 500;
display: block;
float: left;
}
.navigations .left .leftinner {
background-color: #ffcb05;
border-top: 6px solid #000;
border-right: 3px solid #000;
width: 100%;
height: 100%;
display: inline-block;
}
.navigations .right {
width: 50%;
height: 100%;
z-index: 500;
display: block;
float: right;
}
.navigations .right .rightinner {
background-color: #ffcb05;
border-top: 6px solid #000;
border-left: 3px solid #000;
width: 100%;
height: 100%;
display: inline-block;
}
So I managed to solve the issue with this.
Seems the float right on the text inside the right hand side button was the culprit. Changing how the right button moved its text to the right by making use of text-align: right;instead of float: right; solved the issue.
It seems that the floating right of text made the text's width 100% and overlap the button on the left.
I have made a small web page, the source code of which is available on FIDDLE. It uses a jquery plugin which I made for autocomplete.
The plugin adds a new div (.mridautocomplete-list) after the initialized inputs, which contains the autocomplete list :
<input id="test1">
<div class="mridautocomplete-list" style="display: block; left: 8px; width: 169px; position: absolute; background-color: white; border: 1px solid rgb(221, 221, 221); max-height: 150px; overflow-x: hidden; overflow-y: scroll; font-family: Arial; font-size: 13.3333px; z-index: 8888;">
<p class="mrid-autocomplete-item" style="margin: 0px; padding-left: 2px; text-align: left; font-size: 13.3333px; cursor: default; background-color: white;"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="mridautocomplete-item-image" style="height: 11px; width: 11px;"><span style="color: #4682B4; font-weight: bold;">a</span>aa</p>
<p class="mrid-autocomplete-item" style="margin: 0px; padding-left: 2px; text-align: left; font-size: 13.3333px; cursor: default; background-color: white;"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="mridautocomplete-item-image" style="height: 11px; width: 11px;">b<span style="color: #4682B4; font-weight: bold;">a</span>b</p>
</div>
<input class="test2">
<div class="mridautocomplete-list"></div>
<input class="test3">
<div class="mridautocomplete-list"></div>
The problem is :
This web page renders perfectly as expected on fiddle
But when I run the same code on my browser ( without fiddle ), it doesn't get displayed properly, shifting all elements ( SHOWN IN SCREENSHOTS ATTACHED )
Can anyone explain what might be causing the problem ?
Your .test2 class is a width of 80%.
The other inputs have a default width of 173px.
If you resize the fiddle window to a larger width, you will see the same issue.
To fix this you could add a display: block to your .test2 class.
Have you already tried the display CSS property? Setting the second input to "display: block" forces the 3rd input to the next line.
Another option is to place the autocomplete Javascript just before the closing body tag. This also worked for me in Chrome, Firefox and Safari.
I'm trying to get the icon to display in the middle of the words 'some text'.
Could anyone advise?
http://jsfiddle.net/LZxxB/50/
<div>
<div style="display:inline-block;">some</div>
<span class='ui-btn-icon-notext ui-icon-arrow-u-l' style="display:inline-block;"></span>
<div style="display:inline-block;">text</div>
</div>
Here is one way to do it. You basically make an icon button that is not a button.
The HTML:
<div>
<div style="display:inline-block;">some</div>
<span class="ui-nodisc-icon ui-alt-icon nonbuttonicon" >
<span class="ui-btn ui-icon-delete ui-btn-icon-notext ui-btn-inline"></span>
</span>
<div style="display:inline-block;">text</div>
</div>
The CSS:
.nonbuttonicon .ui-btn {
background: transparent;
cursor: default;
border: 0;
margin: 0;
}
.nonbuttonicon .ui-btn:hover{
background: inherit;
}
DEMO
UPDATE:
Here is a way without using jQM buttons and a single span:
<div>
<div style="display:inline-block;">some</div>
<span class="ui-alt-icon ui-icon-delete ui-btn-icon-notext inlineIcon"></span>
<div style="display:inline-block;">text</div>
</div>
.inlineIcon {
display: inline-block;
position: relative;
vertical-align: middle;
}
.inlineIcon:after{
background-color: transparent;
}
Updated DEMO
An if you like the white icon on top of the round disk, the CSS becomes even simpler:
<span class="ui-icon-delete ui-btn-icon-notext inlineIcon"></span>
.inlineIcon {
display: inline-block;
position: relative;
vertical-align: middle;
}
DEMO
These lines of code will reset the jquery mobile css that is displaying it differently. You might need to tweak it a little bit to fit your needs.
div span.ui-icon-arrow-u-l:after {position:relative;}
div span.ui-icon-arrow-u-l {display:inline-block;height:30px;margin-top:0;width:16px;}
Hope this helps.
Disclaimer: I'm relatively new to jQuery and JavaScript. The openStatement() function below executes whenever it is determined that the #statementTab is not already open. If the code below isn't enough information, simply check out the source below.
Basically, the UL containing the various tabs flickers and disappears whenever the user opens the #statementTab. I'd like to fix this.
Source: http://www.cameronhermens.com/dbunkr/brochure.html
// The openStatement function opens the statement tab when the user clicks
<a id="openIt"> (if the statement tab isn't already open).
function openStatement() {
$('#explore').animate({width: '70%'}, '200');
$('#statementTab').animate({width: '213px'}, '1000');
};
// Here's the DIV.
<div id="explore" class="brochure">
<ul id="brochureTab">
<li><a href="welcome.html" >welcome</a></li>
<li>our mission</li>
<li>what is dBunkr</li>
</ul>
</div>
<div id="statementTab">
<a id="openIt">
<img class="opaque left-5" src="images/rightArrow.jpg" height="10" width="6" alt="Expand the Statement tab">
<span class="statementBar">Statements</span>
</a>
</div>
The UL#brochureTab is being hidden during animation because as #explore is animating, the jQuery is applying a style of overflow: hidden to it. This style is then removed upon completion of the animation.
A quick solution (i.e. without addressing the way that you have styled the rest of your elements) would be to add the style overflow: visible !important; to #explore.
You have the ul#brochureTab outside the div#explore by using the CSS top: -45px;.
Whenever you animate the div#explore with jQuery .animate(), the ul#brochureTab gets "flashed" because the jQuery .animate() automatic switches to overflow:"hidden" while performing the animation.
The solution is to use a DIV to serve as a wrapper to the div#explore, and have it with the visual look you've got on the div#explore:
CSS
#wrapper {
background-color: #FFFFFF;
border: 3px solid #CCCCCC;
border-radius: 7px 7px 7px 7px;
box-shadow: 3px 3px 3px #CCCCCC;
float: left;
height: inherit;
padding: 5px;
}
THE MARKUP WOULD BE:
<div id="wrapper">
<div id="explorer">
<ul id="brochureTab">
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
<div id="ui-tabs-3">...</div>
<div id="ui-tabs-10">...</div>
<div id="ui-tabs-12">...</div>
</div>
<div id="statementTab">...</div>
</div>
AND TO PREVENT THE FLASHING:
#brochureTab {
float: left;
left: 10px;
list-style: none outside none;
margin: 0;
padding: 0;
position: relative;
/* top: -45px; remove this line */
}
.ui-tabs-panel {
background: none repeat scroll 0 0 #FFFFFF;
border: 2px solid #CCCCCC;
float: left;
left: 30px;
margin: 0 auto 30px;
min-height: 410px;
padding: 10px;
position: relative;
/* top: -20px; remove this line */
width: 90%;
z-index: 1;
}
To your current animation method, no changes need to be made.
To your new CSS for the wrapper, may require some "tunning".