4

I have a CSS table like this:

(this is a reliable simplification of my system)

<div class="table">
    <div class="row">
        <div class="data">
        abc
        </div>
    </div>
    <div class="row">
        <div class="data">
        def
        </div>
    </div>
    <div class="row">
        <div class="data">
        ghi
        </div>
    </div>
    <div class="row">
        <div class="data">
        jkl
        </div>
    </div>
</div>

And I have a CSS like this:

div.table div.row:not(.hide):nth-child(2n){
    background-color: #D7D4DA;
}
div.table div.row:not(.hide):nth-child(2n+1){
    background-color: #E4E8EB;
}

.hide{
    display:none;
}

The purpose is: When a line is hidden (using the class hide), the styling of the table should remain the same (each line with a different color between the two available). Instead, it get's broken.

According to firefox's firebug, the :nth-child is applied before the :not, not after (as I wanted). How can that be solved?

Note: Altering the HTML is a no go. This is something dynamically made using javascript.

My purpose is not to count for the nth-child the lines that are hidden in order to maintain the styling even if the line isn't visible

ScottS
  • 71,703
  • 13
  • 126
  • 146
brunoais
  • 6,258
  • 8
  • 39
  • 59
  • I've seen you posted this question the other day and I couldn't figure it out. You might want to use javascript/jquery for this. – elclanrs Feb 09 '12 at 18:16
  • 6
    You cannot change the evaluation order of pseudo-classes. Everything in a compound selector is evaluated "at the same time" on any given element. See [this answer](http://stackoverflow.com/a/5217102/106224) for an explanation. Also, I'm sorry that you have to put up with a script that outputs a CSS table that clearly should have been an HTML table. – BoltClock Feb 09 '12 at 18:18
  • @BoltClock♦ thx, man. Seems like I'll have to put up using classes to mark the nodes in the two colors and use js to change the classes when a line is hidden. Thx (again). – brunoais Feb 09 '12 at 18:42
  • Can you add in the css to make that look like the table you want, so that we can spend time working on the problem rather than the basic layout. Cheers – Deadlykipper Feb 16 '12 at 10:29
  • There's no CSS solution. CSS is not prepared to deal with this specific situation. The only way around is using javascript. I use this with nth-child and then I override with js when there's hidden stuff – brunoais Feb 16 '12 at 15:41
  • A possible way around is using a repeating image as a background of the table container. – Alex Feb 17 '12 at 13:51
  • If the size of a row changes puff..... – brunoais Feb 17 '12 at 17:47
  • Do you have access to js as well? You could add "even" and "odd" classes to all the elements and then reassign those classes with jquery excluding the .hide elements after the hide event happens. – squarecandy Feb 29 '12 at 22:38
  • @squarecandy I have js in the page, I just wanted ot have a reaction that does not depend on js. Anyway, it's solved now. I already have a solution that works. Does not work as I intended but it works. I just use the children[] and check 1 by 1 applying even or odd classes for the ones that do not have the substring "hide". – brunoais Mar 01 '12 at 06:41
  • @BoltClock--I'd be interested in your thoughts about the solution I posted for this. – ScottS Mar 03 '12 at 17:21

1 Answers1

2

Pure CSS Answer (CSS3)

There are some careful considerations to take into account (see below), but there does appear to be a way to do this in pure css (note that fiddle uses the fake div table per this post, but it could be done with real html tables) using a linear-gradient with color stops (technique found here) on the table background. The key to make it flexible with font-size changes (or zooming) is to set the height portion of the background-size to twice the line-height set for the rows.

Considerations:

  1. line-height and font-size for row should be explicitly set with em units (except see note #5 below).
  2. If padding is set on the table (not recommended) then some type of adjustment to either background-position or background-clip will likely need to be done to accommodate the padding.
  3. If top or bottom padding or margin is set on the row then it should be in em units and added to the line-height value before calculating the doubled linear-gradient height.
  4. This technique will change color of background within a row if that row has multiple lines in it (see the last table in my example fiddle).
  5. If some other fixed height element were in the rows (images set to 20px high), then the row height and linear-gradient height could be set based off pixel values.

I have not taken the time to play around with #2 and #3 above to figure out for sure the exact adjustments needed, but theoretically it should be possible to accommodate those things if necessary.

Community
  • 1
  • 1
ScottS
  • 71,703
  • 13
  • 126
  • 146
  • A fiddle with 140 revisions. You've been busy! – BoltClock Mar 03 '12 at 17:22
  • @BoltClock--yes, too much time on it for sure. I thought I had an `nth-child` solution until I tested it with mixed types of hides in http://jsfiddle.net/yjkLT/67/ (note all the tables were good until the last two). – ScottS Mar 03 '12 at 17:25
  • Yeah, you won't get very far with `:nth-child()` once you start mixing them up, because it's just not designed to handle that kind of dynamism (although with `:nth-match()` in CSS4 it may be as easy as `.row:nth-match(2n of :not(.hide))` and `.row:nth-match(2n+1 of :not(.hide))`). Meanwhile with CSS3, it turns out that linear gradients with hard color stops *are* great for striped patterns as long as legacy support isn't paramount, so you have my vote :) – BoltClock Mar 03 '12 at 17:30
  • @BoltClock--Nice (the CSS4 info and the upvote). I tried using `.hide:nth-of-type` to get the count on the `.hide` elements, only to find out that it does not work that way (though in my mind, it should), and instead looked to type as `div`. If I could have figured out how to count the `.hide` elements only (with css and selecting off that) I think I could have made a working solution based off `nth-child`. – ScottS Mar 03 '12 at 17:39
  • [`:nth-of-type()` doesn't look at classes](http://stackoverflow.com/a/8539107/106224), it only looks at types (`div`, `td`, etc), so that one's out too. One of the reasons why they proposed `:nth-match()`. – BoltClock Mar 03 '12 at 17:42
  • Nice try but there's the problem no 4. Except for that1 everything is great and great job *thumbsup* – brunoais Mar 04 '12 at 11:44
  • @brunoais--Yes, I have not figured out if there is a way for me to counteract the #4 consideration. For some tables, that would not be an issue (which is why I posted the answer), but for other tables it would definitely be cause to not use this solution. – ScottS Mar 05 '12 at 12:20