Closed DingoEatingFuzz closed 13 years ago
hmmm, i can't replicate the issue, would you mind provide a test case?
Thanks for the quick update.
Here are a couple pages that isolate the problem:
Using comments (has compatibility view button)
Not using comments (no compatibility view button)
Themble is an example of a complete site with the problem:
I noticed that the html5-boilerplate site doesn't have the problem. It could also be htaccess related.
yea, it happens without htaccess, there is the following in the htaccess that fixes this
BrowserMatch MSIE ie
Header set X-UA-Compatible "IE=Edge,chrome=1" env=ie
It might be a good idea to note that on the site or in the documentation for the folks who aren't using Apache :)
hmm, maybe i'm misunderstanding something, but doesn't this mean that the http-equiv=x-ua-compatible solution in the html is useless?
if you have to put in the http header, then you do not need the html-tag...
I think so too. The X-UA-Compatible meta tag is in fact useless here and could as well be removed from index.html of the boilerplate. Why was this issue closed again?
Not gonna lie: I accidentally closed it by clicking the "comment and close" button rather than the "comment" button. And now I don't know how to reopen it. Kind of a github noob.
From what I have noticed, the X-UA-Compatible meta tag in this scenario is useless, since without the htaccess redundancy, it doesn't work (or at least doesn't work fully). As mentioned originally, if the IE comments aren't wrapped around the html tag (they can still be used elsewhere) the meta tag works as expected. It seems to me like the HTML 5 boilerplate should be pushing for HTML(5) solutions. Not Apache ones.
reopened..
I just retitled the issue as "IE conditional comments around html tag adds Compat View icon to address bar"
Agreed this sucks. I don't think it'll make the 1.0 but let's figure out how best to address this for 1.1
Also I could repro in IE9 RC.. I imagine this is also present in IE8 final? Can someone confirm?
Confirmed: http://i.imgur.com/rChH7.jpg
The fix is as simple as getting that <meta http-equiv... />
in before the conditional comments. So to resolve it, we could do something like this:
<!doctype html> <html class="no-js" lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <title>ie test</title> </head> <!--[if lt IE 7 ]> <body class="ie6"> <![endif]--> <!--[if IE 7 ]> <body class="ie7"> <![endif]--> <!--[if IE 8 ]> <body class="ie8"> <![endif]--> <!--[if (gte IE 9)|!(IE)]><!--> <body> <!--<![endif]--> <p>test</p> </body> </html>
But it might be worth mentioning that "X-UA-Compatible" is not valid HTML5, so I think it's perfectly acceptable to remove it all together.
I vaguely remember that there has been a reason for moving the conditional comments from the body tag to the html tag in the first place. Something with deferred loading of scripts in IE8?
Update: Ah, here it is http://webforscher.wordpress.com/2010/05/20/ie-6-slowing-down-ie-8/
A potential solution to this problem could be this arrangement:
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><![endif]-->
<title>Non-blocking downloads in IE8</title>
<link rel="stylesheet" href="css/some.css">
<link rel="stylesheet" href="css/random.css">
<link rel="stylesheet" href="css/files.css">
<!--[if IE 6 ]><link rel="stylesheet" href="css/and.css"><![endif]-->
<link rel="stylesheet" href="css/a.css">
<link rel="stylesheet" href="css/couple.css">
<link rel="stylesheet" href="css/more.css">
<link rel="stylesheet" href="css/huzzah.css">
</head>
<!--[if lt IE 7 ]> <body class="ie6"> <![endif]-->
<!--[if IE 7 ]> <body class="ie7"> <![endif]-->
<!--[if IE 8 ]> <body class="ie8"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <body> <!--<![endif]-->
<h1 style='color:green'>Non-blocking downloads in IE8.</h1>
</body>
</html>
This doesn't block downloads in IE 8 (see test cases below) and removes the compat view icon (only tested in current IE9).
Non-blocking: http://www.webpagetest.org/result/110320_MW_6S9X/
Blocking: http://www.webpagetest.org/result/110320_W1_6S9H/
P.S. As a plus it validates as HTML5 :)
maybe the documentation could be changed a little (assuming the http-header method is bulletproof). currently in the html it is:
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
Remove this if you use the .htaccess -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
we could change the html-comment to say something like you-should-do-this-in-htaccess-only-do-it-in-html-if-you-cannot-do-that...
@gabor I agree, the http-header method should be the way to do this. Although Google planned to lobby validators to tolerate "X-*" http-equiv values and keys according to the comments on this issue here: http://code.google.com/p/chromium/issues/detail?id=22795
On another note, my sample code from above doesn't invoke chrome frame so it has to be changed to this (on line 5):
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!--[if IE]><![endif]-->
The empty conditional comment is because of the blocking issue in IE8. This all is starting to get a little messy :)
I also tested this issue and some combinations for resolving it. I believe that the better solution is to both move the conditional comments down and add the classes to with javascript:
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta charset="utf-8">
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
Remove meta X-UA-Compatible if you use the .htaccess -->
<!--[if lt IE 7 ]> <script>document.documentElement.className+=' ie6';</script> <![endif]-->
<!--[if IE 7 ]> <script>document.documentElement.className+=' ie7';</script> <![endif]-->
<!--[if IE 8 ]> <script>document.documentElement.className+=' ie8';</script> <![endif]-->
<!-- Always put your css and js below this line, see
https://github.com/paulirish/html5-boilerplate/issues/issue/378 -->
<title></title>
I've added a pull request with this solution. The only downside I can imagine is having to support IE < 9 with javascript disabled. And this would be such an edge case that pointing an URL to this issue should resolve the problem.
I forgot to mention. AFAIK, Google Chrome frame docs advise putting the X-UA-Compatible as above in the document as possible. Since <meta charset="utf-8">
must be within the first 512 bytes it was necessary for it to be put before the X-UA-Compatible in previous versions.
So this time I changed the order, since the charset will not be affected by the conditional comments above it.
@irae: it might be a nice idea, but is it too much of a hack? imo
I agree. I think the Javascript idea is very amateurish, especially since it seeks to resolve an issue caused by a piece of code that is not valid HTML5 in the first place. I would hate to see the HTML5 Boilerplate dragged away from the standards-compliance and best-practice foundation on which it was initially built.
Someone put in a pull request (might be the same guy; I don't remember) offering up the same bit of code. I would like to think that it isn't actually taken into serious consideration.
I also agree that this is amateurish. But I have a project that I am writing the front end code and I will not have access to the server. I don't even know where they will host it, what technologies, etc. This is a solution, ugly as it is, that is working better then the current solution of conditional comments around the <html>
tag. In this case I prefer this ugliness that's only comments to modern browsers to broken functionality.
If anyone comes up with a better idea, I will be glad to change in my working projects and remove my own pull request.
I noticed that my other comment on here is a bit distorted, so here are my two cents again.
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!--[if IE]><![endif]-->
<title>Everybody here is a cloud</title>
</head>
<!--[if lt IE 7 ]> <body class="ie6"> <![endif]-->
<!--[if IE 7 ]> <body class="ie7"> <![endif]-->
<!--[if IE 8 ]> <body class="ie8"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <body> <!--<![endif]-->
<h1>Everybody here will evaporate</h1>
</body>
</html>
Like I said before, we need the empty conditional comment because of the newly introduced "IE8 blocking Issue". See test cases for details on that: Non-blocking: http://www.webpagetest.org/result/110320_MW_6S9X/ Blocking: http://www.webpagetest.org/result/110320_W1_6S9H/
Thoughts? I like this one better, because it involves no Javascript to add the classes.
edit: corrected a little slip in the code
@MartinMa: I think a problem with (2) is that a lot of CMS add id/classes to the body
tag, which would create a lot of duplication. Furthermore, it could create problems for people writing IE6-specific styles because the browser doesn't really support chains of classes, e.g., ie6.mybodyclass {}
or we remove 'h5bp stripped version' and make h5bp download rely more on boilerplate custom (aka initializr), if people tick the option to have conditional comments, then a warning says they must have the X-UA-Compatible in server config.
I use "" as the very first line in my HTML files. Then I use the "useful" conditional comments after the X-UA-Compatible meta.
IE8 is still in "IE8 Standards Mode". Didn't try with IE9 and I don't know how to check in IE7.
My 2 cents.
ignore me
I don't get it. I said I'm in standards mode event with these comments before the tag.
But some comments in this bug are saying that if you use some conditional comments around , then IE goes to quirks mode.
@julienw Apologies, I misread your previous comment. If you open up IE8's dev tools, please can you check if you have "Browser Mode" set to "Internet Explorer 8" or "Internet Explorer 8 Compatibility View". If it's the former, it shouldn't drop the doc into IE7 Standards. If it's the later, it should drop the doc into IE7 Standards when using conditional comments outside of the opening html
tag.
I just checked using "IE8 Compatibility View", and it's still IE8 standards.
@julienw Please could you drop a reduced testcase in a pastebin and link to it here? Thanks
http://mathiasbynens.be/notes/safe-css-hacks#comment-13 may be of interest.
Seems like there is a bit of confusion. Just because the button is showing doesn't mean that compatibility view is enabled. The button will be in a depressed state for that.
If the meta tag/http header is interpreted correctly, the button doesn't display at all (which is the desired behavior this ticket is trying to achieve).
OK! @julienw seems correct, here's a basic testcase of what he is describing. It doesn't drop IE8 into IE7 mode. But other issues related to use on body
remain.
Ex 1 : http://pastie.org/1926628
Switching the conditional comments back to the html
element but leaving the empty conditional comment above the doctype also prevents IE8 from dropping into IE7 mode without needing the X-UA-Compatible
header being set on the server-side.
Ex 2 : http://pastie.org/1926635
Made this : http://pastie.org/1926658
Seems to trigger IE8 standards in both IE8 and IE8 Compat.
@zachleat You may well be right about the confusion. Would be great if you got involved in this issue, if you have time. Thanks
@zachleat @necolas in my code, I use document.documentMode to show the mode. Si I guess with this code there will be no confusion :)
This seems to get rid of the button, maintaining Standards mode in both IE8 and IE9. https://gist.github.com/980895
You might also think that since we have a comment above the doctype, it might trigger quirks mode, but I tested it in IE7 too and it maintains Standards mode. IE must pre-process the conditional comments out prior to rendering, avoiding that bug somehow.
Please confirm, but take care to remove of any existing Compatibility View settings in your browser for intranet sites (Tools -> Compat View) or .htaccess rules that might interfere.
@zachleat That was what I found in the "Ex 2" pastie as well. Glad you can confirm it.
@necolas Ah, apparently I'm horrible at reading. Sorry about that.
so an empty CC before the doctype eh
cool hack.. what do you guys think? put into the BP? or document.. this one seems like a tough call..
Is this safe to use? Does this work in feature phones browsers? Not that It would be a real problem, but it's best to know what kind of problem, if any, this could raise before inclusion.
Being the person who raised this issue, I obviously hate the compatibility view (aka, break your website) button a lot. However, I am also on the fence with this.
I honestly don't care about standards; I care about what makes my websites work. This part of me says put the hack in because it works.
The other part of me says don't put the hack in because boilerplate code isn't supposed to be bloated. If the average person is just going to delete the hack and opt for sending this via HTTP header then it shouldn't be in the code by default. It should just be documented.
So I guess my only question is, how many people will need/use this?
@DingoEatingFuzz and others who have reporting this issue : please can you test to confirm if this alternative code avoids the issue too. It should do because the conditional comments appear after the X-UA meta tag and the opening html
tag will be replaced by those that are included in head
.
Another bonus is that you can stick all html
attributes you want (lang
and facebook xmlns
stuff) on the html
tag that is not within the conditional comments...the extra class in the conditional comment is then added to the first html
tag. DRYer :)
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!--[if lt IE 7]><html class="no-js ie6"><![endif]-->
<!--[if IE 7]><html class="no-js ie7"><![endif]-->
<!--[if IE 8]><html class="no-js ie8"><![endif]-->
<!--[if gt IE 8]><!--><html class="no-js"><!--<![endif]-->
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
</body>
</html>
vs
<!--[if IE]><![endif]-->
<!doctype html>
<html lang="en">
<!--[if lt IE 7]><html class="no-js ie6"><![endif]-->
<!--[if IE 7]><html class="no-js ie7"><![endif]-->
<!--[if IE 8]><html class="no-js ie8"><![endif]-->
<!--[if gt IE 8]><!--><html class="no-js"><!--<![endif]-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
</body>
</html>
@DingoEatingFuzz I think that the people who needs this code most are probably the ones with less advanced html skils and possibly less able to configure apache (or other httpd).
I vote for inclusion with inline comment about it's removal.
Why? Removing is easier then inserting it and forgetting or not caring to remove it is (probably) less harmful then forgetting or not caring to insert it.
(and I'm still wishing for some kind soul with many phones available to test this on older phones)
I've done a write up of @julienw's technique and the one I posted above http://nicolasgallagher.com/better-conditional-classnames-for-hack-free-css/
What do people think of these techniques?
I think we have to understand what IE does.
My view is that it does some heuristics with the beginning of a file. We already know this for determining the content-type of a file, either with the first bytes or with the meta charset. But maybe he does this too for "preloading" the conditional comments engine (that could be why conditional comments around don't trigger the 100ms penalty), or for finding the document mode.
Someone has to do some more systematic tests, and it won't be me as I'll soon have no access to computer. :-)
Nice writeup.
To me, it seems like the best solution here is docs on setting this in your server config. Similar to the favicon stuff.. Set it back there and clean up the markup.
@necolas I haven't tested it, but I think your double-<html>
-tag idea should be written like so:
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!--[if lt IE 7]><html class="no-js ie6"><![endif]-->
<!--[if IE 7]><html class="no-js ie7"><![endif]-->
<!--[if IE 8]><html class="no-js ie8"><![endif]-->
<!--[if gt IE 8]><html class="no-js"><![endif]-->
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
</body>
</html>
The difference is in the final conditional comment. Non-IE browsers will use the very first <html>
tag and so don't need the extra one that shows up in the "gt IE 8" line. A further simplification is therefore possible:
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!--[if lt IE 7]><html class="no-js ie6"><![endif]-->
<!--[if IE 7]><html class="no-js ie7"><![endif]-->
<!--[if IE 8]><html class="no-js ie8"><![endif]-->
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
</body>
</html>
In this example, IE9 and up will use the original <html>
tag just like non-IE browsers.
Finally, using the method in your most recent check-in on index.html
, you could just write:
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!--[if lt IE 9]><html class="no-js oldie" lang="en"><![endif]-->
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
</body>
</html>
... and only old versions of IE would get the extra <html>
tag. All other browsers (and validators) would see only the first.
@guitarzan That won't work because the IE-specific classes won't bubble up to the first <html>
tag. You can't have a class on the uncommented tag for this to work.
I see (I think). So this would work:
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!--[if lt IE 9]><html class="oldie"><![endif]-->
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
</body>
</html>
... if you don't need the "no-js" class?
Even though the doctype is HTML5 recommended and the X-UA-Compatible meta tag is present, by putting the HTML tag in a series of IE conditional comments, IE refuses to believe that the website is indeed "modern" and puts the dreaded "Compatibility View" button in the address bar.
The way I get around this is by using JavaScript to add the ie6/7/whatever classes.
Example:
I'm sure there are better ways to handle this, but this works as expected.