Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
418 views
in Technique[技术] by (71.8m points)

c# - Tool tip content is not accessible using keyboard

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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:-

  1. Made it accessible via keyboard and on hover.
  2. 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).
  3. Made it work on touch devices.
  4. 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"/>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...