Looking For Generalized Solutions for CSS display:none; Alternates

mgifford's picture

last year I started an email exchange with an accessibility expert here in Canada. As I pointed out last year, there is a wealth of information on Drupal about strengths/weaknesses of any accessibility enhancements that can be useful for other tools.

The threads of discussion on the CSS display:none; start in April 2006 and was fixed in August 2009 in core:
http://drupal.org/node/58941
http://drupal.org/node/473396

It was then later determined to be broken again VoiceOver, so it was rewritten:
http://drupal.org/node/718922

The end result that was found was:

.element-invisible {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
}

and also:

.element-invisible.element-focusable:active,
.element-invisible.element-focusable:focus {
  position: static !important;
  clip: auto;
}

There were noted concerns about an off left (top/up/down) solution as noted in the first series of discussions. There were also a wealth of options described here.

In trying to implementing Drupal 7's solution he ran into some problem:

1) clip: rect(1px 1px 1px 1px) fails CSS validation. I got around this by using conditional comments to load this in separate IE6 and IE7 stylesheets (CSS validators ignore these files when checking a Web page).

2) Content that is supposed to be made visible upon focus while remaining absolutely positioned will become visible upon focus in all browsers except IE6/7. To make it visible in IE6/7 I have to use static or relative positioning which breaks the intended design. I dealt with this by using the off-left solution in the IE6 and IE7 stylesheets so only IE6 and IE7 will have rtl and bidirectional issues.

3) Solution doesn't work for content that needs to become visible upon mouse hover (only works for keyboard focus). I dealt with this instead by using the CSS opacity property (with the IE opacity filter used in IE-specific stylesheets).

Now I hate testing IE as I'm a Linux/Mac guy. But surely this works in default D7 themes. If not, where are the problems with the testing process?

.element-invisible {
  position: absolute;
  clip: rect(1px, 1px, 1px, 1px);
  height: 1px !important;
  width: 1px !important;
  overflow: hidden !important;
}

To allow this to become visible when it gains keyboard focus, use the following:

.element-invisible.element-focusable:active,
.element-invisible.element-focusable:focus
{
  position: static;
  clip: auto;
  height: inherit !important;
  width: inherit !important;
  overflow: inherit !important;
}

clip: rect(1px 1px 1px 1px); was specified in separate IE6 and IE7 CSS files (using conditional comments).

I'm neither a CSS guy or a IE person. Would like some feedback though to see if anyone else has noticed a problem with IE6 or IE7 with D7. Would it be useful to clarify how best to implement this for other themes in Drupal?

Do we need to clarify the module upgrade docs here: http://drupal.org/node/254940#element-hidden

The Skip links documentation doesn't seem to be very clear: http://drupal.org/node/254940#skip-link

I believe that focusable elements need to follow the following format:

<a href="#main-content" class="element-invisible element-focusable">Skip to main content</a>

I'd appreciate feedback on this.

Has anyone taken the time to look at some of the new D7 themes to see how they have been applying the accessibility work we started in core?

Comments

More thoughts on hiding content

mgifford's picture

I haven't had a chance to edit the article above further, but I wanted to point folks to:

http://snook.ca/archives/html_and_css/hiding-content-for-accessibility

Good to have more discussion/debate about how to best implement this. It's hard to begin to summarize all of the approaches & views that were considered to implement this.

I posted a D8 followup

IE6/7

Suzy's picture

IE6/7 behaviour observations: (only testing method, not tested any default themes as I write my own sorry!)

2) Content that is supposed to be made visible upon focus while remaining absolutely positioned will become visible upon focus in all browsers except IE6/7. To make it visible in IE6/7 I have to use static or relative positioning which breaks the intended design. I dealt with this by using the off-left solution in the IE6 and IE7 stylesheets so only IE6 and IE7 will have rtl and bidirectional issues.

This is part of an old IE bug - the hover/focus/active rules need a bit more for IE6/7 - usually any default property that is is not specified on the original rule, however the problem is which one would not affect the intention, I think visibility: inherit should be good to go.. so I tested this and found it works to make the content visible: (the first clip rule is also needed for IE7)

  visibility: inherit; /* IE6 & 7 /
  clip: rect(auto); /
IE6 and 7 */
  clip: auto;

not sure what's meant by #3, as I tested this with hover and it worked fine

As for the IE7 scrollbar issue reported in some places, I can replicate and found that adding left: 0; to the .element-invisible rule should help most cases - why it happens is that the hidden block in most cases will be 100% of the container in width, if an unforced scroll situation, which if the hidden element is at the end of a line (like after a float instead of under it grr!) creates IE's scroll - so adding that just helps IE to justify to the left. Now the position: static reveal is OK as it will ignore this, like clip itself, however if a absolute/relative position reveal is needed this may need overruled in theme.

The above will not cure the "forced" scrollbar problem (as tested by using white-space: nowrap; on a long text element) reported by snook - but that must surely be a real edge case? - Most designs now have overflow: hidden somewhere on a containing (block formatting context) div and that in itself will make Safari/Opera and IE crop the content so I can't think of a legitimate test case.. however in the interest of trying

Note: the width/height 1px overruled with width:inherit fix - does not work in IE6/7, they don't "get" inherit so they do not overrule the 1px :( - for info, IE7 and below only supports !inherit on direction and visibility

and finally while playing around I discovered that the above IE hover bug, the default IE scrollbar and the forced scrollbar scenario can all be counteracted (in LTR anyway, and most RTL I think) using right: 0;

.element-invisible {
  position: absolute !important; /* becomes the same width as it's container in IE7 /
  right: 0; /
adding this prevents IE 7 scrollbar in most cases and forced scrollbars in all browsers and IE hover bug! /
  clip: rect(1px 1px 1px 1px); /
IE6, IE7 /
  clip: rect(1px, 1px, 1px, 1px);
}

#header:hover .element-invisible {
/
position: static;/
  clip: auto;
  clip: rect(auto); /
IE6 and 7 /
  right: auto; /
reset not required if position static but this also cures the IE Hover Bug as a side effect /
  visibility: inherit; /
IE 6 & 7 hover bug override */
}

(position is commented out as this was the hover code as I was also testing if element to remain Absolute positioned scenario):

if right: 0; is used the right: auto override is enough to cure the IE hover bug, so you wouldn't actually need the visibility: inherit rule, however I left it there with the bug comment for completeness

Just some random findings as I was re-checking how this method was doing :)

Thanks Suzy

mgifford's picture

I added a link back to your comment form the issue.

I'm not sure how well IE6 or IE7 will need to be supported in D8, but this is certainly something that can be considered.

The great thing about approaching this with these generalized classes is that they can just be over-written in the custom.css files of your specific theme.

I am sure that these changes will be beneficial.

Accessibility

Group notifications

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

Hot content this week