/
cc-plus.html
executable file
·434 lines (313 loc) · 17.1 KB
/
cc-plus.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Targeting IE Using Conditional Comments</title>
<meta http-equiv="content-Type" content="text/html; charset=iso-8859-1" />
<meta name="mssmarttagspreventparsing" content="true" />
<meta name="description" content="A discussion of the theory of CSS floating." />
<meta name="distribution" content="global" />
<meta name="resource-type" content="document" />
<meta name="robots" content="all" />
<meta http-equiv="imagetoolbar" content="no" />
<link rel="SHORTCUT ICON" href="favicon.ico" />
<script type="text/javascript">if (window.self != window.top) window.top.location = window.self.location; </script>
<link rel="stylesheet" type="text/css" href="articles.css" />
<style type="text/css">
/* style rules for the article */
code em {color : #00d; font-style : normal;}
code .ie6only {color : #090;}
code em.ie5-5only {color : purple;}
code em.ie5-01only {color : red;}
code {white-space: pre;}
/*** Rules for the new CC method ***/
#IE,
#notIE {
background : #FFB700;
padding : 10px;
text-align: center;
margin: 10px;
font-size: 1.3em;
font-weight: bold;
color: #999999;
width : 30%;
float: left;
}
#IE { /* IE indicator box is dimmed-out for most browsers */
background: #af8700;
color: #997711;
}
#notIE { /* Non-IE indicator box is brightened as the default */
background: #ffcc66;
border: 1px solid #000000;
color: #000000;
}
/* The following rules are obeyed only by IE/Win browsers. These rules
will override the earlier rules and apply different styles for IE */
#IEroot #IE { /* IE brightens the IE indicator box */
background: #ffcc66;
border: 1px solid #000000;
color: #000000;
}
#IEroot #notIE { /* IE dims-out the non-IE indicator box */
background: #af8700;
border: none;
color: #997711;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="/scripts/init.js"></script>
</head>
<body>
<!--[if IE]><div id="IEroot"><![endif]-->
<h1>#IEroot — Targeting IE Using Conditional Comments and Just One Stylesheet</h1>
<div class="wrapper">
<p class="alignright">
<a href="../index-2.html"><strong>Return to p.i.e.</strong></a><br />
<a href="../articles.html"><strong>Return to Articles</strong></a>
</p>
<p style="text-align: right; font-style: italic;">
A Guest Article by <strong><a href="http://www.brainstormbrand.com/about/key_personnel/chalfant.html" title="Hiroki Chalfant's Page">Hiroki Chalfant</a></strong>
</p>
<div id="mastercontainer">
<p>The <a href="../poll/star-html.html" title="Wither the Star-HTML Hack?"><strong>Star-HTML hack</strong></a>
was a very elegant way to easily target style rules at IE and apply fixes.
<strong>Internet Explorer 7</strong> has
<a href="ie7-dehacker.html" title="CSS Hacks and IE 7">fixed the Star-HTML hack</a>,
taking away the elegance. This article introduces a simple method for targeting
CSS rules at IE that uses only <u>one</u> stylesheet and works for all versions
of IE. It will require some minimal markup using Internet Explorer's
<a href="http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp" title="Conditional Comment reference on MSDN">conditional comments</a>
and CSS <a href="http://www.w3.org/TR/REC-CSS2/selector.html#descendant-selectors" title="W3C's description of descendant selectors">descendant selectors</a>.</p>
<p>Here is a quick example. The css-controlled boxes below have detected whether your browser is IE/Win or not, using only conditional comments and a single CSS
file. That file uses only clean rules with no strange complications in the selectors:</p>
<div style="margin: 0 0 0 20%;">
<p id="IE">This browser is<br /> IE/Win</p>
<p id="notIE">This browser is<br /> not IE/Win</p>
</div>
<h3 style="clear: both; padding-top: 1.6em;">#IEroot: The New Star</h3>
<p>
A wrapper may be made to enclose the content of a page, and then you can write
descendant CSS rules that mention that wrapper's ID or class name in the selector.
But what if <em>only IE</em> thought that wrapper existed? Then those rules would only work for IE,
<em>while other browsers would ignore the rules completely</em>.
</p>
<p>
This is more or less how it was with the Star-HTML hack, where a mysterious
wrapper seemed to be surrounding the HTML element in IE browsers. This made
possible a very clean and easy selector construction: <strong>* html #myelement {}</strong>.
Now this trick is different because IE7 has lost the mystery wrapper and will not
read that selector as IE6 does. What we need is a way to make a new wrapper
to use that only IE can see. But how can this be done?
It so happens that you can use Conditional Comments
to make IE think there is a wrapper between the body and the entire page contents.
IE's view of the page element hierarchy will become different from all non-IE browsers,
letting us write CSS to take advantage of the difference. The code is not very difficult, but the
syntax is a bit different and must be correct for the method to work.
</p>
<p class="tip">
<a href="http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp" title="Conditional Comment reference on MSDN">Conditional Comments</a>
behave just like simple HTML comments, but they have a specific syntax that IE/Win
browsers can recognize. When that syntax is exactly correct, IE/Win browsers
will look inside the comment and parse whatever is inside.
</p>
<p>The starting tag for the new wrapper will go directly after the body start tag,
and the wrapper's end tag is placed directly preceding the body's end tag.
Each of these div tags will be wrapped in a conditional comment, allowing only
IE/Win browsers to parse those div tags.</p>
<code><!DOCTYPE your favorite doc type>
<html>
<head>...</head>
<body>
<!--[if IE]>
<em><div id="IEroot"></em>
<![endif]-->
<p id="IE">This browser is IE.</p>
<p id="notIE">This browser is not IE.</p>
<!--[if IE]>
<em></div></em>
<![endif]-->
</body>
</html>
</code>
<p>The first block of code after the body tag has a starting div tag with an ID
of <strong>#IEroot</strong> inside a conditional comment; remember,
<em>only</em> IE sees this div.</p>
<p>The last block of code before the closing body tag is a closing div tag
inside another conditional comment; this closing div tag will
match the starting div tag in the first block of code. Again, only IE will see
this closing tag.</p>
<p>Between the opening and closing of the #IEroot div is where all of the normal
page markup will go. In this example it is just a box with some content, but the idea
is for the #IEroot div to be the ancestor of all page content.</p>
<p>Using CSS, style the page as usual for non-IE browsers. Then in the same stylesheet,
use <strong>#IEroot</strong> as a prefix in descendant selectors to target specific rules at IE. The
example below styles the div called #anyelement to have a red border in non-IE browsers, and a blue border in IE.</p>
<code> /* all browsers make border red */
#anyelement {
border : 2px solid red;
}
/* all browsers see this, but only IE thinks #IEroot exists
as an element and makes border blue */
<em>#IEroot</em> #anyelement {
border-color : blue;
}
</code>
<p>The first rule is a simple rule to apply a red border to #anyelement; this rule is seen by all browsers, even IE.</p>
<p>The second rule changes the color of #anyelement's border to blue, but the selector is a little different than the first rule.
The second rule's selector is a descendant selector; it's interpreted as: the element with the ID of "anyelement" that is a descendant
of the element with the ID of "IEroot" should have the following rules applied.</p>
<p>Since #IEroot was created using conditional comments
and only IE can see the contents of conditional comments, then in IE, #anyelement is a descendant of #IEroot and the descendant selector
matches. Therefore, this rule will apply to IE, making the border of #anyelement blue for all IE browsers, versions 5 through 7. And
because #IEroot is the first div and wraps the entire page, it can be used throughout the stylesheet to target rules at IE. This is used
just like the star-HTML hack was used, except that you cannot target the body tag with this method because the body element is not and cannot
be a descendant of #IEroot.</p>
<p>Here is a <a href="sidepages/example.html" title="Example of IEroot">live demo page</a>. Be sure to view in both IE and non-IE browsers.</p>
<p>Using this technique you can target part of a stylesheet at IE with confidence that this method won't
be affected by future browser releases.</p>
<h3>The Anti-IEroot Rule</h3>
<p>
Normally the CSS code will be clean, and the #IEroot rules will simply override key rules in the main styles
to make IE behave correctly. Some coders will want the option to write a rule that all non-IE browsers will
read, but that IE will not. A Child combinator can be used in a certain way:
</p>
<code>body>#wrapper #anyelement {
styles for non-IE only...
}
</code>
<p>
Just add a prefix to any selector for a page element (#anyelement) with <strong>body>#wrapper</strong>.
Of course, you will need to have a #wrapper element in the page, or some other major element that is a direct
child of the body. The clean HTML should have #wrapper directly inside the body element so that the selector above
will work.
</p>
<p class="tip">
The Child combinator (>) selects the element on the right only if it is a direct child of
the element on the left.
</p>
<h4>Hiding From IE</h4>
<p>
IE6 and below won't read the rule, for the simple reason that those browsers don't support the child selector itself.
IE7 <em>does</em> support it, but IE7 also happens to think there is an element called #IEroot! For IE7, a selector like
<strong>body>#IEroot>#wrapper</strong> would work, but the selector we described above does not include #IEroot.
IE7 thinks #IEroot is in the HTML, so IE7 ignores the rule. Thus all IE/Win versions are blocked from seeing this
type of selector.
</p>
<h3>More on Conditional Comments</h3>
<p>Conditional comments allow special syntax constructions for checking the IE version and are proprietary to Internet Explorer for Windows.
A conditional comment is an HTML element that, in IE may conditionally be read, but, to all other browsers looks like an HTML comment and is ignored.
Here is an example of some markup with conditional comments:</p>
<code><em><!--[if IE]></em>
<p>Only IE shows this paragraph.</p>
<em><![endif]--></em>
<p>A paragraph that all browsers display</p>
</code>
<p>In the above example, the first block of code has a paragraph of text inside a
conditional comment. Internet Explorer has been designed to examine all HTML comments for
certain syntaxes, and when it finds such syntax IE will simply read and parse whatever is inside
the conditional comment. Because conditional comments are hidden inside syntactically
correct HTML comments, all other browsers just see a comment and do not display the paragraph
contained within it.</p>
<p>The next paragraph is outside the conditional comment and displays normally.</p>
<p>If you want to test your conditional comments in different versions of IE, one simple method is to have multiple versions of IE installed
as standalones. But there is a problem with standalones: they don't support conditional comments correctly.
<a href="multiIE.html" title="Taming Your Multiple IE Standalones">This article</a> will help you fix conditional comments
and many other things in your standalone IE's.</p>
<p>If you haven't installed multiple IE's yet, go
<a href="http://tredosoft.com/Multiple_IE">here</a> to download a fast, easy, and complete multiple IE installer
with all the tweaks done for you.</p>
<h3>Deeper with Version Numbers</h3>
<p>Conditional comments support targeting of specific browser versions, which means divs can
be created that will be used in CSS selectors to target not just IE in general, but <em>specific</em> versions of IE.
Here is an example of how this might be done:</p>
<code><em><!--[if gte IE 7]></em>
<div id="ie7andup">
<![endif]-->
<em class="ie6only"><!--[if IE 6]></em>
<div id="ie6only">
<![endif]-->
<em class="ie5-5only"><!--[if IE 5.5000]></em>
<div id="ie5-5only">
<![endif]-->
<em class="ie5-01only"><!--[if lt IE 5.5000]></em>
<div id="ie5-01only">
<![endif]-->
<div id="anyelement">a box with some content</div>
[... more page content ...]
<!--[if IE]>
</div>
<![endif]-->
</code>
<p>Only one of the four conditional divs will be created in IE, depending on the version of the
viewing browser, and none of them will be created in other browsers. Note that only one generic
all-IE div end tag is required, so no need to have multiple CC's for this task.</p>
<p>The first div, <strong>#ie7andup</strong>, will be created in IE version 7 and up. The "gte" means "Greater Than or Equal to."</p>
<p>The second div, <strong>#ie6only</strong>, will be created in IE version 6 alone.</p>
<p>The third div, <strong>#ie5-5only</strong>, will be created in IE version 5.5. </p>
<p>The fourth div, <strong>#ie5-01only</strong>, will be created in IE version 5.01. The "lt" means "Less Than." IE4 is not included,
since conditional comments were not introduced into IE until version 5.</p>
<p class="tip">
When targeting IE5.5 you must add the zeros to the 5.5 or the browser may ignore the
conditional comment. <strong><!--[if lt IE 5.5]></strong> is not good enough,
it must be <strong><!--[if lt IE 5.5000]></strong>. There is no good reason for this,
that's just how it works.
<strong>gte IE 7</strong> stands for "greater than or equal to IE7,"
while <strong>lt IE 5.5000</strong> stands for "less than IE5.5." When writing these CC's, exact
conformance to the syntax is required. Any error will cause the CC to become a normal HTML comment.
</p>
<p>The corresponding CSS looks like this:</p>
<code> <span class="spanbox">/*** All browsers ***/</span>
#anyelement {
border : 2px solid black;
}
<span class="spanbox">/*** For IE 7 and up ***/</span>
<em>#ie7andup</em> #anyelement {
border-color : blue;
}
<span class="spanbox">/*** For IE 6 ***/</span>
<em class="ie6only">#ie6only</em> #anyelement {
border-color : green;
}
<span class="spanbox">/*** For IE 5.5 ***/</span>
<em class="ie5-5only">#ie5-5only</em> #anyelement {
border-color : purple;
}
<span class="spanbox">/*** For IE 5.01 ***/</span>
<em class="ie5-01only">#ie5-01only</em> #anyelement {
border-color : red;
}
</code>
<p>See a <a href="sidepages/example2.html" title="Demo of muli-version variation">live demo</a> of the method. You will need multiple versions of IE to view all the variants.</p>
<p>Not only is IE styled differently, but different versions of IE are styled differently. For example, this method makes it easy to fix the
<a href="http://www.communitymx.com/content/article.cfm?cid=E0989953B6F20B41" title="The Box Model Problem">box model problem</a>
in IE 5.x
while not affecting IE 6 or 7. Each new #IEroot ID is customized to indicate what IE versions are targeted,
in effect "labeling" each special IE rule by version number. This helps when later doing site maintenance,
and team environments benefit as well from the reduced potiential for confusion.</p>
<p style="margin-top: 2em; margin-bottom: 6em;">
This Guest Article is authored by <strong><a href="http://www.brainstormbrand.com/about/key_personnel/chalfant.html" title="Hiroki Chalfant's Page">Hiroki Chalfant</a></strong>
</p>
<p class="small alignright">
<a href="../design/index.html"
title=" Big John's Advanced CSS Design "><strong>Big John Design</strong></a>
<a href="https://github.com/DerOperator/PositionIsEverything/issues">Contact Us</a>
©positioniseverything.net<br />
Last updated: Febuary 2, 2007<br />
Created Febuary 2, 2007
</p>
<!--[if IE]></div><![endif]-->
</div>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-39235363-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>