Browser-dependent CSS switch with JSF
I need some browser specific CSS in my JSF2 application (Mojarra 2.1, Tomcat 7).
I tried adding to my template:
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="#{cfgs.externalCssUrlIE8}" />
<![endif]-->
but the comments are not rendered since I also use:
<context-param>
<!-- Removes any comments from the rendere开发者_JS百科d HTML pages. -->
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
my problem... when I disable `javax.faces.FACELETS_SKIP_COMMENTS, I get a bunch of other problems.. Also I don't think my source-code comments belong to the generated pages.
I also tried to put the switch in CDATA like:
<![CDATA[
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="#{cfgs.externalCssUrlIE7}" />
<![endif]-->
]]>
but the inner < are rendered as html entities.. :-/, so its not working.
Question: Is there any other solution? Does any JSF2 tag exist to handle this? External tag libraries?
Thanks in advance, Steve
The only way is using <h:outputText escape="false">
.
<h:outputText value="<!--[if IE 8]><link rel="stylesheet" type="text/css" href="#{cfgs.externalCssUrlIE8}" /><![endif]-->" escape="false" />
Yes, this is a line of ugliness. But there's no other standard way.
Update: the JSF utility library OmniFaces offers a <o:conditionalComment>
for exactly this purpose so that you don't need the ugly <h:outputText escape="false">
anymore:
<o:conditionalComment if="IE 8">
<link rel="stylesheet" type="text/css" href="#{cfgs.externalCssUrlIE8}" />
</o:conditionalComment>
You might be able to work a solution using the inclusive syntax for conditional comments. Rather than writing <!--[if IE 8]> ... <![endif]-->
, you would write <![if !IE 8]> ... <![endif]>
.
In other words, without the dashes that make it a comment.
This is legitimate syntax. The intention of this syntax is that the conditional part is read by non-IE browsers, whereas with the syntax with the dashes, other browsers will ignore it.
Of course, this has obvious implications for your stylesheets -- the CSS included inside the conditional block will need to be for all browsers other than IE8 (you'll note the exclamation mark to I added above make it 'not IE8'); the IE8-specific stuff would need to be included in your standard stylesheet, to be overridden by the styles in the conditional block.
In other words, it's a reversal of functionality compared with what you're currently trying to do.
The important point for you is that doing it this way the conditional block is not a comment, and therefore shouldn't get removed by your parser.
You may need to rework a few things, but it should work.
The other option, of course, is to find an IE8-specific CSS hack. These do exist, but I would suggest avoiding them if possible, as you'll be making your CSS invalid, and there's always a danger of it breaking in some future browser version.
But if you want to go down this route, here's a link which gives you the answer: http://my.opera.com/dbloom/blog/2009/03/11/css-hack-for-ie8-standards-mode
But don't use that unless you have to. :-)
Hope that helps.
BalusC's answer is the correct answer to my question. Still I want to share a JavaScript + CSS based solution I found: The CSS Browser Selector.
Inserting this minified line of JavaScript enables you to use OS- and browser-specific CSS selectors, e.g.:
- html.gecko div#header { margin: 1em; }
- .opera #header { margin: 1.2em; }
- .ie .mylink { font-weight: bold; }
- .mac.ie .mylink { font-weight: bold; }
- .[os].[browser] .mylink { font-weight: bold; }
If your browser specific styling is still in the beginning, this might be a clearer solution compared to including many .css
files.
精彩评论