I encountered this question while browsing the Q&A section of an online course on advanced responsive design. I found an answer for it, shared it, and decided to post it here as well in case anyone else might have the same dillema.
The dillema is that it could be a lot easier for ensuring browser compatibility if we could define a different style for certain browsers that behave differently from most, e.g. Internet Explorer and, in the case of my website at least, Safari.
So how do we go about doing that? Check out my answer below to find out, and feel free to contribute if you think you know a better way to target specific browsers for specific media queries unique to them.
Using caniuse (https://caniuse.com/), look for a specific property that is only supported by the specific browser you want to target. Then, using the #support query, target that browser with the property you've found is unique to it. Then, whatever styling you apply within that query will only apply to the browser(s) that support(s) the property by which you defined the query.
That is, the properties inside the brackets of a #support query are used to define when - for which browsers - the styling inside the curly braces will apply; they do not need to be the same, that is, you do not need to use the same property styled within the curly braces to define the query in the brackets, so you can choose any property that targets the specific browser(s) you want to display the styling for.
Update:
I found this site that seems to provide the solution to targeting specific browsers and browser versions in the caniuse style, sparing you the need to test each property by hand:
http://browserhacks.com/
This article offers a briefing on how to use it:
https://www.templatemonster.com/help/how-to-create-browser-specific-css-rules-styles.html
Update:
For Internet Explorer only, older versions only, you can create a separate stylesheet to load for them using conditional comments in your HTML. This can be a copy of your general stylesheet, tweaked to work on old IE versions, but loaded only if those versions are detected, therefore not interfering with display on other browsers. They are not, unfortunately, usable for other browsers. This article explains how to use conditional statements.
https://www.quirksmode.org/css/condcom.html
Update:
The most effective solution to this problem seems to me to be to implement some javascript that detects the browser version and then applies specific styles or even modifies the DOM based on the browser(s) you target.
This explains the principle and some applications nicely:
Is there any equivalent to IE conditional comment for chrome and safari?
This, if rather old, is still a very useful such application:
http://rafael.adm.br/css_browser_selector/
And that's it! The ability to ensure browser compatibility with most any browser!
Related
I have a website which I support as far as IE8, no further.
When I first launched the site, I decided to use CSS vendor prefixes for CSSs elements such as border-radius, box-shadow etc. I did this from a complete noob standpoint.
However, is a better approach not to use them and simply let browsers catch up rather than patch up for the sake of uniformity?
No, you shouldn't remove all of them, however you may as well remove the ones which are no longer required.
How can I find out which prefixes are no longer required?
Can I use... is a great resource for checking browser support for various CSS, HTML and JavaScript features. If you perform a search for box-sizing, for instance, it will tell you that all modern browsers have partial support for this and that Firefox requires the -moz- prefix. You can also view all of the CSS support tables on just one page here.
How can I clarify that the prefixes are no longer required?
There are a couple of online resources which display information about browser usage. An example of this is StatCounter. StatCounter offers browser version statistics which can be filtered on time. If we look at the last 3 months, we can guestimate that we should still aim to support Firefox 20+, Chrome 25+, IE 8+ and Safari 5.1+.
Personally, I would just keep your vendor prefixes for now - this still remains professional practice - those browsers who don't need them, will simply ignore them anyway.
Our approach is to drop those which aren't needed.
border-radius
box-shadow
box-sizing (soon? firefox still uses it. Noted by #James Donnelly)
opacity (not a prefix, but no need for the ms-filter thingie)
inline-block (same here, no need for inline+zoom fix)
If you really want to get rid of prefixes, one of the solutions you can try is -prefix-free. It's a javascript plugin which loops through your stylesheets and, according to current browser removes the unused ones.
Although I didn't test it, I think it will definetely lower the performance.
You can also remove prefixes for properties which doesn't have a signifact meaning for functionality and/or user experience, like border-radius, box-shadow etc. You would have to test each element how it behaves without these properties. E.g. you have a button with border-radius: 4px. In a browser which doesn't support border-radius it will simply have rough corners. You must only consider if its worth sacrificing.
Why don't browsers autocorrect CSS3 transitions? The only difference between the Safari/Chrome and Firefox CSS transition is "moz" and "webkit". Surely firefox could just add an autocorrect feature to change every instance of "webkit" in the css to "moz" and the problem would be solved. Or is there something more?
Normally the -moz and -webkit are for CSS selctors are properties that are are specific to the the browser engine. The selector could be unstable, or act differently in each browser as they refine the behavior.
They don't want to "autocorrect" to the other implementation because the other browsers interpretation of the CSS property could be different. It could cause problems about what CSS property should "win" in the event of a conflict. Lastly, it could increase development time for each browser since they would need to figure out what the other browser engine is doing.
In the end what you want is to not use any -* prefixes at all. For that to be possible there needs to be a standard syntax and behavior defined by the, wait for it, CSS standard. Then instead of repeating *-opacity: ... several times with different prefixes, you just write opacity: ... once, like any other CSS declaration.
Vendor specific prefixes are there to allow browser specific behavior regardless of what the current standard says. It allows vendors to implement new features for which no standard exists yet, or to test the implementation of features before committing to it. The end goal is always to implement all features defined by the standard in the way the standard defines it; but you won't get there over night. New features need to be tested as widely as possible to find problems with their implementation or possible problems in the standard itself. This testing happens by making features available through vendor specific prefixes.
When you use a documented standard feature like opacity, it's pretty sure that it works consistently across browsers (*cough*letsforgetabout*cough*IE*cough*forasecond*cough*). When using a vendor specific prefix feature, it means you're using a feature at your own risk which is subject to change and/or may not work consistently (yet). Browser vendors don't touch each others prefixes for a reason, they work towards the standard and eventually make the feature available without prefix.
I have two issues I have ignored so far, but I will really appreciate some light shed onto them.
First: how can I solve differences between Safari, Chrome and Firefox and the various tags that their engines render differently? Should I just write down the right attribute for each in the same css rule? Is there no better way?
Is there a way to separate the CSS sheets for these browsers as I am doing for IE? Is this recommended?
Second: What about CSS3 attributes? Should I just write them again in the same rule after the CSS2 attributes?
Will this cause problems validating the CSS with WC3?
Welcome :)
If you start without the prefixes, you should write the code, generally, with all the semantically appropriate tags, first.
Then, you can decide what your goals are.
If you want W3C compliant CSS files, then you'd need to strip out the vendor specific prefixes by default. This would then allow the latest browsers to pick up the standardised CSS properties if they support them.
This will target less of your market than you might wish, so then you should ask if progressive enhancement is a possibility. If you can reasonably enhance the visuals by using css applied after the page has loaded, such as applying styles with jQuery, MooTools or Prototype libraries AND these libraries are already serving a purpose in your website, then you could apply additional styles with those libraries (and possibly use them in conjunction with Modernizr to determine which elements you may want to additionally support.
However, it's likely that a browser will skip a property it doesn't understand and will render the ones that it does, so I'd suggest that if you code it to W3C Standards first and then add in your additional vendor prefixes 'before' the final (correct) one, then you'll likely have satisfied reasonable measures to be compliant and meet design needs.
Edit:
There is a little bit of confusion between validation results from:
http://validator.w3.org/
and writing valid code related to vendor prefixes to get CSS effects cross-browser:
List of CSS vendor prefixes?
for working on some cross-browser CSS, you might find http://csspie.com, for IE compatibility with some CSS3 properties, useful along with http://www.colorzilla.com/gradient-editor/ for cross-browser gradients and http://cssplease.com for code that gives you alternative vendor prefixes, including different versions of IE support for many different properties.
In terms of validation, here's what W3C says about it: (see comments here: W3 VALID cross browser css gradient,) and official docs here: http://www.w3.org/TR/css3-syntax/#vendor-specific
If you code according to the specifications first and test your code out against that and then add in your vendor prefixes to get the same effects on the browsers you want to support (see progressive enhancement: What is Progressive Enhancement?) then you can be more confident that your code is supporting the appropriate standards, adding value to those with more advanced browsers and still useful for those without additional features (see also WAI III compliance, 508 compliance and others if you want to write a more inclusive site).
Caveat: Web Apps may not always be inclusive or follow these guidelines depending on who the audience is.
If you are using jquery on the site you may want to look into PrefixFree. It's a script that adds the vendor prefixes for you, so for example your put border-radius:6px; in yor css and it reads the browser and adds the appropriate vendor prefix for you via js. I like it cause it keeps my css docs more readable.
I'm dealing with crossbrowser issues... So I׳m looking for the best and clean CSS
One of the most important issues is the "IF" statements for each browser
Take a look at this page:
http://www.conditional-css.com/usage
It contains every information you'll need.
CSS, in and of itself, does not have "if statements".
Internet Explorer browsers do have conditional comments which provide a simple way to deliver code (HTML, CSS or JavaScript) to different versions of IE.
Other browsers don't really have anything like that, though there are browser vendor specific declarations like -moz-border-radius and -webkit-border-radius.
I am trying to figure out the most efficient way to ensure cross-browser compatibility. I have done a bit of research and learned a few interesting things such as the fact that Mozilla/Firefox can't handle a class that has a name starting with a number. Is there a way to make a CSS work for any browser or is it better to just develop multiple CSS and add code to choose which to use based on the browser being used?
You might consider using a CSS Framework such as Blueprint. It includes a CSS reset that should help.
Also, you might want to look at Yahoo's CSS reset
An aside to clarify a point:
... I have done a bit of research and learned a few interesting things such as the fact that Mozilla/Firefox can't handle a class that has a name starting with a number....
Sorry, but that's not a Mozilla limitation, it's in the CSS spec: class names must not start with a number. Any browser that allows them to isn't enforcing the rules properly.
Answered here on StackOverFlow. The relevant part of the spec is at http://www.w3.org/TR/CSS21/syndata.html#characters (see the 2nd paragraph).
To answer your question: There is no way to make a page using just one universal css and have it displayed equally in all browsers, unless you only use an extremely small sub-set of all available css (selectors, values, etc.).
The way I work is:
Use a css reset
Develop for a browser that adheres to the standards pretty well (Firefox, Chrome, Safari, Opera)
Patch things up for IE using conditional comments (because you'll probably need things that don't validate)
A good starting point would be to use CSS reset such as: http://developer.yahoo.com/yui/reset/
Your goal should be CSS that works on all browsers. If you start out with a CSS file per browser, where do you stop? Mobile Safari? Flock? Konqueror? Every version of every supported browser?
Eventually, you might need to compromise, but you can cross that road when you get there.
Regardless of your infrastructure/framework/etc you should test your code on all major browsers. If possible avoid using style sheets for browser specific problems. Browsers will change and adapt which means you might get stuck having to update a bunch of websites when new browsers come out.
CSS is a fickle beast and I haven't found any solution that covers all the quirks except for a lot of due-diligence and testing.
You might use a framework that does this for you, such as GWT, but keep in mind that you will still have some issues.