【问题标题】:Browser-dependent CSS switch with JSF使用 JSF 的依赖于浏览器的 CSS 开关
【发布时间】:2011-09-26 14:47:06
【问题描述】:

我的 JSF2 应用程序(Mojarra 2.1、Tomcat 7)中需要一些特定于浏览器的 CSS。

我尝试添加到我的模板中:

    <!--[if IE 8]>
        <link rel="stylesheet" type="text/css" href="#{cfgs.externalCssUrlIE8}" />
    <![endif]-->

但是由于我也使用了 cmets,所以没有渲染:

<context-param>
    <!-- Removes any comments from the rendered HTML pages. -->
    <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
</context-param>

我的问题...当我禁用 `javax.faces.FACELETS_SKIP_COMMENTS 时,我遇到了很多其他问题。而且我认为我的源代码 cmets 不属于生成的页面。

我还尝试将开关放在 CDATA 中,例如:

<![CDATA[
 <!--[if IE 7]>
        <link rel="stylesheet" type="text/css" href="#{cfgs.externalCssUrlIE7}" />
 <![endif]-->
]]>

但内部

问题:还有其他解决方案吗?是否存在任何 JSF2 标记来处理此问题?外部标签库?

提前致谢, 史蒂夫

【问题讨论】:

    标签: css jsf-2


    【解决方案1】:

    唯一的方法是使用&lt;h:outputText escape="false"&gt;

    <h:outputText value="&lt;!--[if IE 8]&gt;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;#{cfgs.externalCssUrlIE8}&quot; /&gt;&lt;![endif]--&gt;" escape="false" />
    

    是的,这是一条丑陋的路线。但没有其他标准方法。


    更新:JSF 实用程序库OmniFaces 提供了一个&lt;o:conditionalComment&gt; 正是用于此目的,这样您就不再需要丑陋的&lt;h:outputText escape="false"&gt;

    <o:conditionalComment if="IE 8">
        <link rel="stylesheet" type="text/css" href="#{cfgs.externalCssUrlIE8}" />
    </o:conditionalComment>
    

    【讨论】:

    • 谢谢。有用!我也试过 但你是对的:丑陋的转义 h:outputText 似乎是唯一的解决方案。
    • 不客气。请注意 &lt;f:verbatim&gt; 在 JSF2 中已弃用。它完全没有任何价值,因为在 Facelets 中嵌入纯 HTML 是完全允许/支持的(自 JSP 上的 JSF 1.2 以来也是如此)。要在 Facelets 中有条件地呈现纯 HTML(就像您之前使用 &lt;f:verbatim rendered="#{some condition}"&gt; 所做的那样,您应该改用 &lt;ui:fragment&gt;
    • 很好的解决方法,尽管它很丑……你又救了我:)
    • @BalusC h:formh:head 内部使用h:outputText 时未渲染
    【解决方案2】:

    您也许能够使用条件 cmets 的包容性语法来解决问题。与其写&lt;!--[if IE 8]&gt; ... &lt;![endif]--&gt;,不如写&lt;![if !IE 8]&gt; ... &lt;![endif]&gt;

    换句话说,没有破折号使其成为评论。

    这是合法的语法。这种语法的目的是非 IE 浏览器可以读取条件部分,而使用破折号的语法,其他浏览器会忽略它。

    当然,这对您的样式表有明显的影响——条件块中包含的 CSS 需要适用于除 IE8 之外的所有浏览器(您会注意到我在上面添加的感叹号使其“不是 IE8” );特定于 IE8 的内容需要包含在您的标准样式表中,以便被条件块中的样式覆盖。

    换句话说,与您当前尝试执行的操作相比,这是一种功能倒置。

    对您来说重要的一点是,以这种方式执行条件块不是注释,因此不应被您的解析器删除。

    你可能需要修改一些东西,但它应该可以工作。

    当然,另一种选择是查找特定于 IE8 的 CSS hack。这些确实存在,但我建议尽可能避免使用它们,因为你会使你的 CSS 无效,并且在未来的某些浏览器版本中总是存在中断的危险。

    但是如果你想走这条路,这里有一个链接可以给你答案:http://my.opera.com/dbloom/blog/2009/03/11/css-hack-for-ie8-standards-mode

    但除非你,否则不要使用它。 :-)

    希望对您有所帮助。

    【讨论】:

    • 我有一个 [if IE 7]、[if IE 8] 等的列表,所以 BalusC 的答案是一种更简单的方法。无论如何,感谢您的明确回答。
    • @alfonx - 没问题;正如您所说,@BalusC 的答案可能更适合您的情况,但希望您发现我的答案仍然有用;即使这一次没有帮助。 :)
    【解决方案3】:

    BalusC 的答案是我的问题的正确答案。我仍然想分享一个我发现的基于 JavaScript + CSS 的解决方案:CSS Browser Selector

    插入 this minified line of JavaScript 使您能够使用特定于操作系统和浏览器的 CSS 选择器,例如:

    • html.gecko div#header { 边距:1em; }
    • .opera #header { 边距:1.2em; }
    • .ie .mylink { 字体粗细:粗体; }
    • .mac.ie .mylink { 字体粗细:粗体; }
    • .[os].[browser].mylink { 字体粗细:粗体; }

    如果您的浏览器特定样式仍处于初始阶段,与包含许多 .css 文件相比,这可能是一个更清晰的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-17
      • 1970-01-01
      • 1970-01-01
      • 2020-10-14
      • 1970-01-01
      • 2011-10-16
      • 2020-10-08
      • 2014-12-24
      相关资源
      最近更新 更多