如何在 CSS 选择器中使用带有冒号“:”的 JSF 生成的 HTML 元素 ID?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5878692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 00:27:26  来源:igfitidea点击:

How to use JSF generated HTML element ID with colon ":" in CSS selectors?

cssjsfcss-selectorsfaceletsclientid

提问by Dzung Nguyen

I've been working with a simple Java EE project using JSF.

我一直在使用 JSF 处理一个简单的 Java EE 项目。

<h:form id="phoneForm">
    <h:dataTable id="phoneTable">

    </h:dataTable>
</h:form>

I tried to set CSS via #phoneTable { ... }, however it doesn't work. Upon inspection of the HTML source in client side, it appears that the JSF-generated HTML table gets a client ID in form of id="phoneForm:phoneTable". I can't apply CSS via #phoneForm:phoneTable { ... }, because the colon indicates the start of a pseudoselector and causes an error.

我试图通过 设置 CSS #phoneTable { ... },但它不起作用。在客户端检查 HTML 源代码时,JSF 生成的 HTML 表似乎以id="phoneForm:phoneTable". 我不能通过 应用 CSS #phoneForm:phoneTable { ... },因为冒号表示伪选择器的开始并导致错误。

How can I use it anyway in CSS selectors?

我如何在 CSS 选择器中使用它?

回答by BalusC

The :is a special character in CSS identifiers, it represents the start of a pseudo class selectorlike :hover, :first-child, etc. You would need to escape it.

:是CSS标识符的特殊字符,它代表了一个开始伪类选择一样:hover:first-child等你将需要转义。

#phoneForm\:phoneTable {
    background: pink;
}

This only doesn't work in IE6/7. If you'd like to support those users as well, use \3Ainstead (with a trailing space behind!)

这仅在 IE6/7 中不起作用。如果您也想支持这些用户,请\3A改用(后面有一个尾随空格!)

#phoneFormA phoneTable {
    background: pink;
}

Above works in all browsers.

以上适用于所有浏览器。



There are several other ways to solve this:

还有其他几种方法可以解决这个问题:

  1. Just wrap it in a plain HTML element and style via it instead.

    <h:form id="phoneForm">
        <div id="phoneField">
            <h:dataTable id="phoneTable">
    

    with

    #phoneField table {
        background: pink;
    }
    

  2. Use classinstead of id. E.g.

    <h:dataTable id="phoneTable" styleClass="pink">
    

    with

    .pink {
        background: pink;
    }
    

    or

    table.pink {
        background: pink;
    }
    

    Additional advantage is that this allows much more abstraction freedom. The CSS is reusable on multiple elements without the need to add selectors and/or copypaste properties when you want to reuse the same properties on another element(s).


  3. Since JSF 2.x only: change the JSF default UINamingContainerseparator by the following context param in web.xml. E.g.

    <context-param>
        <param-name>javax.faces.SEPARATOR_CHAR</param-name>
        <param-value>-</param-value>
    </context-param>
    

    So that the separator character becomes -instead of :.

    #phoneForm-phoneTable {
        background: pink;
    }
    

    Disadvantage is that you need to ensure that you don't use this character yourself anywhere in the ids and this is thus a very brittle approach.


  4. Since JSF 1.2 only: disable prepending of the form id.

    <h:form prependId="false">
        <h:dataTable id="phoneTable">
    

    so that you can use

    #phoneTable {
        background: pink;
    }
    

    Disadvantage is that <f:ajax>won't be able to find it and that it is considered poor practice: UIForm with prependId="false" breaks <f:ajax render>. This attribute does not exist in all other UINamingContainercomponents, so you still have to deal with them the right way (#1 and/or #2 here above).


  1. 只需将它包装在一个普通的 HTML 元素中,并通过它来设置样式。

    <h:form id="phoneForm">
        <div id="phoneField">
            <h:dataTable id="phoneTable">
    

    #phoneField table {
        background: pink;
    }
    

  2. 使用class代替id。例如

    <h:dataTable id="phoneTable" styleClass="pink">
    

    .pink {
        background: pink;
    }
    

    或者

    table.pink {
        background: pink;
    }
    

    额外的好处是这允许更多的抽象自由。当您想在另一个元素上重用相同的属性时,CSS 可在多个元素上重用,而无需添加选择器和/或复制粘贴属性。


  3. 仅从 JSF 2.x 开始:UINamingContainer通过以下上下文参数更改 JSF 默认分隔符web.xml. 例如

    <context-param>
        <param-name>javax.faces.SEPARATOR_CHAR</param-name>
        <param-value>-</param-value>
    </context-param>
    

    这样分隔符就变成了-而不是:.

    #phoneForm-phoneTable {
        background: pink;
    }
    

    缺点是您需要确保自己不会在 id 的任何地方使用此字符,因此这是一种非常脆弱的方法。


  4. 仅从 JSF 1.2 开始:禁用表单的前置id

    <h:form prependId="false">
        <h:dataTable id="phoneTable">
    

    这样你就可以使用

    #phoneTable {
        background: pink;
    }
    

    缺点是<f:ajax>无法找到它,并且被认为是不好的做法:带有 prependId="false" 的 UIForm 会破坏 <f:ajax render>。此属性在所有其他UINamingContainer组件中都不存在,因此您仍然必须以正确的方式处理它们(上面的 #1 和/或 #2)。


In yourspecific case, I think turning it into a CSS class as described in #2 is the most appropriate solution. A "phone table" namely doesn't seem to represent a website-wide unique element. Real website-wide unique elements such as header, menu, content, footer, etc are usually not wrapped in JSF forms or other JSF naming containers, so their IDs wouldn't be prefixed anyway.

您的具体情况下,我认为将其转换为 #2 中描述的 CSS 类是最合适的解决方案。“电话表”似乎并不代表网站范围内的唯一元素。真正的网站范围内的唯一元素,例如页眉、菜单、内容、页脚等,通常不会包含在 JSF 表单或其他 JSF 命名容器中,因此它们的 ID 无论如何都不会加前缀。

See also:

也可以看看:

回答by Swarne27

<h:form prependId="false">

Does not work if you are using a

如果您使用的是

<h:commandButton>
tag