visuallyhidden sometimes cause a horizontal scrollbar on IE7 #194

Closed
tombigel opened this Issue Nov 15, 2010 · 26 comments

Comments

Projects
None yet
7 participants
@tombigel

Paul's note: the original visuallyHidden technique is from Jonathan Neal.. it's an iteration of research here http://www.webaim.org/techniques/css/invisiblecontent/ and it was first published here: http://j.mp/visuallyhidden

Below we encounter some edge case issues and revise it again.

I encountered an edge case when I used visuallyHidden on an element wider than the page in IE7.

I don't have a test case to show right now (I fixed the bug), but I'll try to describe it:

In a page header I had the following structure:

Example HTML:

<div id="container">
    <header>
       <img id="logo" ... />
       <nav> ... </nav>
       <h1 class="visuallyHidden"> ... Long Text ... </h1>
    </header>
    ...
    ...
<div>

Example CSS:

#container { width: 960px; }
header img { float:left }
header nav { float:right }

The result of this setup was that the hidden H1 (doesn't matter why is it hidden on this page) is floated after the nav element.
Because visuallyHidden applies position:absolute on the element, the text in the H1 does not break, and on IE7 only (Not even on IE6) it's origin is right after the nav menu and it widens the page and causes a horizontal scrollbar.

My immediate solution for this issue was to add left:0 to visuallyHidden, but if the text inside the H1 was a bit wider it would widen the page again.

I don't really understand why clip is better than other methods, before h5bp I used to use this:

.visuallyHidden { overflow:hidden; height:1px; margin-top:-1px; }
/* also, we can add position:absolute and a width */

and it worked perfectly. (for example, look for the the hidden accessibility links and hidden H2 headers on this old demo: http://tendu.tombigel.com)

@jonathantneal

This comment has been minimized.

Show comment
Hide comment
@jonathantneal

jonathantneal Nov 16, 2010

Member

If we want to correct for every seemingly-reasonable possibility of overflow in every browser then we may want to consider.

.visuallyHidden {
    border: 0 !important;
    clip: rect(0 0 0 0) !important;
    height: 1px !important;
    margin: -1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    width: 1px !important;
}

And I know !important is so ugly, but we're hacking here. There is no available property that would do what visibility: hidden; should probably do to begin with on screen-reading devices.

I've tested this class successfully in JAWS 12 and VoiceOver for Mac.

Member

jonathantneal commented Nov 16, 2010

If we want to correct for every seemingly-reasonable possibility of overflow in every browser then we may want to consider.

.visuallyHidden {
    border: 0 !important;
    clip: rect(0 0 0 0) !important;
    height: 1px !important;
    margin: -1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    width: 1px !important;
}

And I know !important is so ugly, but we're hacking here. There is no available property that would do what visibility: hidden; should probably do to begin with on screen-reading devices.

I've tested this class successfully in JAWS 12 and VoiceOver for Mac.

@tombigel

This comment has been minimized.

Show comment
Hide comment
@tombigel

tombigel Nov 17, 2010

why use "clip" if using all the rest?

why use "clip" if using all the rest?

@jonathantneal

This comment has been minimized.

Show comment
Hide comment
@jonathantneal

jonathantneal Nov 17, 2010

Member

The 0 clipping will avoid the potential 1x1 visible pixel speck.

Member

jonathantneal commented Nov 17, 2010

The 0 clipping will avoid the potential 1x1 visible pixel speck.

@tombigel

This comment has been minimized.

Show comment
Hide comment
@tombigel

tombigel Nov 17, 2010

This is why i use height:1px;margin-top:-1px;overflow:hidden; .
It seems to me like it fulfills the same purpose.

This is why i use height:1px;margin-top:-1px;overflow:hidden; .
It seems to me like it fulfills the same purpose.

@jonathantneal

This comment has been minimized.

Show comment
Hide comment
@jonathantneal

jonathantneal Nov 17, 2010

Member

We need position: absolute to remove the element's affect on the document flow. We need clip: rect(0 0 0 0) to remove the element's 1x1 pixel of visibility; test your method on an element with a background color (you can see, like black on white) and you will see a remaining 1x1 dot.

Member

jonathantneal commented Nov 17, 2010

We need position: absolute to remove the element's affect on the document flow. We need clip: rect(0 0 0 0) to remove the element's 1x1 pixel of visibility; test your method on an element with a background color (you can see, like black on white) and you will see a remaining 1x1 dot.

@tombigel

This comment has been minimized.

Show comment
Hide comment
@tombigel

tombigel Nov 17, 2010

Oh... never tested this with a background, you are right.

Oh... never tested this with a background, you are right.

@paulirish

This comment has been minimized.

Show comment
Hide comment
@paulirish

paulirish Nov 18, 2010

Member

reopening this so we can fix this in the css first...

Member

paulirish commented Nov 18, 2010

reopening this so we can fix this in the css first...

@Laz75

This comment has been minimized.

Show comment
Hide comment
@Laz75

Laz75 Nov 18, 2010

I had the same problem, but with Safari and Chrome (and IE9 too). In my case the element with the visuallyhidden class had some large width (set by a different selector) and that's what was causing the scrollbar. I could easily solve it adding a width: auto !important, but I see the solution proposed here seems to be much more complete.

Laz75 commented Nov 18, 2010

I had the same problem, but with Safari and Chrome (and IE9 too). In my case the element with the visuallyhidden class had some large width (set by a different selector) and that's what was causing the scrollbar. I could easily solve it adding a width: auto !important, but I see the solution proposed here seems to be much more complete.

@paulirish

This comment has been minimized.

Show comment
Hide comment
@paulirish

paulirish Nov 19, 2010

Member

I feel very comfortable changing it to

position: absolute !important;  
width: 1px !important;  
clip: rect(0 0 0 0); 
padding: 0 !important;
  • It lacks an !important on the clip, because who uses that.
  • it drops the secondary clip, which i guess wasnt necessary, based on what jon pasted above? plz confirm, jon!
  • it doesnt kill border or height, mostly as i think that's overkill...

How's this sound to everyone?

Member

paulirish commented Nov 19, 2010

I feel very comfortable changing it to

position: absolute !important;  
width: 1px !important;  
clip: rect(0 0 0 0); 
padding: 0 !important;
  • It lacks an !important on the clip, because who uses that.
  • it drops the secondary clip, which i guess wasnt necessary, based on what jon pasted above? plz confirm, jon!
  • it doesnt kill border or height, mostly as i think that's overkill...

How's this sound to everyone?

@tombigel

This comment has been minimized.

Show comment
Hide comment
@tombigel

tombigel Nov 19, 2010

About height:
Was it tested with long lists to see if on certain browsers it doesn't trigger a vertical scrollbar?

About height:
Was it tested with long lists to see if on certain browsers it doesn't trigger a vertical scrollbar?

@paulirish

This comment has been minimized.

Show comment
Hide comment
@paulirish

paulirish Nov 24, 2010

Member

Was it tested with long lists to see if on certain browsers it doesn't trigger a vertical scrollbar?

nope.. can you try it out?

Member

paulirish commented Nov 24, 2010

Was it tested with long lists to see if on certain browsers it doesn't trigger a vertical scrollbar?

nope.. can you try it out?

@tombigel

This comment has been minimized.

Show comment
Hide comment
@tombigel

tombigel Nov 24, 2010

busy week at work, but i'll try to find the time for an experiment.
btw - the site where i had the issue is up: http://zibaba.com

busy week at work, but i'll try to find the time for an experiment.
btw - the site where i had the issue is up: http://zibaba.com

@jonathantneal

This comment has been minimized.

Show comment
Hide comment
@jonathantneal

jonathantneal Nov 24, 2010

Member
/*
    Visually Hidden: Level 1
    Does not support:
        Box exceeding x/y of window (by width or position) in Chrome
        Padding exceeding x/y of window in Chrome & IE7
        Border exceeding x/y of window in Chrome & IE7
*/
.visuallyHidden {
    clip: rect(0 0 0 0);
    overflow: hidden !important;
    position: absolute !important;
}

/*
    Visually Hidden: Level 2
    Does not support:
        Padding exceeding x/y of window in Chrome & IE7
        Border exceeding x/y of window in Chrome & IE7
*/
.visuallyHidden {
    height: 1px !important;
    margin: -1px !important;
    width: 1px !important;
}

/*
    Visually Hidden: Level 3
    Does not support:
        Padding exceeding x/y of window in Chrome & IE7
        Border exceeding x/y of window in Chrome & IE7
*/
.visuallyHidden {
    padding: 0 !important;
}

/*
    Visually Hidden: Level 4
    Supports all known width, position, css combinations
*/
.visuallyHidden {
    border: 0 !important;
}
Member

jonathantneal commented Nov 24, 2010

/*
    Visually Hidden: Level 1
    Does not support:
        Box exceeding x/y of window (by width or position) in Chrome
        Padding exceeding x/y of window in Chrome & IE7
        Border exceeding x/y of window in Chrome & IE7
*/
.visuallyHidden {
    clip: rect(0 0 0 0);
    overflow: hidden !important;
    position: absolute !important;
}

/*
    Visually Hidden: Level 2
    Does not support:
        Padding exceeding x/y of window in Chrome & IE7
        Border exceeding x/y of window in Chrome & IE7
*/
.visuallyHidden {
    height: 1px !important;
    margin: -1px !important;
    width: 1px !important;
}

/*
    Visually Hidden: Level 3
    Does not support:
        Padding exceeding x/y of window in Chrome & IE7
        Border exceeding x/y of window in Chrome & IE7
*/
.visuallyHidden {
    padding: 0 !important;
}

/*
    Visually Hidden: Level 4
    Supports all known width, position, css combinations
*/
.visuallyHidden {
    border: 0 !important;
}
@jonathantneal

This comment has been minimized.

Show comment
Hide comment
@jonathantneal

jonathantneal Nov 24, 2010

Member
/*
    Visually Hidden: Level 4 Combined
*/
.visuallyHidden {
    border: 0 !important;
    clip: rect(0 0 0 0);
    height: 1px !important;
    margin: -1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    width: 1px !important;
}
Member

jonathantneal commented Nov 24, 2010

/*
    Visually Hidden: Level 4 Combined
*/
.visuallyHidden {
    border: 0 !important;
    clip: rect(0 0 0 0);
    height: 1px !important;
    margin: -1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    width: 1px !important;
}
@nimbupani

This comment has been minimized.

Show comment
Hide comment
@nimbupani

nimbupani Dec 1, 2010

Member

Updated visuallyHidden rule to make sure it overrides all other declarations. Thanks Jonathan Neal. Closed by 07768ed

Member

nimbupani commented Dec 1, 2010

Updated visuallyHidden rule to make sure it overrides all other declarations. Thanks Jonathan Neal. Closed by 07768ed

@nimbupani

This comment has been minimized.

Show comment
Hide comment
@nimbupani

nimbupani Jan 3, 2011

Member

Note: The classname uses an inconsistent camelcase. Needs to be updated to use lowercase.

Member

nimbupani commented Jan 3, 2011

Note: The classname uses an inconsistent camelcase. Needs to be updated to use lowercase.

@nimbupani

This comment has been minimized.

Show comment
Hide comment
@nimbupani

nimbupani Jan 19, 2011

Member

Fixed by 6da1bd8

Member

nimbupani commented Jan 19, 2011

Fixed by 6da1bd8

dustinwhittle pushed a commit that referenced this issue Apr 18, 2011

dustinwhittle pushed a commit that referenced this issue Apr 18, 2011

@alanfluff

This comment has been minimized.

Show comment
Hide comment
@alanfluff

alanfluff Feb 24, 2012

I just found an IE7 horizontal scrollbar problem that is fixed when I replace the .visuallyhidden CSS from H5BP 3.0.1 (this):

.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }

with the CSS from 'Visually Hidden: Level 4 Combined' #194 (comment) (this):

/*
Visually Hidden: Level 4 Combined
*/
.visuallyHidden {
    border: 0 !important;
    clip: rect(0 0 0 0);
    height: 1px !important;
    margin: -1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    width: 1px !important;
}

As a newbie here I hope it was OK that I just dropped in and added this comment.

I just found an IE7 horizontal scrollbar problem that is fixed when I replace the .visuallyhidden CSS from H5BP 3.0.1 (this):

.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }

with the CSS from 'Visually Hidden: Level 4 Combined' #194 (comment) (this):

/*
Visually Hidden: Level 4 Combined
*/
.visuallyHidden {
    border: 0 !important;
    clip: rect(0 0 0 0);
    height: 1px !important;
    margin: -1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    width: 1px !important;
}

As a newbie here I hope it was OK that I just dropped in and added this comment.

@cust0dian

This comment has been minimized.

Show comment
Hide comment
@cust0dian

cust0dian Feb 24, 2012

@alanfluff, the only difference between the two is that in latter !important rules are used and if you encounter such problems with stock one, make sure to not define any rules in css/style.css after helper classes.

@alanfluff, the only difference between the two is that in latter !important rules are used and if you encounter such problems with stock one, make sure to not define any rules in css/style.css after helper classes.

@alanfluff

This comment has been minimized.

Show comment
Hide comment
@alanfluff

alanfluff Feb 24, 2012

Thanks cust0dian, I'll check the actual CSS.

I did check in the SASS (that I am new to) that this and the other helper classes came last but of course it's how the CSS looks that counts so maybe it's my SASS use. I'll try to check and comment. Cheers.

Thanks cust0dian, I'll check the actual CSS.

I did check in the SASS (that I am new to) that this and the other helper classes came last but of course it's how the CSS looks that counts so maybe it's my SASS use. I'll try to check and comment. Cheers.

@alanfluff

This comment has been minimized.

Show comment
Hide comment
@alanfluff

alanfluff Feb 24, 2012

@cust0dian I have two stylesheets the second one was IE specific, the first included the helper classes so I thought that was it and swapped them around.

But the problem is still there for IE7. I'm surprised :/ I really thought that would have been the reason.

In case it helps, this is the particular tag that is causing the problem for IE7:

<img class="visuallyhidden" src="/img/logo.png" alt="My Co Inc. logo" />

The site is on a local dev platform tied into a CMS and so not easy to move online, but if there's any more I can tell you/others to help see if this is a real issue or not, just say the word.

@cust0dian I have two stylesheets the second one was IE specific, the first included the helper classes so I thought that was it and swapped them around.

But the problem is still there for IE7. I'm surprised :/ I really thought that would have been the reason.

In case it helps, this is the particular tag that is causing the problem for IE7:

<img class="visuallyhidden" src="/img/logo.png" alt="My Co Inc. logo" />

The site is on a local dev platform tied into a CMS and so not easy to move online, but if there's any more I can tell you/others to help see if this is a real issue or not, just say the word.

@alanfluff

This comment has been minimized.

Show comment
Hide comment
@alanfluff

alanfluff Feb 24, 2012

Just as an experiment and in case it helped explain I wondered if this might work:

<div class="visuallyhidden"><img src="/img/logo.png" alt="My Co Inc. logo" /></div>

and it does—that is the standard CSS from H5BP 3.0.1 does not cause a horizontal scrollbar in IE7 when the visuallyhidden class is applied to a parent of that image rather than the image itself.

I don't suggest this is the answer, just thought I'd note it in case it helps.

Just as an experiment and in case it helped explain I wondered if this might work:

<div class="visuallyhidden"><img src="/img/logo.png" alt="My Co Inc. logo" /></div>

and it does—that is the standard CSS from H5BP 3.0.1 does not cause a horizontal scrollbar in IE7 when the visuallyhidden class is applied to a parent of that image rather than the image itself.

I don't suggest this is the answer, just thought I'd note it in case it helps.

@cust0dian

This comment has been minimized.

Show comment
Hide comment
@cust0dian

cust0dian Feb 24, 2012

Do scrollbars appear in this test case? (I don't have IE7 right now.)

Do scrollbars appear in this test case? (I don't have IE7 right now.)

@alanfluff

This comment has been minimized.

Show comment
Hide comment
@alanfluff

alanfluff Feb 24, 2012

@cust0dian No, neither in jsFiddle nor in a test page made from it:

<!DOCTYPE html>
<html lang="en">
<head>

<title>Hello World</title>

<meta charset="utf-8" />
<meta name="description" content="Describe me please" />
<meta name="author" content="Made by Alan" />

<style>

.bigimg { width: 2000px; height: 2000px; }

.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }


</style>

<link rel="shortcut icon" type="image/ico" href="XXX.ico" />

<!-- enable HTML5 elements in IE7+8 -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

</head>

<body class="helloWorld">

<p>IMG element visually hidden:<p>
<img class="visuallyhidden bigimg" src="img.png" alt="">

<p>Container DIV element visually hidden:</p>
<div class="visuallyhidden"><img class="bigimg" src="img.png" alt=""></div>

</body>
</html>

@cust0dian No, neither in jsFiddle nor in a test page made from it:

<!DOCTYPE html>
<html lang="en">
<head>

<title>Hello World</title>

<meta charset="utf-8" />
<meta name="description" content="Describe me please" />
<meta name="author" content="Made by Alan" />

<style>

.bigimg { width: 2000px; height: 2000px; }

.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }


</style>

<link rel="shortcut icon" type="image/ico" href="XXX.ico" />

<!-- enable HTML5 elements in IE7+8 -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

</head>

<body class="helloWorld">

<p>IMG element visually hidden:<p>
<img class="visuallyhidden bigimg" src="img.png" alt="">

<p>Container DIV element visually hidden:</p>
<div class="visuallyhidden"><img class="bigimg" src="img.png" alt=""></div>

</body>
</html>
@cust0dian

This comment has been minimized.

Show comment
Hide comment
@cust0dian

cust0dian Feb 24, 2012

@alanfluff, then it's something in your CMS styles or somewhere that selects IMG element and overwriting overflow property. Definitely not H5BP causes it.

Just stick with wrapper DIV and you should be fine.

@alanfluff, then it's something in your CMS styles or somewhere that selects IMG element and overwriting overflow property. Definitely not H5BP causes it.

Just stick with wrapper DIV and you should be fine.

@alanfluff

This comment has been minimized.

Show comment
Hide comment
@alanfluff

alanfluff Feb 24, 2012

@cust0dian THANK you and sorry to have bothered the thread with this, glad it's me.

@cust0dian THANK you and sorry to have bothered the thread with this, glad it's me.

This issue was closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment