Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
197 views
in Technique[技术] by (71.8m points)

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

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

<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.

How can I use it anyway in CSS selectors?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

#phoneForm:phoneTable {
    background: pink;
}

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

#phoneForm3A 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 class instead 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 UINamingContainer separator 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. I do not recommend this approach. This is a bad practice.


  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>. I do not recommend this approach. This is a bad practice. Moreover, this attribute does not exist in all other UINamingContainer components, so you still have to deal with them the right way (#1 and/or #2 here above).


In your specific 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.

See also:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...