Can we use CSS 2.1 selectors in practice? - css

The main culprit behind this question is of course IE6, (almost) everybody agrees that a website should support IE6 since it is used by more than 15% of the visitors (for Yahoo it is still an A-Graded browser).
IE6 doesn't support CSS 2.1, so can we use CSS 2.1 selectors in our stylesheets? Let me give an example:
<body>
<div class="header">
</div>
<div class="content">
<h1>Title</h1>
<p>First paragraph</p>
<p>Second paragraph</p>
</div>
<div class="footer">
</div>
</body>
My css could look like this:
body > div {width: 760px;} /* header content and footer = 760px wide */
h1 + p { margin-top: 5px;} /* the first paragraph after the h1 tag should have a smaller margin */
But IE6 won't understand this, so anyway to be browser compatible I should write it like this:
.header, .content, .footer { width:760px; }
And probably I have to give the first paragraph some class name and define it like that in my css. I could make a IE6 stylesheet specific that defines those rules, but that seems so double up (and still doesn't help in the case of the first paragraph needing a class name)...

If you're serious about supporting IE6 100% then you should avoid using CSS that wont work with it. One of the reasons for using those fancy selectors is to make your life easier, but it's not going to make your life easier if you have to rewrite them anyway for IE6. Finally, fancy selectors like that are slow in Firefox, so maybe just avoid them all together.

If you approach your site design from a progressive enhancement perspective then you should be fine, as more modern browsers will just get a better experience than those using ie6. If you are just looking to cut corners or save time developing, then you have to make a choice if ie6 users are important for your site or not.

I think the concept of "supporting" IE6 is the wrong idea, if we say no to that are we just not going to allow IE6 users access to our site and content? Of course not. So the question really is, how much time do you want to spend making the experience of your site the same for IE6 as other browsers.
My own standpoint is that I "support" IE6, in that a user of IE6 will be able to access all a site's content and all it's features, but they might not get the same visual or interaction experience as a Firefox 3 user.
So to answer your question, yes we can use CSS 2.1 and 3.0 selectors to achieve certain affects, as long as the content is still there for IE6 and with an acceptable visual appearance. What's acceptable will depend on the project (and likely the client!).
Your example was a good showcase of this:
p { margin-top: 10px; }
h1 + p { margin-top: 5px;} /* the first paragraph after the h1 tag should have a smaller margin
Here IE6 will still get the paragraph content, and there will still be all important white-space between them, they just won't get the reduced spacing on the first one. That's a fair compromise IMO for the reduced clutter in your HTML.
Another good example would be rounded corners. You can use -moz-border-radius and -webkit-border-radius to get rounded corners in Firefox and Safari, enhancing the visual experience of your site, but IE users still get the content albeit with plain old square corners (and then there are plenty of JavaScript solutions out there to achieve this for people with JavaScript enabled).
This would all come under the heading Progressive Enhancement

Your browser audience will dictate what you support as you've already stated, even a 'techy' website like w3schools still reports the IE6 market share at 17% for march.
That said, if you're going to support it, obviously you need alternatives.
I read another intersting thread about targetting just IE8 yesterday on stackoverflow, and I suspect supporting each browser will be easier if you can target them. I'm in a .net environment and use the approach that someone posted about half way down that thread so that my CSS selectors can very readily become:
body > div {width: 760px;}
.IE6 div.header, .IE6 div.content, .IE6 div.footer { width: 760px; }
Obviously you would find your own way of targetting browsers, but the CSS will equate to something similar.

It's not to the developer but to the site owner to decide whether to ignore IE6. You should give the site owner the stats for that specific site and then the decision should be made.
If you, or the owner, decide to NOT sacrifice the IE6 folks then it makes no sense whatsoever to use those fancy selectors. There is big downside and no upside as of yet.

For every IE6 user on mine site I got big red alert saying, their browser is ancient, and they should download a real browser, like Firefox ;] That's the solution. If webmasters won't say it to users, who will?

Javascript like JQuery.
CSS Hack. But I don't suggest it. Because it isn't W3C standard.
CSS Classname. By using CSS Classname replaces CSS Selector.

Related

CSS not working in Internet Explorer: missing borders img and nav with anchor tags (but works in Firefox)

I thought I had finished the markup for this website that I am creating for my mom’s dog walking business, but then I realized that my CSS is only partially applied to my site in Internet Explorer. It’s strange because the body background image in my CSS displays but my nav image and nav's anchor tags don’t show and the borders to my divs are missing in IE.
Everything works fine in Firefox.
Also the padding and margins are crazy in ie.
I’ve read from people that ie generally isnt too friendly towards margin-left margin-right padding-left and paddin-top- stuff like that. That it generally prefers for example padding: 20px; or margin: 30px;
But I don’t know if that was what I did wrong. I don’t see how that would make my borders and nav image disappear in ie. Very frustrating.
The url is www.grinningpup.com/dannytesting/grinningpup.com/index.html
I tried to write semantic markup. I hope the solution isn't due to a stupid mistake I made.
Welcome to SO!
I've taken a quick look at your site and I can see the issue is that you've used HTML 5 elements which aren't supported in older versions of IE.
Easiest fix is to add Modernizr which is a javascript library aimed at detecting browser support, and in most cases, polyfilling them (only in this case). There are numerous resources on the subject. My fvourite is this; http://diveinto.html5doctor.com/ but just google and check SO for more information.
I hope this helps you!
You are using HTML5, which IE8 and below don't interpret right.
You'll need to include html5shiv and add the following to your css:
article, aside, figure, footer, header, hgroup,
menu, nav, section { display: block; }
HTML "nav" tag and "section" tag not support IE 8 and earlier versions. So, you only use "div" tag solve all problem.

Is there any way to find unused CSS in a website?

Is there any way to find unused CSS in a website?
I'm trying to clean up a project I just inherited.
Dust-me Selectors is a Firefox plugin that finds unused selectors.
I just ran into this and remembered your question: http://github.com/geuis/helium-css
Chrome 59 has built-in coverage display for CSS and JavaScript since 2017-04: https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage
You can enable it by opening the dev tools, then the command menu (Cmd+Shift+P on Mac or Ctrl+Shift+P on Windows and Linux), and then type "show coverage".
There is so much that can be said about best-practice methods for CSS. I'll try to stick to the main points.
Use a CSS reset.
Try to remove really general CSS statements like h1 {} and #container em {}. You're much better off using h1.section-title and #container em.important {}, because that way if you choose to use h1 or em a different way somewhere in your document, you don't have to worry about overriding any existing code.
Don't be too specific in your CSS selectors if you don't have to. You really only need to have high degrees of specificity if being in a specific section changes how the element is going to be displayed. Otherwise, to make your code for your block class reusable, #container .content .block ... could be reduced to .block ... in many cases.
Look for commonalities in your CSS and see if you can create reusable classes. If you have similar blocks class="favorites" and class="popular", turn it into class="block block-favorites" and class="block block-popular", and put the commonalities into .block.
Get in the habit of making areas in your CSS have an auto-width (can be done implicitly) so that they grow to the width of your containers. This makes it incredibly easier to move sections from a narrow portion of your website to a wide portion of your website without having to change any code.
Commenting your code and breaking it down into sections usually helps make code more readable.
You'd be surprised how much cleaner your code looks when you implement more powerful CSS selectors. Most of them are cross-browser compatible (Internet Explorer 7 and later).
Some valuable resources: When can I use... - Quirks Mode on CSS Selectors - w3 on CSS Selectors
Answer moved from:
Best Practices for Cleaning up Existing CSS/unused styles
To add to #cweiske suggestion, Google Chrome has a no nonsense way of uncovering where your "unused" and "never will be used" selectors are.
I have posted a screen capture of how to launch the CSS Coverage tool with step by step markers.
It is a reliable way to figure out where you really are not using stuff.

Getting Transparent PNG to work in IE 6 in img tag

I have a png with transparent background that doesn't work in IE 6. I have gotten round the problem by replacing the few img tags using that image with a DIV, and in CSS I use:
#div {filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="./Images/img.png")}
the problem I have with this is that I then lose alt and title attributes which doesn't make the site very accessible. If I use the above CSS with an img tag I see the correct image but it has the big 'X' over it that IE shows when it can't display an image.
Any suggestions on how I can get IE to behave by showing the transparency correctly in an IMG tag?
One way you can continue to use the DIV tags, but still be accessable is to place a second SPAN tag within the DIV element and put the value for the ALT inside that, then style it to not be off the page... for example...
div.image {
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="./Images/img.png");
}
div.image span {
position : absolute;
top : -9999px;
}
Then the HTML would look like this...
<div class="image" title="The title for the image" >
<span>The ALT Text</span>
</div>
The title tag will still work on the DIV so you should be okay on that part.
I don't think you can simply hide the text (as in display:none;) because I think screen readers will respect that rule (as in not read it)
you could use javascript to enable transparency in ie6. there are many examples you can find. here is a link to one i have used.
http://jquery.andreaseberhard.de/pngFix/
another option is to use htc for ie6 - see here for solution:
http://www.twinhelix.com/css/iepngfix/
only requires an extra line added to your css file - sorry still may require javascript - not too sure.
I used a small javascript tool for solving this problem a couple of month ago. It's named Unit PNG FIX and it's very easy to use.
While someone here gave a JS implementation for this, this solution will be also executed for FF and other browsers. There are better ideas, for example using MS technology :)
One of them uses something called HTC (hypertext component, if I am not mistaking). It's something like... a CSS for behavior. It's really an XML file which lets you attach some functions to a CSS selector. Again, an MS only technology.
In short, visit this site:
http://www.twinhelix.com/css/iepngfix/
I am using this withing a drupal module and I am very happy. If you are wondering, this is the module: http://drupal.org/project/pngbehave
Note: this does not work under IE tester: http://www.my-debugbar.com/wiki/IETester/HomePage
I am using a Windows 2000 with IE6 (running under vmware, if you have to know) to test IE6 sites.
IE6 supports PNG-8 transparency, but not PNG-24. One of my favorite tools to "fix" IE6 is IE8.js.

Which browsers support page break manipulation using CSS and the page-break-inside element?

I'm trying to use the page-break-inside CSS directive, the class of which is to be attached to a div tag or a table tag (I think this may only work on block elements, in which case it would have to be the table).
I've tried all the tutorials that supposedly describe exactly how to do this, but nothing works. Is this an issue of browser support or has anyone actually gotten this working, the exact bit of CSS looks like this:
#media print {
.noPageBreak {
page-break-inside : avoid;
}
}
Safari 1.3 and later (don't know about 4) do not support page-break-inside (try it, or see here: http://reference.sitepoint.com/css/page-break-inside). Neither do Firefox 3 or IE7 (don't know about 8).
In a practical sense, support for this attribute is SO spotty, it doesn't make sense to use it at all at this point. You'd be lucky if even 10% of your visitors have browsers that can support this.
The solution I used was to add
page-break-after:always
to certain divs, or add a "page-breaker" div in where you want breaks. This is quite ham-handed, I know, because it doesn't do quite what you want, and causes content to not reach the bottom of the printed page, but unfortunately there isn't a better solution (prove me wrong!).
Another approach is to create a stylesheet that removes all extraneous elements (display:none) and causes the main content to flow in one main column. Basically, turn it into a single column, text-only document.
Finally, avoid floats and columns when styling for printers, it can make IE (and FF) act wacky.
Safari 1.3+, Opera 9.2+, Konquerer, and IE8 all support it, at least to some degree.
Firefox apparently still does not.
Firefox does not support this as of 2010-11-30, and thus won't in Firefox 4.
IE8 does support page-break-inside: avoid - but when I tried this on IE9, it's not very successful at avoiding page-breaks (this may be a regression, or perhaps IE8 is also only capable of avoiding page breaks in very simple cases).
AFAIK it doesn't work in any webkit browser; certainly not in chrome.
It actually works in Opera, even on real sites.
Safari 1.3 and later support page-break-inside.
So does Konqueror.
I'm trying to use the page-break-inside CSS directive, the class of which is to be attached to a div tag or a table tag (I think this may only work on block elements, in which case it would have to be the table).
Firstly, there's no need to guess. Just look at the specification, and you'll see that it does indeed only apply to block-level elements.
Secondly, <div> elements are usually block-level elements, so there's no problem applying page-break-inside to a <div> element.
Finally, you don't need to wrap it in #media. You only need #media if you want to apply media-independent rules to only one medium, for instance, if you want to use display: block only for one medium. In this case, you don't need to hide those rules from other media, because they'll only apply to paged media anyway.
From preliminary searches, it's hard to find up-to-date statistics on browser support for this, but it seems that Firefox 4beta6 supports it and Chrome 7 does not. Chrome also breaks pages halfway through a line of text, so that part of the text appears on one page and part appears on the next. Uncharacteristic lack of attention to detail, but I guess neither Google nor Apple care about printing things.
Firefox 4 also adds some nice headers and footers to your prints with url, page title, site title, number of pages, and time. Nice.
As a bit more information further to Eamon Nerbonne's answer on the IE rendering (IE8+), you need to make sure the browser is in standards mode. This article on MSDN shows what is necessary - including a meta tag in your html to force the issue:
<meta http-equiv="X-UA-Compatible" content="IE=8" />
Feels kludgy, but there you have it... seems to work more consistently.

Acceptable CSS hacks/fixes

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.

Resources