问题
I am unable to see the contents of the image tool tip when focussed on it using keyboard. Below is a code example:
<img id= "id1" title ="title1" tabindex ="0" src="/images/home.gif" alt="title1" />
I am able to see the tool tip contents when hovered using mouse.
回答1:
According to the HTML 5.2 specification,
The title attribute represents advisory information for the element, such as would be appropriate for a tooltip.
The specification also adds the following warning:
Warning! Relying on the title attribute is currently discouraged as many user agents do not expose the attribute in an accessible manner as required by this specification (e.g., requiring a pointing device such as a mouse to cause a tooltip to appear, which excludes keyboard-only users and touch-only users, such as anyone with a modern phone or tablet).
In other words, one should not rely on the title
attribute for exposing information to keyboard users, including screen reader users. This issue has been around for many years. Accessibility standards recommend(ed) the use of the title
attribute only on the frame
element (which is deprecated in HTML 5) the input
element (if you don't use a label
element for aesthetic reasons) and the abbr
element. See also Steve Faulkner's blogpost Using the HTML title attribute – updated. (Even though the blogpost was last updated in 2013, the advice is essentially still valid.)
If you want the content of the title
attribute to be exposed visually on keyboard focus, you'll need to rely on CSS, JavaScript or a combination of both. Note, however, that the img
element is not keyboard focusable by default.
回答2:
Short Answer
Don't use the title
attribute, it doesn't serve any purpose that wouldn't be better suited as a caption under an image or a <label>
on an <input>
(please don't use a title
on an input....even for a search box, even 'placeholder' text is preferable as at least some screen readers will read that and your touch screen users will still be able to read what the input is for).
Medium Answer
The title
attribute has low support, offers very little to people in the modern age of touch screens (it is only sighted mouse users who don't use magnifiers or other assistive tech who gain anything from a title
attribute) and in general is not a good idea for most use cases.
As a general rule if you do want to use it (so mouse users can see what an image is about) then make sure it is the same as the alt
attribute so that you are providing the same information / experience to screen reader users as non screen reader users.
Long Answer
We played with this for a while, there are some circumstances where the title
attribute (or at least the effect of revealing extra information about an image) can be useful. In the end we 'rolled our own' version of the title
attribute that allowed us to have additional information about a picture, without interrupting the flow of a document with a caption
.
In the example below (a stripped back version of what we use) we have:-
- Made it accessible via keyboard and on hover.
- Provided useful information to those who need it, that has the added benefit of being accessible (as title tooltips don't follow minimum sizing guidelines in some browsers and don't scale even if you change the font size settings in your browser).
- Made it work on touch devices.
- Designed to function like a plugin, in that you produce standard markup and a little bit of JavaScript and CSS magic does the rest.
It still isn't as good as simply providing a caption under the image but I believe it captures the spirit of what the 'title' attribute on an image is designed for, while accounting for accessibility and technology changes from when it was introduced.
Please Note - the first 80 or so lines of JavaScript are just a small helper library that allows jQuery style syntax, the relevant part starts at $("img").each(function(){
.
//tiny replacement for jQuery - adapted version of ki.js
!function (b, c, d, e, f) {
f = b['add' + e]
function i(a, d, i) {
for(d = (a && a.nodeType ? [a] : '' + a === a ? b.querySelectorAll(a) : c), i = d.length; i--; c.unshift.call(this, d[i]));
}
$ = function (a) {
return /^f/.test(typeof a) ? /in/.test(b.readyState) ? setTimeout(function() { $(a); }, 9) : a() : new i(a);
};
$[d] = i[d] = {
on: function (a, b) {
return this.each(function (c) {
f ? c['add' + e](a, b, false) : c.attachEvent('on' + a, b)
})
},
off: function (a, b) {
return this.each(function (c) {
f ? c['remove' + e](a, b) : c.detachEvent('on' + a, b)
})
},
each: function (a, b) {
for (var c = this, d = 0, e = c.length; d < e; ++d) {
a.call(b || c[d], c[d], d, c)
}
return c
},
splice: c.splice
}
}(document, [], 'prototype', 'EventListener');
$.each = function(arr, callback) {
if(toString.call(arr) === '[object Array]'){
var i = 0, l = arr.length;
for(; i < l; ++i) {
callback.call(arr[i], i, arr[i]);
}
} else {
for (i in arr)
callback.call(arr[i], i, arr[i]);
}
return arr;
};
//extended to include "attr"
$.prototype.attr = function(a, b) {
return b === []._ ? this[0].getAttribute(a) : this.each(function(c) {
c.setAttribute(a, b);
});
};
//extended to include "removeAttr"
$.prototype.removeAttr = function(a) {
return this.each(function(b) {
b.removeAttribute(a);
});
};
//extend to include "parent"
$.prototype.parent = function() {
return (this.length < 2) ? $(this[0].parentNode): [];
};
//custom function to wrap an element in another
$.prototype.wrap = function(a) {
return this.each(function(b) {
var c = document.createElement(a)
b.parentNode.insertBefore(c, b);
c.appendChild(b);
});
};
//quick way of exposing everything like 'addClass', 'removeClass' etc. without having to define each one indivdually
var props = ['add', 'remove', 'toggle', 'has'],
maps = ['add', 'remove', 'toggle', 'contains'];
props.forEach(function(prop, index) {
$.prototype[prop + 'Class'] = function(a) {
return this.each(function(b) {
if(a){
b.classList[maps[index]](a);
}
});
};
});
//extend to include "after"
$.prototype.after = function(a) {
return this.each(function(b) {
b.insertAdjacentHTML('afterend', a);
});
};
//Below is the actual function, all of the above is just a simple replacement for jQuery.
//Should work with just jQuery but you would have to check.
$("img").each(function(){
$(this).wrap("div"); //create a div around an image
var title = $(this).attr("title"); //grab the title
var wrapper = $(this).parent(); //grab the div we just created
wrapper.attr("data-title", title); //set the data-title that we use in the CSS on the wrapper
wrapper.addClass("image"); //add the class that we use for CSS
wrapper.attr("tabindex", "0"); //make the div focusable with tabindex="0"
$(this).after('<span class="visually-hidden">, Title ' + title + '</span>'); //add a span with the title in that is accessible to screen readers - note the use of a comma before the 'Title' part as this makes it more natural (as we are 'hacking' an experience similar to that of a screen reader reading an actual title.)
$(this).removeAttr('title'); //remove the actual title, otherwise some screen readers will announce the title twice.
});
.image{
display:block;
overflow:hidden;
}
/*need relative position in order to absolutely position the overlay*/
.image {
position:relative;
width:200px;
height:200px;
margin: 10px;
}
.image img {
width:100%;
vertical-align:top;
}
/*add a transition*/
.image:after,
.image:before {
position:absolute;
opacity:0;
transition: all 0.5s;
}
/*remove the transition for people who have reduced motion as a preference*/
@media (prefers-reduced-motion: reduce) {
.image:after,
.image:before {
transition: none;
}
}
/*create an overlay*/
.image:after {
content:'';
width:100%;
height:100%;
top:0;
left:0;
background:rgba(0,0,0,0.4);
}
/*create a box at the bottom that contains the 'data-title' text that was added to the div we created*/
.image:before {
content: attr(data-title);
font-size: 1.25rem;
line-height: 1.9rem;
width:100%;
color:#fff;
z-index:1;
bottom:0;
padding:4px 10px;
text-align:left;
background:black;
box-sizing:border-box;
-moz-box-sizing:border-box;
}
/*make the overlay visible on hover and focus*/
.image:hover::after,
.image:hover::before,
.image:focus::after,
.image:focus::before{
opacity:1;
}
/*put a border around on focus*/
.image:focus{
outline: 2px solid #333;
outline-offset: 4px;
}
/*visually hidden class used to make text screen reader accessible but not visible*/
.visually-hidden {
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
white-space: nowrap; /* added line */
}
<img src="https://via.placeholder.com/150" title="First Image" alt="First Image"/>
<img src="https://via.placeholder.com/150" title="Second Image, A Longer Text Test for a more complex title, adjust to your needs" alt="Second Image"/>
来源:https://stackoverflow.com/questions/60559067/tool-tip-content-is-not-accessible-using-keyboard