CSS 'display: none' causes problems for screenreaders

Events happening in the community are now at Drupal community events on www.drupal.org.
mgifford's picture

I would really like to understand this issue better - http://drupal.org/node/58941

As Webchick says "If 1/50th of the people complaining that this isn't fixed yet actually put some energy into reading the copious documentation cross-linked here and creating said patch, this probably would've made it into Drupal 4.7."

So, I'd like some other opinions about the difference between:

html.js fieldset.collapsed * {
    visibility: hidden;
}

html.js fieldset.collapsed * {
text-indent: -9999em;
height: 0px;
line-height: 0px;
}

I think this one's been tested by beginner #12

html.js fieldset.collapsed * {
    position: absolute;
    top: -1000em;
    left: -1000em;
}

html.js fieldset.collapsed * {
  position: absolute;
  top: -1000em;
  left: -1000em;
}
html.js fieldset.collapsed table *,
html.js fieldset.collapsed legend,
html.js fieldset.collapsed legend * {
  display: inline;
  position: relative;
  top: 0;
  left: 0;
}

And should we be thinking about including it for div.form-item as well as an .offscreen class that I've suggested in another issue.

.offscreen html.js fieldset.collapsed div.form-item  {
   position: absolute !important;
   left: -999em !important;
}

CSS hacks such as left: -1000em; are now being recommended by WCAG 2.0, so they are here to stay. http://css-discuss.incutio.com/?page=ScreenreaderVisibility

From Juicy Studio, looks like they'd recommend this one:
http://juicystudio.com/article/screen-readers-display-none.php

.offscreen html.js fieldset.collapsed div.form-item  {
{
    position: absolute;
    left: -999em;
    width: 1em;
    overflow: hidden;
}

Would like to get a better perspective on some of these CSS options.

Comments

I'll refer this to the experts ...

cliff's picture

Mike, I'll put a post in the WebAIM forum to ask the same question. There we can get definitive answers from world-class experts on accessibility. In fact, you might want to join that forum so you can get quick answers to questions just like these.

Thanks Cliff

mgifford's picture

I will join the forum. Like to find who in the Drupal community has experience here too.

Mike

OpenConcept | CLF 2.0 | Podcasting

CSS and Drupal

Joshue's picture

Hi Cliff and Mike,

The issue is that using CSS 'display:none', will actually hide the content contained in the <div> that the declaration is attached to from the screen reader completely. The content is just not rendered to the screen at all and therefore not detectable by the screen reader. Use of 'display:hidden' will generate a content box but not the content. This is not always desireable however, As Gez points out in the Juicy Studio article, this hiding/not diplaying is not always entirely the case but it seemed to be a bug, if an background URL has been added to the a parent of the CSS declaration, sometimes the content will be picked up by the screen reader. Depending on what you wish to achieve, a solution may be to have the content displayed with in the source code but use a simple IR technique to move it off the screen. The kind of show/hide feature that is in vogue today, is sometimes more than just eye candy as it is useful for showing and hiding things that are only needed within different contexts.

Maybe a user defined preference for certain menu types would be good? I am not totally familiar with this issue as it relates to Drupal, it seems to relate to form elements embedded in a collapsible menu? Is this correct?

Anyway, the combination of both the 'display:none' and 'display:hidden' seems to be a workaround that sits well with the two most used screen readers, JAWS and Window eyes. You may find some useful pointers on this part of the Juicy Studio thread. [1]

Cheers

Josh

[1] http://juicystudio.com/article/screen-readers-display-none.php#comment3

Ok, so first of all where is

mgifford's picture

Ok, so first of all where is 'display: none;' used in the code?

bash-3.2$ grep -ir 'display:' * | grep none
misc/autocomplete.js: display: 'none'
modules/block/block.css: display: none;
modules/color/color.css: display: none;
modules/openid/openid.css: display: none;
modules/openid/openid.css: display: none;
modules/profile/profile.css: display: none;
modules/system/system.css: display: none;
modules/system/system.css: display: none;
modules/system/system.css: display: none;
modules/system/system.css: display: none;
modules/system/system.css: display: none;
themes/garland/print.css: display: none;
themes/garland/style.css: display: none;
themes/pushbutton/style.css: display: none

And the other option that Juice Studio suggests 'visibility: hidden;'

bash-3.2$ grep -ir 'visibility:' * | grep hidden
misc/autocomplete.js: $(this.popup).css({visibility: 'hidden'});
misc/print.css: visibility: hidden;
modules/system/admin.css: visibility: hidden;
modules/system/defaults.css: visibility: hidden;
modules/system/system.css: visibility: hidden;
modules/user/user.js: confirmResult.css({ visibility: "hidden" });

I'm going to disregard the javascript at this point so we've got these 11 files:

misc/print.css
modules/system/admin.css
modules/system/defaults.css
modules/system/system.css
modules/block/block.css
modules/color/color.css
modules/openid/openid.css
modules/profile/profile.css
themes/garland/print.css
themes/garland/style.css
themes/pushbutton/style.css

Providing this css:

/* From misc/print.css */

#menu {
  visibility: hidden;
}

/* From  modules/system/defaults.css */

html.js .custom-container label {
  visibility: hidden;
}

/* From modules/system/defaults.css */

/*
** Markup free clearing
** Details: http://www.positioniseverything.net/easyclearing.html
*/
.clear-block:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

/* From modules/system/system.css */

div.password-confirm {
  visibility: hidden;
}

html.js fieldset.collapsed * {
  display: none;
}

textarea.teaser {
  display: none;
}

/*
** Installation clean URLs
*/
#clean-url.install {
  display: none;
}

/*
** For anything you want to hide on page load when JS is enabled, so
** that you can use the JS to control visibility and avoid flicker.
*/
html.js .js-hide {
  display: none;
}

/* From modules/block/block.css */

#blocks tr.region-populated {
  display: none;
}

/* From modules/color/color.css */

/* Preview */
#preview {
  display: none;
}

/* From  modules/openid/openid.css */

html.js #user-login-form div#edit-openid-identifier-wrapper,
html.js #user-login div#edit-openid-identifier-wrapper {
  display: none;
}

#user-login-form li.openid-link, #user-login-form li.user-link,
#user-login li.openid-link, #user-login li.user-link {
  display: none;
}

/* From modules/profile/profile.css */

#profile-fields tr.category-populated {
  display: none;
}

/* From themes/garland/print.css */

ul.main-menu, ul.secondary-menu,
#header-region, .sidebar {
  display: none;
}

/* From themes/garland/style.css */

/* Prevent the previous directive from showing the content of script elements in Mozilla browsers. */
#header-region script {
  display: none;
}

/* From themes/pushbutton/style.css */

.hide {
  display: none
}

So, skipping the javascript and print information, class/id tags to look for seem to be:

fieldset.collapsed 
textarea.teaser 
#clean-url.install 
#blocks tr.region-populated 
#preview
#profile-fields tr.category-populated 
#header-region script
.hide 

Major files of concern listed are:
system.css

Areas to focus on for improbability seem to be Advanced Search:
http://openconcept.ca/search/node

Problem is that people want it to be visible to screen readers by default (and not hidden to them).

So, seems that we're looking at an off-screen alternative because we don't want "the contextual information displayed on the screen, but [want it to be] announced to screen reader users." and also "it is always better to position content aimed at providing context for screen reader users off-screen"

For those instances we actually want to hide from both screen readers and visual readers this would be good:

.hide
{
    display: none;
    visibility: hidden;
}

But for an off screen solution we're looking at something like:

.context
{
    position: absolute;
    left: -999em;
    width: 1em;
    overflow: hidden;
}

It's then just a question of going through each of the elements to determine if there is any they should be visible to screen readers. Sound good?

OpenConcept | CLF 2.0 | Podcasting

makes sense to me...

johnbarclay's picture

I prefer .offscreen over .context because its more straightforward. Just looking at the css rules, a simple override css for accessibility with higher specificities would take care of much of this in Drupal 6.

Found you via WebAIM

kathyk's picture

Hi John, Mike, Josh,
Happy to find discussion on very current accessibility efforts for core Drupal.

I've used "off-top" successfully to make a "track-changes" HTML page read "begin insert"/"end insert" around the 'ins' and 'del' tags nicely so do know how that can be effective, but it was soooo messy. So, can agree with '.offscreen' as a solution in some cases.

Next question: I'm concerned with the edit node "collapsible fieldsets" in that we have content creators who are screen reader users and expert HTML editors. I've been asked to make the interface as simple as possible, but don't want to remove options permanently (comment, url, attachment, etc).

Question: If the fieldset link is clicked even though the choices are there from the DOM and would be read, the page is refreshed and focus is lost. Are you talking about handling this with 'display: none;' on the 'html.js fieldset.collapsed *' or is this a case for ARIA?

  • Kathy K

CSS and Drupal

Joshue's picture

Hi Mike, John and Kathy,

.hide
{
    display: none;
    visibility: hidden;
}

But for an off screen solution we're looking at something like:

.context
{
    position: absolute;
    left: -999em;
    width: 1em;
    overflow: hidden;
}

It's then just a question of going through each of the elements to determine if there is any they should be visible to screen readers. Sound good?

@Mike, looks fine to me.
@John, will using the .offscreen class essentially achieve the same thing?

Either way using these kind of offscreen methods is perfectly fine to keep vital content discoverable for screen reader users and hiding them from sighted users or for aesthetic reasons. As long as the underlying markup is semantically solid and available either on screen of off - all is well.

@Kathy,
Next question: I'm concerned with the edit node "collapsible fieldsets" in that we have content creators who are screen reader users and expert HTML editors. I've been asked to make the interface as simple as possible, but don't want to remove options permanently (comment, url, attachment, etc).

Would some kind of simple JS show/hide functionality work here? FWIW if the user could select the kind of interface elements that they needed in a preference section that would really help. It may also make your lives easier when trying to design an interface that properly serves the the broadest range of user needs. Some functionality and UI styles may suit one user group better than others. For example, using a drag and drop API is not great for non-visual users so a simple user preference section where a user can choose to globally remove any of this kind of functionality when they don't wish it would be great. As I say it may make your implementations easier.

Question: If the fieldset link is clicked even though the choices are there from the DOM and would be read, the page is refreshed and focus is lost. Are you talking about handling this with 'display: none;' on the 'html.js fieldset.collapsed *' or is this a case for ARIA?

Could this be done asynchronously? It may be possible to use scripting combined with wrapping the next desired object/element that you wish to user to have focus in a negative tabindex? I actually don't know if ARIA would help in this case. ARIA describes the role, states and properties of complex widgets and components of the interface. It may be a case that even with elements of the page using ARIA components, for the sake of backwards compatibility if nothing else, you may still need to use some tricks like the scripting/negative tabindex value for focus issues as currently there are a limited number of elements that a user agent such as a screen reader can actually focus on.

Gez Lemon has written extensively about this so you may find the following useful, though the first one will be more relevant.[1] [2]

Cheers

Josh

[1] http://juicystudio.com/article/making-ajax-work-with-screen-readers.php
[2] http://juicystudio.com/article/wai-aria-live-regions.php

.offscreen and opting in/out

johnbarclay's picture
  • the .offscrren selector will accomplish the same thing. .offscreen, .context {..} would work also. We would likely need a whole set of selectors.

In the the d6 accessible module, I throw this in as a switch that turns on and off some css overrides.

I believe the collapsable fieldsets are candidates for ARIA, but not sure of an example markup. THis looks closest: http://test.cita.uiuc.edu/aria/tabpanel/tabpanel2.php

I think we should pick an aria case and do one for d7. Either the drop and drag ordering stuff or collapsing/exapanding content.

Testing & Arising Issues

mgifford's picture

Really great to see this thread grow. Josh/Kathy, got great input here. Looking forward to seeing more suggestions for enhancements.

I've set up a dev environment using the CSV code. If folks are interested in testing it please send me a note with a request and I'll email you the url. Would like folks to set up user accounts at different levels so that we can test different elements.

I'm looking for a javascript alternative to what we're doing with misc/collapse.js

Not sure if it is being messed up by the change here:

/* Removing display: none; for accessibility of collapsed items */ 
html.js fieldset.collapsed * {
  position: absolute;
  left: -999em;
  width: 1em;
  overflow: hidden;
}

or later on here:

/*
** For anything you want to hide on page load when JS is enabled, so
** that you can use the JS to control visibility and avoid flicker.
*/
/* hiding & removing for screen readers */
html.js .js-hide {
  display: none;
  visibility: hidden;
}

In the case of all collapsible html that I can think of, you'd want that to be presented to a screen reader so it should just be offscreen and not hidden.

I tacked these onto the bottom of the modules/system/system.css file. This should be standardized, clearly documented and not thrown out to individual themes:

/*
** Accessible Hiding/Offscreen  
*/

/* Hide content for all users through css */
.hide {
  display: none;
  visibility: hidden;
}

/* Temporarily remove content, but make visible to screen readers */
.offscreen {
  position: absolute;
  left: -999em;
  width: 1em;
  overflow: hidden;
}

Like offscreen because it is clear what is supposed to be happening (like hidden).

In most cases in going through the css using display: none; I do think it shouldn't be visible to anyone. This does need to get reviewed however much more closely.

Mike

OpenConcept | CLF 2.0 | Podcasting

Making the expansion text disappear

mgifford's picture

I've tossed some code up here for review:
http://openconcept.pastebin.com/m37acba5c

There's still a big problem as the expansion text, say here search/node - with the 'Advanced search' text doesn't show up.

Mike

OpenConcept | CLF 2.0 | Podcasting

Breakthrough on New Accordion CSS

mgifford's picture

Well, I'm really not a CSS or Javascript expert, as I've spent most of the last decade digging about in the LAMP stack and getting myself really familiar with PHP/MySQL. However, with some persistence and help from folks along the way I finally stumbled across a solution I could build on:
http://www.sitepoint.com/blogs/2007/04/30/javascript-and-screen-readers/

I really liked this article too as far as JQuery accessibility, but it didn't give me missing piece:
http://www.smashingmagazine.com/2008/09/16/jquery-examples-and-best-prac...

I've now tried it on a Mac with Firefox 3, Safari 3.2.1 , Opera 9.6 & in Windows in IE 6, Firefox 2 & Opera 8, and finally in Ubuntu with Firefox, Galeon, Konqueror & Opera. Seems to work fine in all of them


/*
** Collapsing fieldsets
*/
html.js fieldset.collapsed {
border-bottom-width: 0;
border-left-width: 0;
border-right-width: 0;
margin-bottom: 0;
height: 1em;
}

/* Removing display: none; for accessibility of collapsed items */
html.js fieldset.collapsed * {
position: absolute;
left: -999em;
}

html.js fieldset.collapsed legend {
position: static;
}
html.js fieldset.collapsible legend a {
padding-left: 15px; /* LTR /
background: url(../../misc/menu-expanded.png) 5px 75% no-repeat; /
LTR /
}
html.js fieldset.collapsed legend a {
background-image: url(../../misc/menu-collapsed.png); /
LTR /
background-position: 5px 50%; /
LTR /
}
/
Note: IE-only fix due to '* html' (breaks Konqueror otherwise). /
* html.js fieldset.collapsed legend,
* html.js fieldset.collapsed legend *,
* html.js fieldset.collapsed table * {
/
display: inline; - removed /
}
/
For Safari 2 to prevent collapsible fieldsets containing tables from dissapearing due to tableheader.js. /
html.js fieldset.collapsible {
position: relative;
}
html.js fieldset.collapsible legend a {
position: static;
}
/
Avoid jumping around due to margins collapsing into collapsible fieldset border */
html.js fieldset.collapsible .fieldset-wrapper {
overflow: auto;
}

Think it's nearly ready to submit a patch for D7.

OpenID has a similar AJAX function that is giving me a bit more trouble.

Mike

OpenConcept | CLF 2.0 | Podcasting

I don't know how screen

dvessel's picture

I don't know how screen readers work so I can't say this with any certainty and if this was brought up, I apologize.

Assuming JavaScript still functions in the same way as standard browsers, shouldn't the link to hide and show the field work as designed? They serve the purpose of cutting down on clutter visually. Wouldn't it be the same for screen readers? The link to hide and show should be accessible for screen readers. If so, they can toggle it themselves and skip any fields they're not interested in.

Okay, I could have read the

dvessel's picture

Okay, I could have read the summary on the issue. Looks like it can't. It'd be nice if we knew of all the popular screen readers and their capabilities though to know what we're dealing with.

The capabilities of screen readers vary

cliff's picture

Knowing the capability of a screen reader is a lot like knowing the capability of a computer. Can computers run the latest version of Flash? Well, yes and no. Some can. Some can if their owners make certain adjustments. Other computers could never do it (he says as he looks fondly at his old Mac SE—which still runs just fine with Word 4.0, by the way).

So it is with screen readers. There are many different makes out there, many different versions of each make, and each version can be adjusted by the user to a great extent to fit his or her personal preferences. For example, JAWS is now in version 10, but staying current costs money (JAWS 10 runs about $1000) and, believe it or not, people with disabilities have no easier time than the rest of us when it comes to finding that much money to get the latest version of software we use every day.

WebAIM recently began a survey of people who use JAWS and other forms of assistive technology. One purpose of this survey is to find out what features of the assistive technology people actually know about and, of the features they know about, which ones they actually use. (Just as with any other software, screen readers can have "features" that get in the way of most of what certain users do. Word's tendency to try to out-think me on formatting issues comes to mind.) Another purpose is to find out what percentage of people using assistive technology are one, two, three, or more versions behind the latest release.

I wish it were simple, dvessel. But it's a complicated world out there. (I suspect the results of WebAIM's survey will pretty much confirm that.)

In that world, the bottom line for using Java in pages meant to be accessible is to be sure that the page still works—perhaps not as slickly, but does still work—with Java turned off.

I get the picture. How

dvessel's picture

I get the picture. How unfortunate.

The display none property is applied through js flipping on a class. It just cannot follow through and handle clicking the legend link. This leads me to think that the fix should be in js, not CSS. If done through shifting the content, it affects everyone else who choose to tab through content. Since it's off screen, it'll become unusable.

Off-screen labels should not affect tabbers

cliff's picture

At least I don't think so. The whole point of an off-screen label is to ensure that a person who can't see the page design knows where they are on the page. (They know because their reader reads the off-screen heading to them.

People who tab through the page can see — they just can't see well enough to read typical text. So they enlarge their view and use the tab to get through the page because, as anyone who has ended up in the wrong county on a Google map knows, scrolling through an enlarged image is pretty darn slow.

Take this page, for example. I can tell from the design that this heading:

Not a Real Heading

does not begin a new comment. Whenever a new comment begins, I see at least two clear signals:

  • a new border around the new comment
  • the name (and sometimes the avatar) of the person who made the new comment

Above this heading, those signals are missing, so I know that I'm still reading the same comment. People who enlarge and tab through should also be able to see the border, or at least the name, at the beginning of each new comment.

But people who can't see — or who see so poorly that even enlarging the image does them no good — can't tell anything from the design. An off-screen label can be used to tell them where comments begin and end.

When that label is positioned off screen to the left of the paragraph it labels, it serves as a stop for the tab order. The stop is at the same vertical level as the paragraph, so the tab order still works. Mike's CSS markup will work just that way.

Interestingly, I've heard speculation that future generations of screen readers will be able to read style classes. In other words, in the code for the heading of each comment:

<h3 class="title">Off-screen labels would not affect tabbers</h3>


screen readers might some day be able to detect this attribute:

class="title"


and interpret it to mean, "The next comment is beginning." If that does happen, the off-screen heading would become redundant, and we could get rid of it.

But that's a long way off. In the meantime, we have to build code that works for people who use today's screen readers.

Oh, by the way, as I said elsewhere, the initial results are out for the WebAIM survey I mentioned earlier in this thread. It's interesting reading.

For one thing, people might be keeping their screen readers more current than I had thought. If the 1,049 screen-reader users they surveyed are truly representative (it was a self-selected sample, so they might not be), 74.6 percent update their software within a year after the release of a new version. On the other hand, a significant fraction — about one in 15 — are still using a screen reader that is at least 3 years old.

Tabbing through form fields

dvessel's picture

Tabbing through form fields is very commonly done, and pushing it off screen will affect me and everyone else who choose to keep their hands on the keyboard. If it's not hidden, tabbing will follow the focus off screen giving no indication of what's going on.

Possibly a simple solution, make sure the browser can handle jQuery and how it's used in Drupal. If it can't, turn it off. No more flipping on classes through js, no more problems.

Form fields should not have off-screen headings

cliff's picture

In this post, I refer to the Illinois Center for Information Technology Accessibility's best practices for making pages work for people with disabilities. I also mention a result obtained by using their Functional Accessibility Evaluator to check whether the Drupal Groups page adheres to these best practices. These "best practices" are not in competition with WCAG — rather, they are methods for complying with WCAG while ensuring that your Web page works for everyone.

Using these best practices, we can identify form controls adequately without using off-screen headings:

  • Each input element with type=text | password | checkbox | radio | file and each select and textarea element must either be referenced by the for attribute of a label element via its id attribute, or have a title attribute. (By the way, g.d.o fails on this point.)
  • Each input element with type=button | submit | reset must have either a value attribute or a title attribute.
  • Each input element with type=image must have either an alt attribute or a title attribute.
  • Each label and legend element must have text content.

But without using off-screen headings, what can we do to identify the row of tabs at the top of this page as site navigation?

Adding a heading above the row of tabs would detract from the visual design of this page. But without that heading, people who cannot see the visual design are left with a list of links that has no clear purpose.

So we add a heading for their screen readers to announce to them, but we position that heading off-screen to the left so it won't interfere with the visual design.

It is true that when we tab to this heading, we would find nothing in focus on the screen, but we could probably figure out by the fact that the page would jump down to the level of that row of tabs that we had encountered an off-screen heading for the nav tabs. If it were me, I would just hit the tab again until a form field was in focus.

I understand that that's still an inconvenience to the tabber, but that inconvenience seems minor compared to the difficulty that people who rely on screen readers must encounter when they have to figure out the organization of a Web page with no clues to the purpose of any of possibly several lists.

Places to suggest change

mgifford's picture

Each input element with type=text | password | checkbox | radio | file and each select and textarea element must either be referenced by the for attribute of a label element via its id attribute, or have a title attribute. (By the way, g.d.o fails on this point.)

Each input element with type=button | submit | reset must have either a value attribute or a title attribute.

  • Yup. Has a value attribute

Each input element with type=image must have either an alt attribute or a title attribute.

  • That's a bit harder to pin down as there are many ways to upload images.

Each label and legend element must have text content.

Are there other places in Drupal Core where this needs to be better addressed?

I don't use tabs myself, so don't really understand how it would affect a sighted user.

Should we have some discussion about this here:
http://drupal.org/node/364219

Should there be an alternate patch suggested? An off-screen class seems to be like something that everyone (including the WCAG 2.0 folks) are suggesting. About time to formalize how to remove elements (for everyone) using CSS & how to just hide them from sighted users.

Mike

OpenConcept | CLF 2.0 | Podcasting

Wish I knew more about core

cliff's picture

Nonetheless:

  • Mike, I agree that the D7 patch fixes the first issue for input elements.
  • Images are always tough. I recognize the technical issues. There's also the problem that the alt attribute should be empty (not missing, but empty) for eye candy, but best practices are really beginning to encourage that eye candy be handled through CSS, not through content. Is there a way, over time, to make sure every uploaded image gets an alt attribute? Is there a way to prioritize and attack the core methods first? Need someone with a lot more knowledge of Drupal to help sort this out.
  • Yes, removing blank labels is a good idea — assuming that it's blank because it lacks a purpose. (Hard to get a clear idea of when this would happen.)
  • To check the tab order, at least in FireFox, simply open the page, and keep hitting "Tab." As you do, you will see a dotted outline jump from one link or form field to the next. There are two problems I know of to consider:
    • If it skips a form control, people who navigate with tabs probably won't be able to find that element.
    • If it takes a long time to get to the heart of the page, people who navigate with tabs will probably get frustrated before they find the main content. (If you do this on any g.d.o "Discussion" page, you will quickly get to the actual discussion and skip through each topic. That's good. If you do it on the page for any one item at Amazon.com, it will take forever before you get through all the links in the chrome to the information about the item. That's bad.)

Hope this helps. Looks like you're doing a great job of patching problems. And from what I know, the offscreen patch is the way to deal with this issue.

Cliff

Forcing Alt Tags for Images in Drupal

mgifford's picture

Hi Cliff,

Thanks for this feedback. Glad it seems to be generally goin gin the right direction.

I'd really like to see a 'Force alt tag' configuration option when uploading images. However at least in previous versions of Drupal, this isn't handled by Drupal Core. We can look at advancing this with modules like IMCE, FCKEditor, CCK types, and the various Image upload/gallery tools, but don't think it's something we can address as an issue with core.

Some of these are also part of external 3rd party tools that we'd need to consult about providing a force accessible option for image uploads.

Think we should start some issues about this though (but first checking to see if this feature has already been requested).

Mike

OpenConcept | CLF 2.0 | Podcasting

Forcing Alt Tags

Joshue's picture

Hi Mike and Cliff,

I'd really like to see a 'Force alt tag' configuration option when uploading images. However at least in previous versions of Drupal, this isn't handled by Drupal Core. We can look at advancing this with modules like IMCE, FCKEditor, CCK types, and the various Image upload/gallery tools, but don't think it's something we can address as an issue with core.

It is desirable for the user agent to help the author write accessible content in as many instances as possible. Some of this kind of thing can be handled via the editor such as Xstandard or whatever but as much of this kind of that that could be handled by the Drupal core would be great. In other words if the very nature of the core aided authors in the development of accessible content etc by hints, prompts, other aids - then fantastic.

But this kind of 'reminder' for alt is a good start but could cover other kinds of content like tabular data, use of elements and even things like ARIA roles/properties in due course.

Cheers

Josh

Can you think of a way to do this?

mgifford's picture

Hey Josh,

I'm not sure how to do this without fundamentally changing how Drupal manages files and provides feedback to non-core modules.

I agree that this kind of warning would be good, but just can't visualize how to even begin including it without a fairly large rewrite of certain pieces of a lot of projects.

Mike

OpenConcept | CLF 2.0 | Podcasting

Can you think of a way to do this?

Joshue's picture

Hi Mike,

Actually, there are many parts of the core or under the hood stuff that won't have to change at all. In principal the system should just support accessibility at every step. How to do this? Well much of this support can happen at a different layer to where raw data is handled or where file management takes place. Its the presentation layer I guess, as this is where the author and also the user will interact with authored content and the UI. Authors can of course roll up their sleeves and modify the CMS to suit their needs but many may not do this at all and are happy to use the Drupal API to build stuff. So the API could 'prompt' authors and design how tasks are done to suit multiple user requirements (where possible).

For many authors they just need to often be prompted on how to properly mark up HTML content (it could be argued that they should have the smarts themselves to know how to do this in the first place), maybe tips and guides as authors build their sites and applications using Drupal. Using editors that will support emerging standards like ARIA and other exciting accessibility developments would also be excellent. Some editors already do this kind of thing by providing various fields where the author can enter alternate text for graphics, captions/summaries for tables and so on. Good accessiblity related advice in the online Drupal materials that authors would use for reference would also help. It really is just about awareness of diverse user needs so exactly how the tool works can /help/ the process and ensure an improved user experience for all users. That's what already makes a CMS like Drupal so good.

Cheers

Josh

Not sure

mgifford's picture

I think this needs to be stuck at the contrib level until we get a few more of the kinks worked out.

Possibly we could consider something for an Input format whereby the HTML searches for Only local images are allowed. without alt tags or with blank alt tags. That wouldn't give an ability to alert the user at the moment though I don't think.

I think one should be able to enter in raw HTML however they want to have it cut/paste into the body window.

The most user friendly way I can see to do this is make modifications to tools like IMCE. As an example I've done this here:
http://drupal.org/node/370048

There are just a number of modules that allow you to do this though.

Following the principal you've laid out sounds nice, but I'm just not sure even where to begin to implement it.

Mike

OpenConcept | CLF 2.0 | Podcasting

CSS (mostly) & Javascript Turned Off

mgifford's picture

I think mostly it's a matter of having it work as independent of CSS & Javascript. Having a fallback that is simpler and allows every visually impaired visitor (including all of the search engines) to be able to navigate a site.

Display:none is a bit of an exception here, because screen readers respect it. Not sure if there is any other CSS that impacts screen readers.

Mike

OpenConcept | CLF 2.0 | Podcasting

Screen Readers and Show/Hide Content

Joshue's picture

@dvessel:
Often the screen reader has access to the content that is hidden using some show hide technique. It is just its visual presentation that make accordion menus and the like visually interesting. Most screen readers use a virtual buffer known as the OSM (Off Screen Model). Essentially content gets loaded into this buffer and is then explored by the user. Actually the user is not actually interacting with the screen at all but with this OSM content. This is why semantics are so important as it structures this buffered content and allows the user to navigate it easily. When the user goes into Forms Mode in JAWS for example if they need to enter data into form fields and so on, they switch from using this buffered content to interacting directly with the text fields and other form elements that are embedded in the page.

It is kinda tricky but it is important to understand these different modes to really get a grip on how screen readers work.

HTH

Josh

Summary

johnbarclay's picture

Yeah. This would help. Keeping an eye on author edited content is a chore. Its not like the templates where you fix them just once.

I added it in the features request section of Accessible Helper Module. http://drupal.org/project/issues/accessible?states=all My cvs upload is there, but the little versions table isn't showing up. I think I have to run a script to create the table. http://drupal.org/node/365160/release

It would also be nice to have a summary of how well author entered content validated as opposed to the entire page. It could be in the same format as translation overview (http://drupal.org/node/2612920) and run as cron job that checked new revisions against one of the accessibility testing apis. I'll ask around and see what apis are available for testing web page fragments. I also added this to the feature requests: http://drupal.org/node/370156

Restricting & verifying user content

mgifford's picture

On the front of restricting user content, htmLawed is a reasonable approach. It can be further customized to somewhat address alt tags:
http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/htm...
http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/htm...

But even then it could just be replacing an alt="" with a alt="image.jpg" which is really no better much of the time. Mind you it is possible to build a module that indexes all references to image tags in the database and displays their alt tags. That could be potentially useful as a validation tool.

User display would just need node id & link, image title & line as well as the existing alt tag (or warning if it is blank).

That would be a nice addition to the accessible module.

Also, this link doesn't work:
http://drupal.org/node/2612920

Mike

OpenConcept | CLF 2.0 | Podcasting

Restricting & verifying user content

Joshue's picture

Also note using alt="" will remove the image from the screen readers output. It will be ignored, this can be useful. If the image has useful content or performs some kind of function, that content or outline of function should be included in the alternate text. If the image is eye candy or just presentational then give it the null alt value, (alt=""). Adding alt="image.jpg" is pretty useless as it 1) means that the image has possible focus 2) provides no useful data for the user.

Cheers

Josh

John, Agreed on the

mgifford's picture

John, Agreed on the presentation from the Translation Overview Module

Josh, good analysis. And yes, forcing an alt value for file name doesn't really do much to improve the readability for a screen reader.

Will ask about that here - http://www.bioinformatics.org/phplabware/forum/viewforum.php?id=5&login=1

Mike

OpenConcept | CLF 2.0 | Podcasting

Josh is right on

cliff's picture

Two things always bug the heck out of people using assistive technology and, to at least that extent, interfere with accessibility:

  • when an img tag has no alt attribute
  • when an img tag has a useless alt attribute

Unfortunately, there are lots of borderline cases that introduce widespread disagreement regarding the definition of “useless.”

Whatever the solution, it would have to:

  1. Ensure that <img src="source_url.ext" /> never happens.
  2. Get the author to consider whether the best answer is <img src="source_url.ext" alt="" /> or <img src="source_url.ext" alt="brief explanation" />.
  3. Perhaps link to a place where authors who need more information could get it.

But we will never ensure that all alt attributes satisfy everyone. In many cases, I'm not sure we could even satisfy a majority. For instance, in one forum I recently witnessed a week-long — um — discussion that focused on the issue of the appropriate treatment of a photo next to the name of the same person, much like the photos that appear as avatars on this page.

Roughly equal camps insisted that the alt attribute should be:

  • alt="" (that is, empty)
  • alt="[name]" , (that is, the name of that person, but nothing more)
  • alt="photo of [name]"
  • alt="[name] - photo as [format]" (for example, "Cliff - photo as jpg file")

Smaller groups insisted on other variants as well. (A very few even thought that the filename would be a useful alt attribute. Most strongly disagreed with that position, though.)

So what goes between the quotes after alt= is truly a judgment call. We just need to be sure that the software makes it possible to put something there. From that point, authors will have to think about it and do their best.

Correct use of @alt

Joshue's picture

Good points Cliff. Its worth noting that how to use @alt correctly is mandated by WCAG 2.0 [1]

There is little you can do apart from assist the author. If the tools they use are designed to help the creation of accessible content, that is half the battle. The rest is in the hands of the author.

[1] http://www.w3.org/TR/WCAG20-HTML-TECHS/G82.html

Yes, the success criterion in WCAG 2.0 helps sort it out

cliff's picture

In fact, Josh, the url you gave, which is the WCAG success criterion for text alternatives, is a reasonable target for a link intended to help authors make the best decision.

I would pair it with a link to the corresponding explanation of failure of this success criterion. (There are links from the success criterion to this explanation, but they are so far down the page that very few people are likely to find them.)

Having done that, we just have to leave the decision up to the authors.

Noteworthy to this discussion: One specific example of a failure is to use a filename that is not otherwise a valid text alternative.

URLs included in this post:

Better than offscreen?

mgifford's picture

Alex makes some good arguments here:
http://drupal.org/node/386462#comment-1306896

About why we should be using:

height:0px; overflow: hidden;

Rather than the offscreen classes we've been tossing about.

Any thoughts or user experience based on this approach?

As he says "this is drupal core, so we should cater the unexpected"

Mike

OpenConcept | CLF 2.0 | Podcasting

Does Alex's technique really work?

cliff's picture

Mike, I would turn the question around: What evidence does Alex have that this approach actually works for people who have visual impairments or limited manual dexterity?

I do not have direct experience testing these techniques with people who have disabilities. I'm highly skeptical of Alex's approach, because it is not what I have read or heard from people who have done actual testing. I'll see if I can get some feedback from at least one of them, though.

Having said that, I notice that Alex is specifically addressing the skip nav link. WCAG calls for a skip nav link on the presumption that the nav links will always be first in the tab order. But that doesn't have to be the case: The most elegant approach is to use CSS intelligently to put content first, nav last.

We've talked about this before so I realize that it would be quite a challenge to get all themers and designers to embrace that approach. But I wonder, too, about the wisdom of forcing skip nav links on everyone, even those few who are riding the wave of the future.

Hmm.

wdmartin's picture

Hmm.

I've just run a quick spot-check with FireVox. Alex's height: 0px; overflow: hidden; method does indeed get read aloud by the screen reader. However, there are some drawbacks.

1) As written, it only works on block level elements. If you just want to hide a single link, or a form label (for example), then you'll have to add display: block; to the CSS, or else wrap your inline element in another block-level element and hide that.

2) The technique doesn't affect any margins of the targeted element might have. So if you do use it on a block level element, you'll need to add margin: 0; as well, otherwise some space remains visible on screen.

Alex lists several points in favor of his technique:

1) it is the easiest to override by (sub)themes (think of WAP, WII, NDS, iPhone etc...), simply by setting height: auto; or by explicitly setting height and overflow to auto or scroll.

I don't see why it's any easier to override than something like position: absolute; left: -999em; or similar. All you would need to do in that case is set position: static;, at which point any top/left properties stop having any effect on it. And, if you've added display: block; to make his method work with in-line elements, you'll have to override that to restore the margins.

2) the problem with the w3c example is that it actually does take space, therefor possibly confusing CSS developpers that wonder where that pixel went.

This appears hypothetical. Even granting that inexperienced CSS users may easily be confused about how positioning works, surely we could give the class a descriptive name like "offscreen" or "hidden" which describes the purpose of the code. That would go some way towards addressing the problem.

3) this method doesn't touch width, thereby allowing this to adhere to it's context.

I don't understand what that means. In a screen reader, the context is based on HTML source order. CSS doesn't affect that. Does anyone know what he was referring to here?

4) usably in any design, floating, absolute or any other you can think off.

I think he's suggesting that using absolute positioning in an offscreen class would cause problems in themes where the bulk of the layout is done via positioning. I see two ways in which it might interact with a position-based layout.

First, the offscreen element may have a positioned ancestor element closer in the tree than the root element. Suppose we have a hidden form label for some kind of form, in a block in the right side bar, and the block is positioned. If the distance in the offscreen class is something like left: -10px; top -10px, then the hidden form label might actually be visible. However, all we need to do in that case is specify a really large left/top value. This is why I favor em units for offscreen classes. A value of -999em will be nearly 12,000 pixels at most standard font sizes, which is substantially larger than any individual monitor on the market.

Second, the offscreen element might wind up screwing with the layout of any positioned children. Suppose we have a fieldset whose children have been hidden using an offscreen class. If the children are all themselves positioned, it might theoretically cause them to display in wonky ways because they'll be positioned with regard to the offscreen element. But -- they themselves will be offscreen at the time. Again, all we need is a very large value to move everything off screen.

5) already proven track record, as part of unobtrusive javascript.

May we have an example, please?

6) this is drupal core, so we should cater the unexpected ;)

I think he's being facetious here. A good thing too, since the unexpected is -- well, unexpected. ^_^

As for myself, I favor using absolute positioning to hide extra cues for screen readers. Not only is that the W3C recommendation (as m.gifford pointed out) but it's also recommended by WebAIM -- note that all their examples in that discussion of invisible content use a technique based on position: absolute. I take WebAIM's recommendations seriously. They've been specializing in web accessibility issues for ten years now. The techniques they suggest are based on substantial testing, evaluation, and discussion. I don't always follow their suggestions -- for example, they prefer leaving the "skip to main content" link visible to sighted users, which bugs me -- but their recommendations are always worth considering.

1) As written, it only works

alexanderpas's picture

1) As written, it only works on block level elements. If you just want to hide a single link, or a form label (for example), then you'll have to add display: block; to the CSS, or else wrap your inline element in another block-level element and hide that.

actually, it only doesn't work on inline elements. it works on <p>, <li>, <h#> etc.

-

2) The technique doesn't affect any margins of the targeted element might have. So if you do use it on a block level element, you'll need to add margin: 0; as well, otherwise some space remains visible on screen.

This is partially true, dependant on how your theme is set-up, (and which browser you're using)
1) If you're using any kind of "reset CSS" it'll always work properly.
2) margins are mergable, and will also show this behavior here.
3) afaik, no element you might wish to hide has (bottom-/top-)padding by default.
therefor, the only time this problem possibly shows, is when a padding has been explicitly or when an element has a padding by default.

-

Also, placing it above the top or beyond the sides still suffers from some problems:

webAIM: http://webaim.org/techniques/css/invisiblecontent/

Placing the content above the viewport is preferable to placing it to the left or right of the viewport because both of these other directions cause display irregularities in some browsers.

Accessibility Tips: http://www.accessibilitytips.com/2008/03/04/positioning-content-offscreen/ (linked from WebAIM Forums)

Avoid offscreen using top
[...]
[...]if the content you are hiding is originally below the fold on the screen, when a focusable element in the off-screen styled content receives focus, the page scrolls right to the top of the document trying to bring this content into view. This jump in content creates confusion for keyboard users, and screen magnifier users.

What is just as bad is when the user tabs again, the page again jumps, this time downward to the next focusable element. [...]

-

this method doesn't touch width, thereby allowing this to adhere to it's context.

I don't understand what that means. In a screen reader, the context is based on HTML source order. CSS doesn't affect that. Does anyone know what he was referring to here?

meaning if you want to make it visible again, you don't have to worry about width, because it is not overridden.

Just following up

mgifford's picture

1) Referencing this comment height: 0px; overflow: hidden; works for screen readers. I've got it working in my sandbox and it seems to be working pretty well (I could really use some more help on testing this though). There are some occasional glitches that require more testing, but display:none; is used pretty extensively and this is going to happen with any solution.

The thing I am beginning to like more about this solution is that it doesn't interfere with the BIDI problems that are inherent with Right to Left sites (Arabic, Hebrew, Farsi, etc). Proposing an off screen model where it is off to the left has problems for some significant non-Western languages. Putting it up top seems to have problems with confusing screen readers for text placement.

Perhaps W3C's example is just a bit too Western.

2) Maybe we need to bring some design folk in here to weigh in on what they would like to work with. Any solution we come up with is going to have some issues.

OpenConcept | CLF 2.0 | Podcasting

Neat

wdmartin's picture

That's a good link about keyboard focus scrolling the browser window when following tab order with absolutely positioned elements above the top of the viewport. I just tried it out, and it does screw up, exactly as advertised.

Regarding this:

Placing the content above the viewport is preferable to placing it to the left or right of the viewport because both of these other directions cause display irregularities in some browsers.

Archive.org's Wayback Machine has listings for WebAIM's invisible content page back to August 15th 2006, and that text has been there from the beginning. I'm inclined to wonder -- what display irregularities, exactly? Affecting which browsers? Is this still an issue? I think I'll try and get in touch with WebAIM and ask them.

mgifford's picture

Now it it could be I've just implemented this wrong, but this works fine in Firefox:

  height:0px; overflow: hidden;

Just not in Opera or Safari on the mac. Any suggestions? Maybe I implemented it incorrectly.

Mike

OpenConcept | CLF 2.0 | Podcasting

jQuery Accessibility Issues

mgifford's picture

After hearing about problems for accessibility with jQuery at the 2nd accessibility BoF at DrupalConDC I ran across the following page with a work around for the display:none problem we've been having with Drupal.

Seems like it works well enough simply to switch the default implementation so that jquery inserts display:none rather than removes it which seems to be better for screen readers. Would like to know how this works in the demo from someone who actually uses one.

Also interesting to know about the jQuery accessibility group.

Looks like this is a good place to find best practices within the jQuery community that we can implement in Drupal.

Mike

OpenConcept | CLF 2.0 | Podcasting

that is called: Unobtrusive JavaScript

alexanderpas's picture

http://en.wikipedia.org/wiki/Unobtrusive_JavaScript

its basic principles are generally understood to include:
[...]
Progressive enhancement to support user agents that may not support advanced JavaScript functionality

Accessibility

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: