Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The <!--[if gt IE 8]><!--> is unecessary #1437

Closed
komputist opened this issue Sep 24, 2013 · 23 comments
Closed

The <!--[if gt IE 8]><!--> is unecessary #1437

komputist opened this issue Sep 24, 2013 · 23 comments

Comments

@komputist
Copy link

The Hello World page of H5bp begins like so:

 <!DOCTYPE html>
 <!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7"><![endif]-->
 <!--[if IE 7]><html class="no-js lt-ie9 lt-ie8"><![endif]-->
 <!--[if IE 8]><html class="no-js lt-ie9"><![endif]-->
 <!--[if gt IE 8]><!--><html class="no-js"><!--<![endif]-->

But what use is the for the conditional comment on that last line? The HTML parser will use the first start tag that it sees and disappare any other identical start tag that it might see.

The h5bp shoudl take advantage of how the HTML paraser actually works and delete the conditional comments on the last line - so that we get this:

 <!DOCTYPE html>
 <!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7"><![endif]-->
 <!--[if IE 7]><html class="no-js lt-ie9 lt-ie8"><![endif]-->
 <!--[if IE 8]><html class="no-js lt-ie9"><![endif]-->
 <html class="no-js">
@necolas
Copy link
Member

necolas commented Sep 24, 2013

That would result in 2 opening html tags in IE 6-8.

@necolas necolas closed this as completed Sep 24, 2013
@komputist
Copy link
Author

@necolas

Below I paste a screenshot from the IE8’s DOM inspector parsing the H5BP Hellow World page, with the change that I proposed. As you can see, the result (in the DOM) is just a single HTML start tag.

skjermbilde 2013-09-24 kl 02 55 34

@necolas
Copy link
Member

necolas commented Sep 24, 2013

Re: this https://twitter.com/komputist/status/382308854731509760. Yeah, I know how the parser works, thanks (http://nicolasgallagher.com/better-conditional-classnames-for-hack-free-css/).

We're getting rid of the conditional comments in the next release anyway.

@roblarsen
Copy link
Member

I didn't realize there was going to be a test.

@komputist
Copy link
Author

@necolas

Regarding, "removing anyway": Yes, my bug report is about what happens before that removal.

Regarding the bubbling up effect that you describe in that article, cool, then I can set e.g. the language attribute on the uncommented element, and get it to bubble up to the conditionally commented start tags:

<!DOCTYPE HTML>
<!--[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]-->
<html class="no-js" lang="en" >

Meanwhile, feel free to treat my input as an answer to the final words of that article:

If you find any other approaches, or problems with thoseposted here,
please leave a comment but also consider adding what you’ve found
to the relevant issues in the HTML5 Boilerplate GitHub repository.

@TheDutchCoder
Copy link

@komputist as @necolas already pointed out: that will result in two opening html tags in IE6-8.
You might not see it in IE's inspector, but they are there. Simply run your output through a validator and you'll see an error. (like: "Line 3, Column 31: Stray start tag html.").

@komputist
Copy link
Author

Well, @TheDutchCoder

  • The HTML5 validators that I am aware of will not see any error because they treat conditional comments as comments - unlike legacy IE, they do not read inside them, so I can safely say that you are wrong there.
  • I don't know what is actually happening in the “brain” of IE, but I choose to trust the DOM inspector. If there has ever been a problem due to two opening tags in IE6-8, then - of course - the issue should be considered. But as I see it, we are just prepping an outdated browser, and hence, I think, that we must allow ourselves to play some tricks with it. After all, the very conditional comments thingy is such a trick.

@roblarsen
Copy link
Member

I just tested it out quickly and at least in IE10 running in IE8 mode the behavior is as expected

With this markup:

<!DOCTYPE html>
<!--[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]-->
<html class="no-js" lang="en" >

Running

>> console.log(document.getElementsByTagName("html")[0].className) 
 no-js ie8 
>> console.log(document.getElementsByTagName("html").length) 
 1 
>> console.log(document.documentMode) 
 8 

which is as expected.

I'd be curious to try it in real IE8 to see if that behaves the same way.

Not that any of this matters, since we're dropping it anyway, but it's interesting to play around with. Yet another wrinkle in this godrosaken corner of web development. Too bad it came up now and not years ago when we were first crafting this. We could have saved BYTES.

@TheDutchCoder
Copy link

Real IE8 returns the same thing, browsers are smart enough (yes even older IE) to drop double tags. They also try to fix other mark-up errors, but that doesn't mean they should be put in the source ;-)

Just because something works, doesn't mean it's a good idea ;-)

And you're right, since they will be dropped, it's kind of a moot discussion.

@komputist
Copy link
Author

Don't be so ”aunty”. Conditional comments are a hack. That is the problem. If you accept CCs and admit that the entire legacy IE6-8 browsers are on their way to the dustbin of the Internet, then it is beyond me why you defend that we sent “clean” code to IE8. (But I realize that I probably ain't going to convince you.)

@TheDutchCoder
Copy link

No need to get insulting here.

Yes, CC's are a 'hack', but IE8 will still be here for a while, especially in the Government (hell, the Canadian Government just 'upgraded' to it for a lot of their departments).

There's a difference between using a hack which doesn't interfere with the actual HTML output, and those that do (like in this case).

As I said before, it doesn't matter if a browser ignores and/or fixes certain things, it can still be a bad practice.

Feel free to remove the CC's in your own projects, nobody is stopping you.

@komputist
Copy link
Author

Above @roblarsen proved that it does not interfere with “the actual HTML output”. I understand the argument that "we are anyway not going to use CC in H5BP anymore" (for whatever reason). I continue to not understand the other argments.

@roblarsen
Copy link
Member

Well, I didn't prove anything yet. I ran a quick test in IE10 using the f12 tools. I'll test with with webpagetest tonight to see how well it works falling back to ie6 and across different os/browser versions, etc. This being IE, I wouldn't be surprised if something weird shook out :)

While I think it's academic here (and thankfully at my job, since we're now IE9+-- yes, there's hope even in financial services) I think it's a nicer looking pattern and like the fact that it clearly separates the oldie stuff from the normal stuff. It also satisfies the dreamweaver bug which ended up making the pattern even uglier for a while. Also, fewer bytes.

If this were 2010 I'd be really intrigued by this. As it stands it might be a better way forward for anyone still using this.

@komputist
Copy link
Author

@roblarsen The ”bubbling” effect does apparently not “bubble” attributes that begins with the letters “xml” or which are prefixed. So for instance, if we have this:

<html>
<html xml:lang="" lang="" xmlfakery="" xmlns="" class="foo">

then the resultig DOM in IE6-9, is a s folllows:

<html lang="" class="foo">

In IE10 and all other browsers, then everything bubbles up. Depending on how one views it, this difference can be seen as a feature. E.g. it would mean that the selector

[xmlns] {color:lime}

would only have effect in “modern” browsers.

@komputist
Copy link
Author

@roblarsen You said:

If this were 2010 I'd be really intrigued by this.

@necolas in his article in May 2011 essentially had what I propose in his hands, but dismissed it for more or less puristic reasons:

While it’s interesting to explore these possibilities,
the “classic” method is still generally the cleanest.

@roblarsen, you also said:

As it stands it might be a better way forward for anyone still using this.

Indeed. Please note that I have only proposed this as an incremental improvement of the current version of H5BP. Thus, I realize that next version perhaps should not use conditional classnames the way H5BP is known for.

@roblarsen
Copy link
Member

I didn't read the article when it was originally released. I also don't like the pattern as presented in that article so I wouldn't have had the same reaction as I have to yours. Two separate blocks of HTML with one block following two meta elements is super weird looking and would require even more discussion and explanation than the current pattern. The way you've shown it is easier on both counts ("This stuff is for old ie, this stuff is for normal browsers")

@komputist
Copy link
Author

Thanks for your kind words! Since you are so positive, here is another variant:

<!--[if ie]><![endif]-->
<!DOCTYPE HTML>
<html lang="" xml:lang="" xmlns="http://www.w3.org/1999/xhtml" >
   <head>
<meta charset="utf-8"/>
<title>foo</title>
      <!--[if !ie]><!-->
     <script>
         <![CDATA[<![endif]-->
         </ie xmlns="right" />
         <meta http-equiv="X-UA-Compatible" content="IE=7"/>
         <![if lt IE 7]><html class="no-js lt-ie7"><![endif]>
         <![if    IE 7]><html class="no-js    ie7"><![endif]>
         <![if    IE 8]><html class="no-js    ie8"><![endif]>
         <![if    IE 9]><html class="no-js    ie9"><![endif]>
         <script>]]>
      </script>
… snip …

Explanation:

The above method com does the following:

  1. The first cond. com causes subsequent X-UA-Compatible to work.. (Well known issue.) Alternatively, if quirks mode in IE6 and IE7 is OK, the on can replace first cont-com with this fake cond.com: <!--[]-->
  2. The second cond.com makes legacy IE not see the start tag of the script element, whereas other browsers see it.
  3. Thus, when IE sees the EndIf statement, it actually reads inside the script element, and thus it detects 3 objects inside the script element:
    1. The </ie xmlns="right" /> is my own discovery - it has the same effect (with one exception) on unknown elements as has the HTML5 Shiv javascript. Namely, it makes legacy IE treat them as elements. The caveat is that you cannot use the element names for styling - you must add class names and style shose. (More could be said about this - but this is enough for now.)
    2. The X-UA-Compatible does what it needs to do.
    3. The Cond.coms do what they are expeted to do.
  4. The sectond <script> start tag is there fore IE so it does not get surprised when it sees the </script> end tage.
  5. The CDATA declaration is there simply for XHTML compatibility

Advantages:

  1. The legacy code is stuffed inside a script element
  2. It is HTML5 and XHTML5 valid, from top to toe.
  3. In my example, the html start tag inside the script element will “bubble up” to the “real” html start tage (like in my initial example in this bug.)
  4. The code can be made pretty short since, inside the script element, we are free to use <![if ie]> - we don't need to use <!--[if ie]>. Thus, we save 4 characters per cond.com.
  5. It is damn cool - coold that we target IE by hiding the script start tag.

@FagnerMartinsBrack
Copy link
Contributor

@komputist
It seems too verbose considering the given advantages like the useless XHTML support.

The legacy code is stuffed inside a script element

Which kind of advantage is that?

@komputist
Copy link
Author

@FagnerMartinsBrack

@komputist
It seems too verbose considering the given advantages like the
useless XHTML support.

The CDATA declaration prolongs the code by 12 characters.

The legacy code is stuffed inside a script element

Which kind of advantage is that?

While it is possible to not use the script element,

<!--[if ie]>
    </ie xmlns="right" />
    <meta http-equiv="X-UA-Compatible" content="IE=7">
    <![if lt IE 7]><html class="no-js lt-ie7"><![endif]>
    <![if    IE 7]><html class="no-js    ie7"><![endif]>
    <![if    IE 8]><html class="no-js    ie8"><![endif]>
<[endif]-->

the advantages of using the script element are:

  1. Conceptual: The script element is, per HTML5, an extension point. And thus, since hacks are a kind of extension of the standard markup, it makes sense to place inside script.
  2. Syntax coloring: A conditional comment is still a comment, and so its contents gets syntax colored as if it is a comment - which is suboptimal when the content is markup. The script element method has the advantage that syntax coloring works as you would expect.

Btw, for the record and for the fun, if you only want to target all legacy IE’s, then the scrip method allows you to drop the <![if ie]> statements inside the script element:

<!--[if !ie]><!--><script><![endif]-->
</ie xmlns="right" />
<meta http-equiv="X-UA-Compatible" content="IE=7"/>
</script>

Also, here is another variant, with only a single <!--[if foo]> statements.

<!--[if !ie]><!-->
<!DOCTYPE HTML>
<html lang="" xml:lang="" xmlns="http://www.w3.org/1999/xhtml" >
   <head>
<script><![endif]-->
<!DOCTYPE HTML>
<html class="ie" lang="" xml:lang="" xmlns="http://www.w3.org/1999/xhtml" >
<head></ie xmlns="right" />
<meta http-equiv="X-UA-Compatible" content="IE=7"/>
</script>

@FagnerMartinsBrack
Copy link
Contributor

The XHTML thing was just an example, in the end everything is pretty irrelevant for day to day use. Interesting research though, make me realize how happy I am not having to support oldIE 💃

@komputist
Copy link
Author

I don't find this method more verbose than the code that H5BP currently uses. But it is of course more verbose than not using conditional comments. Indeed the day is nearing when cond.coms are irrelevant. So I just had to “get this out” before that day! ;)

@komputist
Copy link
Author

@FagnerMartinsBrack

The legacy code is stuffed inside a script element

Which kind of advantage is that?

The advantage is that if we replace the script element (he, he) with a style element, we get to hide the ”X-UA-Compatible” element. Because, somehow IE10 still sees it, without any need for conditional comments. (Yeah, interesting that it treats style different form script). This also works to disable the compatibility button in IE10.

EXAMPLE:

<!DOCTYPE html>
<html>
    <head>
<meta charset="UTF-8"/>
<style>
    <meta http-equiv=X-UA-Compatible content=IE=edge>
</style>

Add a negative conditional comment to target IE9 and IE8 (howver, it does not remove the compatibility button in those browsers):

<!DOCTYPE html>
<html>
    <head>
<meta charset="UTF-8"/>
<!--[if !ie]>-->
<style><![endif]-->
       <meta http-equiv=X-UA-Compatible content=IE=edge>
</style>

To remove the compatibility button in IE8 and IE9 (I assume IE9 works like IE8 in this regard – I have not fully tested it – others probably have tested it already), one can add an empty conditional comment before the DOCTYPE:

<!--[if !IE]><![endif]-->
<!DOCTYPE html>
<html class="no-js">
    <head>
<meta charset="UTF-8"/>
<!--[if !ie]>-->
<style>
       <![endif]-->
       <meta http-equiv=X-UA-Compatible content=IE=7>
</style>

And also, for an HTML5 Shiv alike effect in IE8 (and in IE8 mode in IE9+), we can as well add a unknown element with a xmlns attribute on – and if we make it </foo xmlns="bar"/> instead of <foo xmlns="bar"/>, it will even disappear from the DOM – which I consider handy. This element can be added either inside the conditional comment on top of the page

<!--[if IE 8]></z xmlns="z"/><![endif]-->
<!DOCTYPE html>
<html class="no-js">
    <head>
<meta charset="UTF-8"/>
<!--[if !ie]>-->
<style>
       <![endif]-->
       <meta http-equiv=X-UA-Compatible content=IE=Edge>
</style>

Or inside the style element:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
    <!--[if !ie]>-->
    <style>
      <![endif]-->
      </z xmlns="z"/>
      <meta http-equiv=X-UA-Compatible content=IE=7>
    </style>

Which place choose? If one plans to run any other mode than Edge mode (in the examples above I picked IE7 mode, to make it easy to check if it works in both IE8, IE9 and IE10), then the </ xmlns="z"/> should stay inside the style element or one could place it on top of the page, and make sure the conditional comment targets more than simply IE8.

But since the boiler plate is focused on Edge mode, we can move it out of style, and inside the IE8 conditional comment on top of the page. This perhaps has the advantage that all IE8 related is collected in one place. And another advantage is that if you test your page in e.g. IE7 mode, the page is likely to break - and as such it provides for more realistic testing.

Finally: Yeah, you can place e.g. conditional comment inside the style element and let the conent ”bubble up”:

<!--[if IE 8]></z xmlns="z"/><![endif]-->
<!DOCTYPE html>
<html class="no-js">
    <head>
<meta charset="UTF-8"/>
<!--[if !ie]>-->
<style>
       <![endif]-->
       <![if ie 8]><html lang="en"><![endif]>
       <meta http-equiv=X-UA-Compatible content=IE=Edge>
</style>

All in all, this (that is: the use of style ellement shows that it is possible target IE8, IE9 and IE10 without resorting to a HTTP header and without creating non-conforming code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants
@necolas @roblarsen @komputist @FagnerMartinsBrack @TheDutchCoder and others