1

I use several tables and I want to shade alternating table rows. The common way to do so is

.t tbody > tr:nth-child(odd) > td:nth-child(1) {
      background-color:#f0f0f0;
    }

This works in Firefox, Chrome, and Safari, but IE does not support the nth-child() pseudo class. Short of tagging each row manually with a class, is there an alternative cross browser method to accomplish this? I wish to avoid this because it will consume space on the embedded system.

Note: This page is served from an embedded system acting as a WiFi Access Point. That means, that the client will be connected to the embedded system, and not to the internet. Means no JS libraries.

EDIT: IE 9 will support nth-child(), but I need to be able to support IE 7 and 8 as well

waldol1
  • 1,841
  • 2
  • 18
  • 22
  • 1
    What version(s) of IE do you need to support? IE understands `:nth-child()` starting from version 9. – BoltClock Aug 30 '13 at 20:54
  • I need to support IE 7, 8, 9 – waldol1 Aug 30 '13 at 21:02
  • If you can't use a JS library, then the only option you have is to add classes to the elements you want to style when you're writing the page. But I'm not entirely sure why you can't use a library if it's served from the same host as the main html page; it should be accessible just the same as the page itself. Maybe your issue is the file size? IE9.js is 40k, which is probably smaller than your logo graphic. Smaller if it's gzipped. And only old IE users would ever need to download it. – Spudley Aug 30 '13 at 21:04
  • 1
    I'm concerned about byte space. Adding a class attribute will consume about 10 bytes per element. Embedding an entire js library to solve a formatting issue is not feasible unless I have over 4,000 elements, which I do not. – waldol1 Aug 30 '13 at 21:06
  • 2
    IE7 just made me write several lines of code I've not written before. The joys of being an early 20-something coder in 2013. I'm really spoiled. – BoltClock Aug 30 '13 at 21:09
  • http://stackoverflow.com/questions/8492121/ie8-nth-child-and-before – markasoftware Aug 30 '13 at 21:18
  • @Markasoftware Quoting the accepted answer "You cannot emulate more complex variations of `:nth-child()` such as `:nth-child(odd)` or `:nth-child(4n+3)` with this method." I'd have to count bytes to see if it would result in a smaller code size for my table lengths... – waldol1 Aug 30 '13 at 21:21

3 Answers3

3

No; unfortunately you have to tag each row manually with a class to replace :nth-child(odd). You can replace :nth-child(1) with :first-child though, assuming you're supporting something like IE7 or IE8 and not an extremely old version.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
1

Here is the css you need:

.shaded {
    background-color: #F0F0F0;
}

Here is a js function that will accomplish this, given some assumptions about the table structure:

function go() {
  tables = document.getElementsByTag('table');
  var i, len = tables.length;
  for(i = 0; i < len; i++) {
    var tbody = tables[i].children[0] // assumes <tbody> is first child
    var k, num_trs = tbody.rows.length;
    for(k = 0; k < num_trs; k+=2) {  // k += 2 for alternate shading
      var tr = tbody.rows[k];
      tr.classList.add('shaded');
    }
  }
}

I'm sure someone could improve on it so that it intelligently selects the tbody, or takes a parameter to determining shading pattern.

waldol1
  • 1,841
  • 2
  • 18
  • 22
  • 1
    I'll keep my answer - my code ended up being much more convoluted though, because I wasn't able to make some of the assumptions you're making here. Case in point: getting elements by class is a pain in anything below IE8, while you've simply chosen to grab any `tbody` elements directly, which seems simple enough in retrospect. – BoltClock Aug 30 '13 at 21:55
  • hmmm, grabbing the tbody elements directly and not going through the tables would make for less complication. Good idea. – waldol1 Aug 30 '13 at 22:00
  • Yeah I was assuming you had other tables without the `t` class, and that you didn't want to style rows under those other tables. – BoltClock Aug 30 '13 at 22:03
  • Oh, in the code I'm using I do do it that way. It is easy enough to replace `document.getElementsByTag` with `document.getElementsByClassName`. But all my tables have the t class anyway. But that might be able to go away now. – waldol1 Aug 30 '13 at 22:13
  • 1
    `document.getElementsByClassName` doesn't work on IE7 though. – BoltClock Aug 30 '13 at 22:14
  • doesn't it? I didn't check that. I'll stick to using `document.getElementsByTag` – waldol1 Aug 30 '13 at 22:15
1

Place this script at the end of your page. It assumes the first tbody found, but you could modify this to whatever offset (or to handle multiple tbodys), or even make things easier by targetting with a specific id.

<script>
(function(){
  var 
    tby = document.getElementsByTagName('tbody')[0],
    trs = tby.getElementsByTagName('tr'),
    i, l = trs.length
  ;
  for ( i=0; i<l; i++ ) {
    if ( (i + 1) & 1 ) {
      trs[i]
        .getElementsByTagName('td')[0]
          .style
            .backgroundColor = '#f0f0f0'
      ;
    }
  }
})();
</script>

The above could be minified if you are worried about bytes.

Pebbl
  • 34,937
  • 6
  • 62
  • 64