2

I'm using a clipping technique to hide content for sighted users but make it available to screen readers. It looks like this:

.accessible-hide {
  position: absolute;
  clip: rect(1px 1px 1px 1px);
}

And when I want to show that item again, I can give it one of these classes, depending on its original positioning:

.accessible-show-static {
  /* No need to reset clip if we're resetting the position to static. */
  position: static;
}

.accessible-show-relative {
  /* Ditto for relative positioning. */
  position: relative;
}

.accessible-show-absolute {
  /* If the shown element should have absolute positioning, reset clipping. */
  clip: auto;
}

This works great in most browsers, but of course in Internet Explorer 8 there's a problem! With the second class, .accessible-show-absolute, resetting the clip property via clip: auto still clips to the element's box, and cuts off any children of that element that are positioned outside it (via absolute positioning or whatnot). How can I reset the clipping in a way that shows those elements?

(Note: I realise that a much tidier solution would be to simply remove the .accessible-hide class via JavaScript, but sometimes you need do do it within CSS -- like, for example, hover or focus states:)

.submenu {
    position: absolute;
    clip: rect(1px 1px 1px 1px);
}
.menu-item:hover .submenu {
    clip: auto;
    top: 100%;
    left: 0;
}
Paul d'Aoust
  • 3,019
  • 1
  • 25
  • 36
  • 1
    The issue comes from a misinterpretation of the [CSS 2.1 spec](http://www.w3.org/TR/CSS2/visufx.html#clipping), which says that `clip: auto` should not clip, but `clip: rect(auto, auto, auto, auto)` should clip to the padding box. I guess IE8 and Safari 5 interpret the former as the latter. – Paul d'Aoust Nov 01 '13 at 17:14

2 Answers2

3

Just give it a larger clip for IE8 than is necessary. This will work for all other browsers too, so you don't need any browser-specific hacks (although you may want to also include the newer comma-separated syntax for rect(), which isn't supported by IE7 but is actually valid CSS unlike the non-comma-separated syntax):

.accessible-show-absolute {
  clip: rect(-9999px 9999px 9999px -9999px);
}
Paul d'Aoust
  • 3,019
  • 1
  • 25
  • 36
1

clip: inherit

As long as the parent container doesn't have clip set, you can use clip: inherit to remove the clipping mask in IE8 as an alternative to clip: auto.

In your first example:

.accessible-hide {
    position: absolute;
    clip: rect(1px 1px 1px 1px);
}

.accessible-show-absolute {
    /* If the shown element should have absolute positioning, reset clipping. */
    clip: inherit;
}

In your second example:

.submenu {
    position: absolute;
    clip: rect(1px 1px 1px 1px);
}
.menu-item:hover .submenu {
    clip: inherit;
    top: 100%;
    left: 0;
}
gfullam
  • 11,531
  • 5
  • 50
  • 64
  • 1
    Nice answer; upvoting because it feels tidier than my answer. (If IE8 supported `initial` that'd be even better.) I find it quite odd that `clip` is non-inherited but `inherit` successfully resets it. Oh CSS. – Paul d'Aoust Feb 19 '15 at 20:32
  • The confusing thing now is that both your answer and mine are correct... so which one to mark as 'the' correct one? One of us could our answer to include the other person's answer; I wouldn't want to steal reputation juice from you though. – Paul d'Aoust Feb 19 '15 at 20:34
  • Don't sweat it too much. If you need guidance handling the situation, here is a good post on Meta: [Which answer do I accept if I have multiple correct answers?](http://meta.stackexchange.com/a/13397) :) I answered more than a year late, so I'm inclined to say keep your currently accepted answer if that's what you used. I appreciate the up vote. – gfullam Feb 19 '15 at 21:25