While reading the CSS code of Twitter bootstrap, I noticed that some elements have a CSS rules with a * at the beginning. For example:
.row-fluid {
width: 100%;
*zoom: 1;
}
Why is this technique being used?
Ignore posts about * being an "everything" selector, as it is, but that isn't what it is in this case.
Putting * before an attribute allows you to target ie7 and below. This is an old hack that shouldn't really be used as you can target ie7 and below in better ways.
Quick explanation of how to target older IE versions. If you read to the bottom you will see he explains that it is better to use conditional comments than hacks, as they are after all, hacks.
The asterisk is a hack for IE6 and IE7.
see: http://paulirish.com/2009/browser-specific-css-hacks/
In this case, I think is a hack for ie6/7
Related
My skin has the following CSS:
dl.definition dd:last-child {
margin-bottom: 0;
}
/* IE class */
dl.definition dd.last-child {
margin-bottom: 0;
}
Is it possible to combine these into one even though the second is just for IE ?
Thanks everyone for the answers but I am not sure anyone really said if I could just do this:
dl.definition dd:last-child,
dl.definition dd.last-child {
margin-bottom: 0;
}
Your hoped-for solution won't work:
dl.definition dd:last-child,
dl.definition dd.last-child {
margin-bottom: 0;
}
The reason this won't work is because as far as old versions of IE are concerned, dd:last-child is an invalid selector, and thus it will throw away the whole block. It doesn't matter that it also contains a valid selector; the whole thing is thrown away because of the invalid one.
A few options on how to improve things, and save yourself the hassle of duplicated code all over the place...
Upgrde IE. There are javascript libraries available such as Selectivizr or ie7.js/ie8.js/ie9.js which patch IE to make it support more CSS selectors. :last-child is included in pretty much all these libraries.
Downgrade your CSS. You're already writing the .last-child class into your code to support old IE versions, so just use that for everything and forget about using the :last-child selector. Then you only need one selector for all browsers.
Graceful degradation. Drop the IE-specific code, and just allow Old IE users to see a slightly broken page. As long as it doesn't affect usability, it may not be a big deal. You may not have that many old IE users (and the numbers will continue to fall), and those people who are still using old IE are used to seeing sites that are slightly broken (or worse) these days.
Re-arrange your layout to use :first-child instead of :last-child. :first-child has much better support (it goes back to IE7, though there are bugs with it in old IEs).
Use a CSS compiler like SASS or Less, so you can write your CSS in a more logical and structured form, before converting it to real CSS code when you deploy it to the site.
Hopefully one of those solutions will work for you. My suggestion would be the Selectivizr library, but any of the above should provide a workable solution for you.
In the HTML add
<!--[if IE]>
<style>
dl.definition dd.last-child {
margin-bottom: 0;
}
</style>
<![endif]-->
Not an exact answer to your question but a workaround for IE6 & IE7 can be found here which tells that you can use properties in single css file.
This gives again a more sophisticated solution.
And again you can use multiple properties in single css file and browsers will ignore it if it does not understand it. Cheers to growing smartness of browsers. :-)
Conditional comments for IE. You can specify verion of IE, for that you want to select CSS
Just stumbled upon this in a borrowed css file - something I've never noticed before, and punctuation in context is inherently hard to google:
.ez-radio { zoom: 1; *display:inline; _height:15px; }
What's the '*' prefix do?
And for the matter the underscore in _height?
Is this some new CSS3 trickery?
It's used for CSS hacks in Internet Explorer.
* is IE 6 - 7 only (thank you, mck89!)
_ is IE 6 and below.
Don't use them. If you need browser specific CSS definitions, use specialized CSS definitions instead.
Those symbols are used to target IE lower version browsers called it CSS HACKS.
FF, Chrome or Safari always ignored those strings in CSS class.
dont want to duplicate Zanathel's answer, but its important to mention:
please do not use them in your stylesheet, keep it hack-free
when you need to use hacks, dont use hacks, use conditional comments, and place your ie specific css in these files
Does anyone know why the following CSS code is not working on IE8, and yet it's working on EVERY OTHER browser?
table.wrap tr:first-child td, table.wrap tr:last-child td { height:20px; }
table.wrap td:first-child, table.wrap td:last-child { width: 20px; }
I understand that IE8 does not support CSS3 features. But I don't think I'm using CSS3 here.
I sincerely appreciate your help.
Thank you so much!
See Quirksmode.org for a full compatibility chart of all CSS features across all the various browsers.
As you'll see from the link above, IE8 does not support the last-child feature.
It does support first-child, but since you've put them together in the same selector, it will throw the whole thing away because it doesn't recognise the last-child part.
Also note note that Quirksmode first-child as being buggy in IE8, so even though it is supported, you may want to be careful about using it.
To solve the problem, you might want to try an IE hack to get it to support extra CSS features.
One that looks quite good is Selectivizr. You might also want to look into Dean Edwards' ie7.js / ie8.js / ie9.js. Both of these aim to patch missing features into older versions of IE. They're not perfect, but they may resolve the problem for you.
Hope that helps.
IE isn't compatible: http://reference.sitepoint.com/css/pseudoclass-lastchild
I believe last-child is a part of css3 and not supported by IE8.
Which is the CSS hack you use most often and which one do you avoid using?
I am asking this question so that I can understand different views of different people about CSS hacks and also understand which hacks are good and which ones are not.
Not technically a hack, but I often include conditional comments to target IE 7-:
<!--[if lte IE 7]>
<link href="ie7.css" />
<![endif]-->
I actually get away without using many hacks.
Most used - clear fix
Most hated - !important rules because they are an indication that the stylesheet is probably not organized properly. It also means that some styles are too general that they ought to be. Not good for performance either.
I mostly use min-height hack and avoid using underscore trick something like _margin that targets IE6.
I've found that if I use the XHTML 1.0 strict doctype, mostly things just work... That said, I don't really do anything fancy... But a nice minimalistic site like SO would be pretty easy to design sans hacks...
PNG transparency in IE6 with AlphaImageLoader()...
IE versions >6 and Firefox and Chrome all support full 8-bit transparent PNGs, but for IE6 compatibility you have to do the above css hack. Your CSS file will no longer validate but if you rely on transparent PNGs like I do... it's worth it.
Most Used: Negative Margins
Seems this is the one I have to use most often: create a CSS class
.inline-block { display: inline-block; }
use it to style any element you wish to display as inline-block (instead of using display: inline-block; directly). Then, in your IE-only (v.7 or earlier?) file:
.inline-block
{
zoom: 1;
*display: inline;
}
Sad panda.
Is there a list of 'good' clean CSS hacks, which are certain to be future-proof?
For example, zoom:1 is safe, as long as it's only served to IE, and you remember it's there. The very common hack of using child selectors is not safe because IE7 supports them. Using height:1% just feels dirty (but that might just be me).
I know of ie7-js, so IE6 bugs don't worry me much. Also, I'm not looking for a religious debate, just sources.
Thanks for the replies - I've selected the one with best sources as answer.
Thanks also for the suggestions to use separate CSS files, or not to worry about it. I entirely agree with you, and for me, those are givens. But when faced with a layout problem, I want a safe fix that will minimise the risk that I'll have to revisit the problem in $IE or $FF + 1. Sorry I didn't make that clearer.
For the majority of IE bugs I think you're best off using conditional comments around a link to a browser specific stylesheet. It tends to keep things pretty neat and it's quite self documenting.
This is a good place for well-documented and well-tested browser bugs and the hacks allow you to work around them:
http://www.positioniseverything.net/
I've used Peter-Paul Koch's "QuirksMode" website a lot for issues involving CSS and cross-browser compatibility. He tends to frown on browser-specific methods, but he does have a page on CSS Hacks.
Nicole Sullivan (AKA Stubbornella) who works for the Yahoo Performance team suggested in The 7 Habits for Exceptional Perf that you should use the CSS underscore hack to patch up IE6 bugs because:
Hacks should be few and far between.
If you will only have 5-6 hacks (which is already plenty) then it would not make sense placing those in an external file and thereby separating it from its context.
An extra file would lead to performance penalties (Yahoo Best Practices, Rule 1).
It should however be noted that this is not valid CSS.
There's no such thing as a good clean/acceptable [css] hack - always code to Standards, and then use browser+version specific stylesheets for any hacks required to make things work.
For example:
default.css
default.ie6-fix.css
default.ie7-fix.css
default.ff2-fix.css
etc
Then, when new version of a browser are released, copy the previous version's hacks and remove the bits that no longer apply (and add new bits, if necessary).
(Load individual stylesheets using Conditional Comments for IE, and user-agent sniffing for other browsers.)
Underscore-hack for IE6-stuff works quite well, eg.
min-height:50px;
_height:50px;
It doesn't require moving things out of context into new css-files, only IE6 gets them and they're easy to filter out if you should decide to stop supporting IE6. They're also very minimal and won't clutter your CSS that much.
Modifying your CSS for browser-specific support is never wrong - as long as you can easily contain it. As you'll notice, standards-compliant browsers, * cough * everything except MSIE, will never break with future releases. New W3C standards also don't break previous standards, they usually deprecate or extend previous standards at the most.
People have mentioned conditional comments which are great for handling IE. But you'll need a bit more for handling all browsers (mobile, gecko, webkit, opera, etc.). Usually you'll parse the incoming request headers to fetch the browser type and version from the User-Agent param. Based on that you can begin loading your CSS files.
I belive the way most of us do it is by:
First developing for one standards-compliant browser (let's take FF for example)
Once the CSS is complete you approach providig support for IE (this can be easily done with the conditional comments, as perviously mentioned)
First create a CSS file that will fine tune everything for IE6 and any other version below
Then create a CSS file that will handle everything for IE7
Lastly, create a CSS file that will handle everything for IE versions of IE8 and greater
Once IE9 comes out, make sure you set IE8+ handling to IE8 specific, and create a IE9+ CSS file with required fixes
Finally, create an additional CSS file for webkit fixes
If required, you can also create additional files to specifically target Chrome or Safari if required
Concerning browser specific CSS implementations, I usually group all of those in my main css file (you can easily do a search for those and replace them in one document if needed). So if something has to be transparent, I'd set both opacity and filters (MSIE) in the same block. Browsers just ignore implementations they don't support, so your safe. Specific implementations I'd tend to avoid are custom implementations (hey, I like the -moz box above the W3C one, but I just don't want to rely on it).
As it goes with CSS inheritance and overriding, you don't have to redefine all the CSS declarations and definitions in every CSS file. Each consecutively loaded CSS file should only contain the selector and specific definitions required for the fix, and nothing else.
What you end up with in the end is your (huge) main css file and others, containing a few lines each, for specific browser fixes - which sums up to something that's not that very hard to maintain and keep track of. It's a personal preference what browser your base css file will be based off, but usually you'll be targeting a browser that will create the least amount of issues for other browsers (so yes, developing for IE6 would be a very poor decision at that point).
As always, following good practices and being pragmatic and meticulous with selectors and specifics about each class and using frameworks will lead you down the path of goodness with seldom fixes required. Structuring your CSS files is a huge plus unless you want to end up with an unordered meaningless mess.
Centricle has a good list of CSS hacks and their compatibilities.
I don't think you'll find a list of hacks that will be future proof, as know one can tell what stupid thing will be implemented in IE next.
This article is a good summary of CSS hacks: http://www.webdevout.net/css-hacks
Here's a good list of filters that are very stable:
/* Opera */
.dude:read-only { color: green; }
/* IE6/IE7 */
#media,
{
.dude { color: silver;}
}
/* IE8 \0 */
#media all\0
{
.dude { color: brown; }
}
/* IE9 monochrome and \9 */
#media all and (monochrome: 0)
{
.dude { color: pink\9; }
}
/* Webkit */
* > /**/ .dude, x:-webkit-any-link { color:red; }
/*
* > /**/
/* hides from IE7; remove if unneeded */
/* Firefox */
#-moz-document url-prefix()
{
.dude { color: green; }
}
When defining rules, I find it good to allow natural degradation take place, for instance, in CSS3 there is support for RGBA Colour models, but there isn't in CSS2, so I find myself doing:
background-color: #FF0000;
background-color: rgba( 255,0,0, 50% );
So that when the later rule fails on older browsers which don't support it, it will degrade to the previously defined style.
I prefer the global conditional comment technique described by Hiroki Chalfant;
I find it helpful to keep my IE-targeted rules side-by-side with my standards-targeted rules in a single valid stylesheet.