Acceptable CSS hacks/fixes - css

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.

Related

The least expensive method for old IE fallback: modernizr, star hacks or otherwise?

Here's an example style supported by most browsers:
.class {
background: rgba(0,0,0,0.3);
}
Old IE (IE 6-8) don't support rgba. There are at least three methods I could potentially use to support this.
Same class
.class {
background: grey;
background: rgba(0,0,0,0.3);
}
Modernizr
.class {
background: rgba(0,0,0,0.3);
}
.no-rgba .class {
background: grey;
}
star hacks
.class {
background: rgba(0,0,0,0.3);
background: grey\9; /*IE8 and below*/
}
I prefer to use methods 1 and 2 because they cover more than just IE browsers, but I'm not sure which method I should use.
Method 1 is good because it works even if JS is disabled. However, there's an extra attribute to render for all modern browsers.
Method 2 is good because it segregates the bad browsers into their own classes. Modern browsers won't render this class which saves milliseconds of rendering time.
Maybe there's something else I'm not thinking of that could be better? I'd like to avoid using PIE.htc or filters. What is the best method for optimization and load time?
For this kind of style, the correct answer is the first one you listed:
.class {
background: grey;
background: rgba(0,0,0,0.3);
}
Specify the fall-back options first, followed by the preferred option.
IE will set the background to grey because it doesn't support rgba; other browsers will use the rgba version as intended.
The reasons this is the best answer are:
It is the canonical "correct" answer for this exact scenario: CSS was designed to work this way, with exactly this kind of situation in mind.
It is the least expensive option, because no browser has to do any extra rendering or scripting. IE will completely ignore the second background, so nothing extra happens there; other browsers will parse both, but parsing the second will overwrite what has been parsed for the first, so the only overhead is the parsing, which would have to be done anyway for whichever option you pick.
Of the other possible solutions, Modernizr is great, but is overkill for this scenario -- if you have a solution that doesn't involve any scripting, there's no need to use a scripted solution. And the CSS hacks should be avoided at all costs. There may be cases where they are worth using, but I personally haven't seen a legitimate use for one since I stopped trying to support IE6.
The other solution that is available but which you didn't mention is conditional comments: ie use IE's <!--[if IE]> syntax to load an alternative stylesheet for IE. However I would avoid this as well if possible, and again, the need for this kind of solution is fading away as IE6 and IE7 become more distant memories.
Finally, a slightly different option for you: Just ignore old IE. For some things, IE8 may not render things the way you want, and it's a pain to make it do so. In these cases, it is a perfectly legitimate strategy to just let it fail. For the example in the question, this isn't necessary, as we have a perfectly good CSS solution, but for other more complex styles, consider how bad the site will look if IE doesn't get things right; if it's still usable, then there may be a case for simply letting it slide. This option needs to be weighed against the number of users that will be affected and how much of a problem it causes for them, and also the requirements you're working to, but it should be considered as an option.
Your method #1 is the generally accepted way, because not only does it handle IE, but it also handles any browser that doesn't support the CSS in question (in this case, RGBA). The rule for CSS that browsers are supposed to follow is that if they don't recognize a line, they ignore it and move on. As for more capable browsers, CSS such as this is cheap, and the browser may not even render the fallback CSS at all (I know most don't download the image for image-based fallbacks).
Method 2 not only adds classes (which add weight), but adds an entire JavaScript library. If you're dealing with a bunch of other CSS3 type stuff (especially things that don't have such easy fallbacks), then it's not a big deal, but if you're using to handle fallbacks such as these, or just one or two, then you're adding a lot of overhead (including potentially another HTTP request) for not a lot of extra benefit. Even if the modern browsers don't render the classes, they do have to run the JavaScript to check for the capability.
Method 3 is a hack and should be avoided whenever possible (I recommend conditional stylesheets over resorting to hacks). Not only does it target only specific versions of a specific browser (thus leaving all the other browsers that don't support this CSS out in the cold), but relies on bugs in a browser to get the job done. And what happens if that code triggers a different bug in a different browser, or if a browser recognizes the line with the hack, but also behaves properly with the correct CSS? Have a look at some of the tutorials circa 2005, when IE6 and IE5 for Mac were still major contenders, and see the crazy lengths people went to with browser hacks to keep them from stepping on each others' toes. (Note: I do not consider prefixed CSS to be hacks. Prefixed CSS items are documented functionality that the browser vendors chose to add and serve the stated purpose of sandboxing those features. If they are for things that make it into the standard, then they are designed to be phased out over time.)
So, in order of preference - Fallback CSS, Modernizr, Conditional Stylesheets, Browser Hacks.

Can I combine a style that works with different browsers into one CSS?

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

Is it necessary to have valid CSS?

Is it necessary to have valid CSS? I am using Twitter Bootstrap for rapid web development and after running the two main Bootstrap style sheets through the W3C CSS Validator, I noticed about 600 errors.
My question is, my site looks good so why is it so important for the CSS to be valid?
Yes, it is absolutely necessary to have valid CSS. CSS is a programming language and as such, you must follow its language rules. Just because browsers tend to accept invalid HTML and try to render it, it doesn't make generating ill-formatted HTML a good practice. The same is true to CSS, although - fortunately - CSS rules are quite a bit stricter than HTML rules.
Another reason is that valid CSS has guaranteed behavior - if you write a rule, you can expect that rule to behave a certain way. (Buggy browsers, like all versions of IE aside.) If your CSS is invalid, any behavior you get is undefined and it may break when a patch release is issued for any of the browsers that you use for testing. Your CSS won't necessarily break but when you write invalid CSS, you get no guarantees of any behavior - you simply get some behavior that may seem correct to you but that may change any time.
If you have correct CSS mixed in with incorrect CSS, browsers tend to ignore the invalid parts (just how the specification tells them to) but each browser does it slightly differently. Similarly, while many people advise to use CSS hacks, I'd say not to, for the above reasons.
The CSS doesn't have to be valid to work. Browsers simply ignore the CSS that they don't understand.
Validating the CSS is a method to test if it follows the specification. If it does, any browser that is up to date with the specification used will understand the CSS.
It's somewhat of a debated topic really. The W3C tools are certainly good to use, but they tend to not account for a lot of modern code. Naturally, it's difficult for them to not only advance standards, but also make sure the tools they offer are accountable to new and inventive code.
In order to get websites to look good in all browser and across all platforms requires people to maybe stretch outside of the norms that otherwise would be "valid". It's tough to argue against a site that works perfect cross browser and platform even if the CSS isn't 100% spotless. That's my two cents.
Your CSS doesn't need to be valid (depending on who you ask), but if it is invalid, you should have a reason for the invalidity:
audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
}
The validator has a parse error here because of the asterisk at the beginning of property. This is a obscure but recognized hack for targeting Internet Explorer. Other browsers will ignore the properties that it won't recognize but IE6/7 will read properties with asterisks.
input:-moz-placeholder,
textarea:-moz-placeholder {
color: #999999;
}
input:-ms-input-placeholder,
textarea:-ms-input-placeholder {
color: #999999;
}
input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder {
color: #999999;
}
The validator error here is a result of vendor-specific pseudo-classes. Note than unlike unrecognized properties, if a browser doesn't recognize the selector the entire rule will be ignored so the vendor placeholder extensions need to be separate rules. This happens even when using the comma operator so:
input::-moz-placeholder,
input::-ms-input-placeholder,
input::-webkit-input-placeholder, {
color: #999999;
}
would be ignored in all browsers unless they recognized all three vendor prefixes.
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
This is the old-style IE extension for gradients. It ripples and causes a number of errors in the validator even though IE follows it and other browsers will not quietly ignore it.
width: auto\9;
The \9 is another IE hack that targets IE<=8
The bottom line is that if you are doing something non-standard, make sure you know why you are doing it.
Now a days there are different number of browsers with different number of versions.Some supports lot but some are not.So when you include styles it is always not possible to fit 100 % perfect.If your style works without any problem ok.But when it goes to different browsers if you get problem related CSS , You have to take care otherwise no problem.
yes its important, most of browsers follows the w3c standard when they load the html page. if your page don't have the valid css, in different browser it might appear different ways. Old internet explorers didn't followed the W3c standards which cost alot to the developers result in developer need always extra css for the IE to display page properly.

"fix internet explorer" stylesheet

I have a website that I've developed and tested using Firefox 9 exclusively. I'm pretty happy with the layout/styles when viewed in this version of Firefox. I'm now facing the unenviable task of making it display equally well (or as close as possible) in IE7+ (I'm not supporting IE6). Naturally, I'd also like it to display well in Chrome & Safari, but I think they implement the standards reasonably well, so I'm not so worried about them.
I'm using JQuery for JavaScript, which hopefully means I don't have too many differences in JavaScript behaviour, so my chief concern is the CSS. I imagine many others have been down this path, so I'm hoping there's a stylesheet available which when (conditionally) included will fix most common CSS problems seen when viewing a website in IE that has only been tested with Firefox. Does such a thing exist?
A catch-all miracle.css file which cures all IE-related ills? If only! The solution will probably boil down to a selection of some or all of the following:
Normalize (http://necolas.github.com/normalize.css/)
Brings most browser default settings to a more consistent baseline (think of this as an alternative to the popular Eric Meyer reset.css)
Modernizr (http://www.modernizr.com)
Seeing as you're already using javascript, including modernizr will give you additional methods of detecting browser capabilities. Also auto-injects .ie7 / .ie8 etc classes into your markup where necessary, allowing you to target IE in your styling, e.g.
.standard { ... }
.ie7 .standard, .ie8 .standard { ... }
CSS3PIE (http://www.css3pie.com/)
Progressive Internet Explorer - allows for styling which typically fails on IE (e.g. linear gradients, radiused corners, etc.)
IE7.JS (http://code.google.com/p/ie7-js/)
Probably the closest to what you were after, as an alternative to CSS fixes (which no doubt will still be necessary). Should help get you closer to the desired end result though.
I don't think there is any sort of stylesheet that does this for you.
You may look into a js script that look at solving IE issues. Or You can always do it the old fashion way using IETab and targeting the areas where you know there is going to be issues.
Most of them are described here: http://net.tutsplus.com/tutorials/html-css-techniques/9-most-common-ie-bugs-and-how-to-fix-them/.
Hope it helps :)

What Safari-specific pure CSS hacks are out there?

I'm wondering if there's any way to write CSS specifically for Safari using only CSS. I know there has to be something out there, but I haven't found it yet.
I think the question is valid. I agree with the other responses, but it doesn't mean it's a terrible question. I've only ever had to use a Safari CSS hack once as a temporary solution and later got rid of it. I agree that you shouldn't have to target just Safari, but no harm in knowing how to do it.
FYI, this hack only targets Safari 3, and also targets Opera 9.
#media screen and (-webkit-min-device-pixel-ratio:0) {
/* Safari 3.0 and Opera 9 rules here */
}
There are some hacks you can use in the CSS to target only Safari, such as putting a hash/pound (#) after the semi-colon, which causes Safari to ignore it. For example
.blah { color: #fff; }
.blah { color: #000;# }
In Safari the colour will be white, in everything else it will be black.
However, you shouldn't use hacks, as it could cause problems with browsers in the future, and it may have undesired effects in older browsers. The safest way is to either use a server side language (such as PHP) which detects the browser and then serves up a different CSS file depending upon the browser the user is using, or you can use JavaScript to do the same, and switch to a different CSS file.
The server-side language is the better option here, as not everyone has JavaScript enabled in their browser, which means they wouldn't see the correct style. Also JavaScript adds an overhead to the amount of information which needs to load before the page is properly displayed.
Safari uses WebKit, which is very good with rendering CSS. I've never come across anything which doesn't work in Safari, but does in other modern browsers (not counting IE, which has it's own issues all together). I would suggest making sure your CSS is standards compliant, as the issue may lie in the CSS, and not in Safari.
So wait, you want to write CSS for Safari using only CSS? I think you answered your own question. Webkit has really good CSS support. If you are looking for webkit only styles, try here.
You'd have to use JavaScript or your server to do user-agent sniffing in order to send CSS specifically to Safari/WebKit.
#media screen and (-webkit-min-device-pixel-ratio:0) {}
This seems to target webkit(including Chrome)... or is this truly Safari-only?
This really depends on what you are trying to do. Are you trying to do something special just in safari using some of the CSS3 features included or are you trying to make a site cross browser compliant?
If you are trying to make a site cross browser compliant I'd recommend writing the site to look good in safari/firefox/opera using correct CSS and then making changes for IE using conditional CSS includes in IE. This should (hopefully) give you compatibility for the future of browsers, which are getting better at following the CSS rules, and provide cross browser compatibility. This is an example.
By using conditional stylesheets you can avoid hacks all together and target browsers.
If you are looking to do something special in safari check out this.

Resources