4

Possible Duplicate:
CSS 3 content selector?

I couldn't find a way online to hide or show elements based on their contents in CSS. More specifically, in the following example, I'm searching for a CSS3 rule that would allow me to hide all <tr> entries whose second <td> child contains File.

<tr> <td>Succeded</td> <td>File</td> <td>Create</td> <td>Left->Right</td> <td>\Thunderbird\00sqrcu5.default.archive.7z</td> </tr> <tr> <td>Succeded</td> <td>Folder</td> <td>Create</td> <td>Left->Right</td> <td>\Thunderbird\mab</td> </tr> <tr> <td>Failed</td> <td>File</td> <td>Create</td> <td>Left->Right</td> <td>\Thunderbird\mab\abook.mab</td> </tr> 

Is this even possible? I know that it would be better to add attributes to the <tr> elements, but I'm not sure if an attributes-based solution would support complex rules such as "second child is not 'Folder' and first is 'Failed'".

Ideas?

4
  • 1
    Not with CSS selectors. XPath, I'm not sure. Commented May 4, 2011 at 19:31
  • 1
    I know this could easily be done with jQuery. Not with CSS. Commented May 4, 2011 at 19:33
  • 1
    Attribute-based solution? What do you mean exactly by that? Can you add the text of the node as an attribute (for example, <td t="File">)? Commented May 4, 2011 at 19:33
  • 1
    jQuery solution here. Commented May 4, 2011 at 20:42

3 Answers 3

4
  • CSS3 : no
  • javascript: yes
  • xpath: yes (something like //td[2][contains(text(),'File')]/..)

The xpath works like this:

  • //td = select tds anywhere in the document
  • [2] = restrict them to those that are the second child
  • [contains(text(),'File')] = restrict them to those that have File in their text
  • .. = go up one level (to the tr)

You can quickly test your xpath here

Sign up to request clarification or add additional context in comments.

1 Comment

+1: Better explanation of the XPath, plus a better testing link.
3

You can select all of those elements with XPath:

var headings = document.evaluate( "//tr[td[2][contains(text(),'File')]]", document, null, XPathResult.ANY_TYPE, null ); while(a = headings.iterateNext()) { console.log(a); } 

jsfiddle link

Not with css: Can't backtrack.

Edit:

See Dan's post (below) for an explanation of the pieces. The difference between the two is that I start with the tr element and give it a condition that it must contain a td with "File", whereas Dan's solution starts with the td element, specifies that it must contain "File", then backs up a level to the tr.

Also, he includes a link to a great XPath test page.

4 Comments

I was curious about the performance so I created this jsPerf test. It seems that your xpath is faster, great job :)
@Dan: Well, then I got lucky! (I've rarely used XPath besides in some xslt ages ago.) Also, your testing link is cool.
I almost never use xpath. I prefer jQuery and the like. I already +1'ed you :)
AAaah, not sure which answer to accept now :) Both great, upvoted both =)
-1

Try This. You stated

I'm searching for a CSS3 rule that would allow me to hide all entries whose second child contains File.

So I assume it is always the second child

td:nth-child(2) { display: none; } 

Working example

6 Comments

@JAA149 in one case the second child does not have File as content.
You can't make that kind of assumption.
Change your markup. Add the title attribute with a value of "file" to every td that has the content as file and use attribute selector such as td[title="file"]{display: none;}
Or you can try this tr:first-child > td:nth-child(2) { display: none; } tr:last-child > td:nth-child(2) { display: none; } jsfiddle.net/XanUS/1
@JAA149: I think you are missing the point, he wants to hide the entire tr (but only if its second child has 'File' in it).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.