The Table Ruler

by Christian Heilmann

97 Reader Comments

Back to the Article
  1. It might be nice at least to mention the following CSS: table.ruled tr:hover {
        background-color: #aaaaff;
    } It won’t work in IE (which doesn’t support :hover except on anchors), but it’s the best solution for browsers that support it.
    Copy & paste the code below to embed this comment.
  2. if (document.getElementById && document.createTextNode) Why are you testing for these functions when you use neither?  Wouldn’t it be better to check for document.getElementsByTagName? if(tables.className==‘ruler’) Probably should check to see if classname _includes_ ruler - that way allowing for multiple classes. trs[j][removed].nodeName==‘TBODY’»
        && trs[j][removed].nodeName!=‘TFOOT’ If nodeName == ‘TBODY’ then it’s definitely not going to equal TFOOT !
    Copy & paste the code below to embed this comment.
  3. For things that involve dynamically altering elements’ classes (as IE necessitates), it’s often best to assume that there is an existing (non-empty) class for the element. For example: function mouseoverHandler(e) {
      var class = e.currentTarget.className.split(/\s+/);
      class.push(‘IEhover’);
      e.currentTarget.className = class.join(’ ‘);
    } function mouseoutHandler(e) {
      e.currentTarget.className = e.currentTarget.className.replace(/\s*IEhover/,’‘);
    } someElem.addEventHandler(‘mouseover’,mouseoverHandler,false);
    someElem.addEventHandler(‘mouseout’,mouseoutHandler,false);
    Copy & paste the code below to embed this comment.
  4. Since most people using this might want also to be able to “click” their rows…. function clickHandler(e) {
      var class = e.currentTarget.className;
      if (class.match(/\s*clicked/)) {
        class = class.replace(/\s*clicked/,’‘);
      } else {
        var classSplit = class.split(/\s+/);
        classSplit.push(‘clicked’);
        class = classSplit.join(’ ‘);
      }   e.currentTarget.className = class;
    } someElem.addEventHandler(‘click’,clickHandler,false);
    Copy & paste the code below to embed this comment.
  5. As for :hover, you answered yourself, IE without the IE7 extension doesn’t support it, this technique is a hack for the present situation. As for the checking, it is a standard way to check for DOM, excluding Opera 6 and other browsers that claim to understand DOM but implement it flakily. As for making the rows clíckable, I dislike that as you might want different targets for each TD not one for the whole row.
    Why different classes when you can do that with different IDs as shown in the example?
    Copy & paste the code below to embed this comment.
  6. Sorry, reading CSS-D emails at the same time confused me.
    Copy & paste the code below to embed this comment.
  7. Anyone think it’s possible to use accesskeys to set focus and navigation up & down in the table, a la Excel? I know that’s out there, but was wondering about how I use a spreadsheet.
    Copy & paste the code below to embed this comment.
  8. My “clicking” doesn’t have to do with loading a new page, popup, or anything, but simply allowing rows to present the appearance of being “selected” with a mouse click. I usually implement this in tandem with the hover with such CSS as: table.interactive tr:hover td {
        border: 1px solid blue;
    } table.interactive tr.clicked td {
        background-color: #ddddff;
    } Not sure what you’re asking with regard to classes vs. IDs, but since this is all about attributes of similar objects, doing this with class seems to be natural. (I really wish the HTML people had used a different term than “class”; it makes people neglect the multi-class power…)
    Copy & paste the code below to embed this comment.
  9. How you use a spreadsheet? Use Openoffice or Excell. I am sure you can simulate that, but why reinvent an app in DOM? As for focusing, you can of course do that, but what happens to the links in the TDs then?
    Copy & paste the code below to embed this comment.
  10. I use spreadsheet-like things in DOM for building database web apps. It’s a very intuitive way for people to work: highlight some rows with mouse clicks, then click another button to perform some function on the data they represent. In this context I have a hidden input for each row whose ‘disabled’ attribute gets toggled by the mouse click. Any links in the TDs are still active. Usually what happens by default is that the click will go first to the row, then to the link, so what you see is the row turning color right before your browser switches pages. I work around the row-click here by doing noSelectRow = false;
    function linkMouseoverHandler(e) {
      noSelectRow = true;
    }
    function linkMouseoutHandler(e) {
      noSelectRow = false;
    } ...and adding a noSelectRow check to the row-clicking function.
    Copy & paste the code below to embed this comment.
  11. albeit Javascript dependent, but I suppose in a closed environment you can expect that.
    Thanks for adding this to the discussion, if anybody needs that functionality added, this is one way to do so.
    Copy & paste the code below to embed this comment.
  12. Note that the tfoot element should come after thead but before tbody.  This seems to be well-supported and is designed so that footer rows, e.g. totals, can displayed by the user agent before the entire table has been loaded.
    Copy & paste the code below to embed this comment.
  13. First, why use JavaScript at all when pure CSS can do the same thing?
    Second, to be valid XHTML the tfoot tag must be placed before the tbody tag.  Further, on the topic of valid XHTML, there are other errors in the example page including using the wrong mime type for an XHTML document.
    Copy & paste the code below to embed this comment.
  14. If IE doesn’t support it don’t use it. I don’t care if sucks of not. It’s 95% of the web. Good article, one question:
    Why return false on the mouseover?
    Copy & paste the code below to embed this comment.
  15. Tfoot has to come before Tbody? Jesus that makes a lot of sense doesn’t it?
    Copy & paste the code below to embed this comment.
  16. Quite useful, especially coupled with the previous article http://www.alistapart.com/articles/zebratables/ and the ability to sort columns by clicking on the column header. Now I just need a client who needs this functionality =)
    Copy & paste the code below to embed this comment.
  17. No one has mentioned the .htc behavior hack? (http://www.xs4all.nl/~peterned/csshover.html) This seems to work fine. And when/if the time comes when IE isn’t dependant on this hack you just remove the line from you css file.
    Copy & paste the code below to embed this comment.
  18. I’m just not crazy about this implementation. People have become used to the idea that hover-over effects indicate links, and this could confuse them unless you spell out the script’s purpose above the table.
    Copy & paste the code below to embed this comment.
  19. You might want to check out how Opera (7.23) handles this, marking the actuall text and not the background.
    Copy & paste the code below to embed this comment.
  20. Tfoot has to come before Tbody. This is so the browser can render the Thead and Tfoot while the rest of the Tbody (which could potentially have a large amount of data) is being downloaded.
    Copy & paste the code below to embed this comment.
  21. Looking at the posts, yeah, IE doesn’t support it, but it doesn’t mean it’s a “hack”. As Felipe said, a small note about the pure CSS implementation (with an explanation that it’s a :hover problem in IE) could have been discussed in the main article. I’m sure several readers are wondering about it. It’s still a good read though. =)
    Copy & paste the code below to embed this comment.
  22. if you put the <tfoot> after <tbody> in your table, the w3c validator will tell you that this is not standards compliant. still, if you put <tfoot> and <tbody> in the right order, the browser should display the contents of the <tfoot> at the end of the table ;) makes sense…? i actually tried to make hover <td>s using css only, but in IE that is not possible :( so you have to use JS to make it “IE compliant” :)) but i think a little modification in the JS code of the “zebra stripes” article can bring you the desired result.
    Copy & paste the code below to embed this comment.
  23. First of all, nice article. Best JavaScript I’ve seen here in a while. However, there are some small points. 1) As said before, you can’t assume there’s only one class being used.
    2) In XHTML documents node.nodeName is lowercase. Therefore, when you compare node.nodeName it’s best to lowercase it and compare it to a lowercase tag name: trs[j][removed].nodeNam.toLowerCase() e==‘tbody’
    3) Nitpicking: I rather see trs.item(j) than trs[j]. It doesn’t make a difference at all, but item() is semantically a bit more right.
    4) Don’t hijack events when you don’t know what other code is running. Use a cross-browser addEvent method like Scott Andrews: http://www.scottandrew.com/weblog/articles/cbs-events
    Copy & paste the code below to embed this comment.
  24. However could you please read through the comments before repeating questions and solutions? The IE7 hack (and in that I include other .htc shenanigans) was mentioned, same way that not only hover as IE does not support it without them. I realised the opera problem earlier aswell, and I am at loss of an explanation, a shame as it is my favourite browser atm (7.5 beta that is). Good points about the tfoot, will rectify that on my copy of the article. Also the lowercase will be implemented, however I still don’t see the point in several classes, when you can add in ID and a contextual selector?
    Copy & paste the code below to embed this comment.
  25. Chris said:
    “however I still don’t see the point in several classes, when you can add in ID and a contextual selector?” You could be styling two tables using one class. If one of these tables uses the ruler, however, you have to reside on using the ID. It’s a matter of preference how one solves this problem. In my opinion third-party JavaScript code should not effect the way the site must be build in any way. By this I mean, among other things, event hijacking and classNames.
    Copy & paste the code below to embed this comment.
  26. The great thing about switching the class of the hovered element is that when you want to change the colors, you don’t have to update all the code, just that class in the CSS file.
    BTW “htc shennanigans” is a phrase I intend to use a lot from now on.
    Copy & paste the code below to embed this comment.
  27. No offense, but using item(i) over because of “Semantics” is one of the stupidest things I’ve ever heard.
    Copy & paste the code below to embed this comment.
  28. One small thing—which isn’t a fault on your part, the script won’t work if you have multiple classes. I’m not sure where the blame should lye here (if anyone is to be blamed at all, that is). Since we’re accessing the class using a special “className” property, as opposed to just “class” (the name of an attribute), one would expect it to do more that just compare a string. Have the browsers got it wrong? Or should we have to split the “className” or regex it each time we need to use it?
    Copy & paste the code below to embed this comment.
  29. Seems like you need to apply a regExp as explained earlier to do that. I wouldn’t have expected multiple classnames to be that widely, used as I am a big fan of contextual selectors instead (I don’t like adding loads of attributes in the HTML).
    Copy & paste the code below to embed this comment.
  30. CM Harrington: To do this, I had to change the scripts a bit. For the zebra table, I changed it to apply a class to each odd tr, rather than a bg color to each td in the tr. For the ruler script, I had to get the current/old class just before it is changed to the ‘ruler’ class, the place the old class back, rather than an empty string. Works nicely at the moment. Will post code if anyone wants it.
    Copy & paste the code below to embed this comment.
  31. To add a class:
    obj.className+=” class”;
    Classes are seperated by spaces. className is misleading.
    Copy & paste the code below to embed this comment.
  32. Dante-Cubed said:
    “No offense, but using item(i) over because of “Semantics” is one of the stupidest things I’ve ever heard.” That’s why I said I was nitpicking. It all comes down to personal preferences. I’m guilty of having used both ways in the past (actually, first using item(), then [] and now back to item()).
    Copy & paste the code below to embed this comment.
  33. I haven’t tried the HTC yet. This is my attempt. It should use the script in IE and the hover in NS/Moz/Firebird/Opera. STYLE:
    table.ruler tbody tr.ruler
    {
      background:#039;
      color:#fff;
    }
    table.ruler tbody>tr:hover
    {
      background:#039;
      color:#fff;
    } SCRIPT:
    var undefined; function formatTable(oTable){
      var aBody = oTable.getElementsByTagName(“tbody”);
      var iLen = aBody.length;
      for(var i=0; i < iLen; i++)
      {
        var aRows = aBody.rows;
        var iRowsLen = aRows.length;
        for (var x=0; x < iRowsLen; x++)
        {
          aRows[x].attachEvent(“onmouseover”, toggleRow);
          aRows[x].attachEvent(“onmouseout”, toggleRow);
        }
      }
    }
    function toggleRow(e){
      var
      var sClass = oNode.className;
      if(/ruler/.test(sClass)==true)
      {
        oNode.className=sClass.replace(/ruler/,”“);
      }
      else
      {
        oNode.className += “ruler”;
      }
    }
    function init()
    {
      if(document.attachEvent!==undefined && document.addEventListener==undefined)
      {
        var aTables = document.getElementsByTagName(“table”);
        var iLen = aTables.length;
        for(var i = 0; i < iLen; i++)
        {
          if(/ruler/.test(aTables.className)==true)
          {
            formatTable(aTables);
          }
        }
      }
    }
    onload = init;
    Copy & paste the code below to embed this comment.
  34. It’s broken in Opera, but the one that is used by phpMyAdmin works fine. I’ve had this problem before though, so maybe it’s an Opera quirk.
    Copy & paste the code below to embed this comment.
  35. The code above won’t work because you’re doing
    className+=“class”;
    when it should be
    className+=” class”;
    The space is important because that’s what seperates classes.
    Copy & paste the code below to embed this comment.
  36. Multiple classes are a very powerful feature of HTML/CSS that gets ignored much too often. I’m not sure I see what people propose with contextual selectors and IDs. IDs are used to identify an HTML element *uniquely*, whereas multiple classes are used to “describe” an element. Let’s say I have a table of account titles and balances for the accounts on which I want to do four things (all pretty “standard”): 1) highlight a row by clicking it
    2) have a row’s cells acquire a border on row hover
    3) italicize all a row’s text when the balance is zero; color it red when it’s negative
    4) zebra-stripe the table Can anyone point out a better solution to this than multiple classes? Even if all your users use Moz (and thus can use tr:hover), you’ve still got three separate attributes to assign that affect the presentation.
    Copy & paste the code below to embed this comment.
  37. I just forgot the test for multiple classes. Silly mistake. ” ruler” won’t work if it’s the only class. You first have to test if there’s already a class and then add the space. IE (of course) chokes on class=” anythingWithASpaceFirst”
    Copy & paste the code below to embed this comment.
  38. >>IE (of course) chokes on class=” anythingWithASpaceFirst”
    Well duh. IE is correct here and all other browsers a are wrong. If you’re putting a space first, you’re implying there’s a class before that is an empty string.
    I’m getting really sick of all this IE bashing. IE has better DOM support than Mozilla.
    Copy & paste the code below to embed this comment.
  39. For the record I wasn’t ‘bashing’ IE. It just seemed from your post that you only wanted the space added before the class and I was informing you that it wouldn’t work in IE and also that I had forgotten the multiple class conditional. To me it seems silly in that the leading space shouldn’t just be ignored. For the amount of poorly coded stuff that MSIE lets just slide but addition of a space chokes things up. Quirky.
    Copy & paste the code below to embed this comment.
  40. Huh? Explain that one, if you could….
    Copy & paste the code below to embed this comment.
  41. It is called Excel or Open Office.
    If you want to simulate them online, then you can use multiple classes.
    IMHO an app that ONLY works with Javascript has its space, but is too restrictive for my taste. And the idea of this article is not to replicate Excel in DOM+Javascript. It simply shows a nice visual effect for long tables that can help you reading them easier. Most points here are valid but far off the purpose of this article and the audience it was intended to. We don’t all do web applications and their rules don’t apply everywhere. In a brochureware environment, the use of several classes is rather annoying than helping as contextual selectors are so much easier to redesign, and the content may not be as maintainable for us (we might not have the chance to add 3 classes to one element in our CMS).
    Copy & paste the code below to embed this comment.
  42. All you need to do the very same using solely CSS is: table.class tr:hover {background-color: #ccc;} Just aply the class to the intended table and voila the same effect.
    Copy & paste the code below to embed this comment.
  43. Welcome to the world of reading a forum before posting what was mentioned in a nicer way earlier and to be found true, but belonging in a world where IE is not the most used browser.
    Copy & paste the code below to embed this comment.
  44. Pretty hard to accept any assertion that IE has better DOM support than the other modern browsers (Mozilla, Opera, Safari, Konquerer, etc.), especially considering the fact that MS didn’t even implement full DOM support with the release of IE 6.x. Full DOM support may not come until the release of Logjam (excuse me I meant Longhorn) if at all. But the IE devotees know how to make things work in the proprietary world of MS, and they don’t want to be bothered with making things work for the rest of the world. If they even acknowledge another platform exists.
    Copy & paste the code below to embed this comment.
  45. I am not an IE Devotee.
    I use MyIE2. It uses the IE code engine which I hate, but I like the tabbed browsing, popup blocking, auto scrolling and other featues too much to leave it (and yes I know Mozilla has tabs and popup blocking).
    I do acknowledge other browsers (although I only started embarrisngly recently). Where I learned Javascript I was brought up with the fact that IE was the best and the only other browser was the crappy Netscape. Of course that is wrong.
    IE has better or about the same DOM support as Mozilla. IE has its bugs in the DOM. The main reason IE has better DOM support is because of Mozilla’s stupid event model, where 0=left button. Plus IE stuff is simpler, like currentStyle instead of getComputedStyle.(x, null).propertyValue..
    This is just my opinion. I seem to have forgotten that on the ALA forums, anything that goes against Mozilla is forbidden and considered trolling.
    Copy & paste the code below to embed this comment.
  46. According to spec - tfoot should be before tbody. Excerpt: TFOOT must appear before TBODY within a TABLE definition so that user agents can render the foot before receiving all of the (potentially numerous) rows of data.
    I didn’t know this myself, and only just found out, after having to code a table for the first time in an age…and referred to this tutorial and the spec.
    Copy & paste the code below to embed this comment.
  47. If you had referred to the first entries you’d have seen this was pointed out twice already :-)
    Copy & paste the code below to embed this comment.
  48. I have already encountered this need little trick in the source code of the phpMyAdmin MySql DB administration tool (http://www.phpmyadmin.net/home_page/). They’ve also added a onClick-event to change the background color of a ‘clicked’ row.
    Copy & paste the code below to embed this comment.
  49. I’m sorry, I admit I was rude and that I didn’t read erlier postings, though I can blame the latest to the rush I had at the moment of writing, the former was solely due to my mood at the time and atitude. If anyone felt ofended I truly am sorry and reiterate my apologies to all of you, including and specialy to the author of the article.
    Copy & paste the code below to embed this comment.
  50. Justin: Could you post your zebra tables/table ruler? I would like to check it out. Thanks.
    Copy & paste the code below to embed this comment.
  51. I always use this: <td >text</td>
    Copy & paste the code below to embed this comment.
  52. cute April fools Marleen.
    Copy & paste the code below to embed this comment.
  53. In my case I had alternating background colors on the rows already. I had to make this modification to keep those alternating colors when the mouseout fired. // Declare a public variable to remember the style var oldRowStyle // use this code instead
    trs[j].onmouseover=function(){oldRowStyle = this.className; this.className=‘ruled’;return false}
        trs[j].onmouseout=function(){this.className = oldRowStyle; return false}
    Copy & paste the code below to embed this comment.
  54. This is a great article, implementing this technique on any table is a trivial matter. Other than adding the class name to my table, the lack of HTML altering makes this technique the best I’ve seen for highlighting table rows (with IE-friendly behavior). Is there any way to correct the problem of IE hiding part of my document when the hover action occurs? In IE6, when a row becomes highlighted other text in my page (any <DIV> that comes after the table and is visually lower in the page than the table) becomes hidden.
    I know this is a known issue with IE6, but I know of no fix for it, if there is one at all? Got IE6? See the behavior here:
    http://www.eprojectlog.com/jkf/links/ I used to apply a background image to my <A>‘s
    on hover, but this would cause the same problem. Once I removed the background image on hover from my anchor tags in the document body, all was well. As you can see by the page, the background image still displays on the left nav and right nav bar during mouseover on anchors, just not in the center content area. If I could find a fix for this, I’d love to apply my background image to the central content area’s anchors. Thanks for the great article Chris!
    Copy & paste the code below to embed this comment.
  55. I went to Position Is Everything once again and re-read their article on this subject:
    http://www.positioniseverything.net/explorer/peekaboo.html
    Which discusses some possible work-arounds.
    I found that putting position:relative in my two floats and on the float container fixed the problem partially, but created more visual problems that didn’t justify using this technique. I’m not going to give an absolute width to the content div (another possible fix), so IE6 folks will have to deal with disappearing text.
    I showed this bug to somebody, and they thought it was a *feature*. Hiding content the visitor currently wasn’t viewing… that’s what I’ll call it, A Feature custom for IE6 users!
    Copy & paste the code below to embed this comment.
  56. >>so IE6 folks will have to deal with disappearing text.<<
    Maybe I wasn’t wrong about ALA being an “idiot magnet”.
    April fools!
    Really though, a remark like that is translated to me as:
    “I am too lazy to solve a bug that appears in 95% of the time because that browser sucks”.
    By doing stuff like that you’re punishing the user for using IE6. Why do you want to do that?
    Copy & paste the code below to embed this comment.
  57. I found solution to my problem, however it only introduces new problems. I’m not sure if the trade-off is worth it or not, and with further debugging I may be able to find an adequate solution.
    The whole point of my comment was to get feedback on this issue, possibly others who have seen this and dealt with it accordingly. For me, it’s part of the entire debugging process and I find it very useful. Take these two pages for example.
    Initial page, with disappearing text problem:
    http://eprojectlog.com/jkf/links/ Attempt to fix the issue with IE6:
    http://eprojectlog.com/jkf/links/attempt1.php This second link does correct the problem, but notice the difference in the behavior of the links in the right column, under the section “Donate” and “Mailing List”. Compare the behavior in these sections to the first link.
    Copy & paste the code below to embed this comment.
  58. Through a variation of the Owen hack <http://www.albin.net/CSS/OwenHack.html>, it’s possible to make this work in Opera. Here’s the regular CSS:
    tr.ruled {
      background: #9cf;
      } Then add this:
    head:first-child+body tr.ruled {
      background: #9cf;
      }
    Copy & paste the code below to embed this comment.
  59. any ideas about doing this technique with columns instead of <tr>s, i.e. vertical? the simple way in css with col:hover {...} doesn’t work.
    Copy & paste the code below to embed this comment.
  60. “I still don’t see the point in several classes, when you can add in ID and a contextual selector?” How about using different class token for alternate rows? As you are probably aware, nth-child are not supported in IE. What guys like to do to get that functionality use use a class for alternate rows.
    <tr class=‘hover’>
    <!—tds here—>
    </tr>
    <tr class=‘alternate hover’>
    <!—tds here—>
    </tr>
    <tr class=‘hover’>
    <!—tds here—>
    </tr> Then you can have a combined class selector so you can get a different state for alternate rows. tr.alternate.hover,  { } tr.hover { }
    The javascript required to remove a class is a little trickier. There’s two ways to do it, really. I’d be happy to explain it. Are you interested on seeing an ALA article on working with multiple classNames in JavaScript? Write to ALA. I’ll be happy to provide, if they’ll have me. http://www.alistapart.com/contact/
    Copy & paste the code below to embed this comment.
  61. Want to learn about multiple classes in CSS? Here -> http://www.dhtmlkitchen.com/learn/css/multiclass/
    Copy & paste the code below to embed this comment.
  62. Again, bias against IE is getting really annoying.
    >>IE doesn’t support nth-child
    NO BROWSER DOES!! See my CSS3 Tests site page: http://www.geocities.com/seanmhall2003/css3/pseudo.html
    Stop making IE out to be worse than it is; it’s getting tedious.
    Copy & paste the code below to embed this comment.
  63. Sounds great to me. :) I mean, really, Safari, Mozilla, and Opera users get “punished” so often by buggy code that only works with IE. I’m all for interoperability where feasibly, but if something can work substantially more cleanly with code that basically everything but IE supports, I’m all for it. Having said that, I think if sites are developed to use advanced CSS and “degrade” to IE when necessary (using, alas, browser sniffing), users can take notice of stuff like that and do sometimes find in that an incentive to upgrade. Me, I can’t see why any web developer would want to work without Javascript Console and DOM Inspector. Lifesavers.
    Copy & paste the code below to embed this comment.
  64. http://www.fczbkk.com/js/tablemagic/index.html
    Copy & paste the code below to embed this comment.
  65. There’s clearly mixed opinions about the script from the foregoing comments, but even so I thought this was really nice code. I’m well-versed in regular JS but just a noob at DOM scripting, and this example isn’t just useful for work, it was helpful to learn from. Code that’s easy to understand like this is the sign of someone who really knows what they are doing. Excellent piece, Christian - thanks!
    Copy & paste the code below to embed this comment.
  66. Ian, Haven’t been around Brinkster in some time, been having so much fun with CSS and web standards that I haven’t touched ASP/ASP.NET in a while. Great article indeed, simple approach and very effective. It’s the “Look Ma, I’m not touching HTML!” technique, nothing better.
    Copy & paste the code below to embed this comment.
  67. The same ID “mytable” is used twice in the example on two different tables within the same page. This is not valid. Please correct it.
    Copy & paste the code below to embed this comment.
  68. Of course, this requires inline onmouseover and onmouseout, as opposed to a global onload…however, it does not need to detect DOM type (works in DOM browsers anyways) and can work on any element at all…anywhere. <html>
    <head>
      <title>Untitled</title>
      <style type=“text/css”>
      table, th, td { border : 1px solid #000; border-collapse : collapse; }
            .sectionData { background : #9CF; }
      .sectionDataOn { color : #CCC; background : #333; }
          </style>
    </head>
    <body>
      <table>
      <tr class=“sectionData”  >
      <td>test</td>
      <td>test2</td>
      </tr>
      </table>
    </body>
    </html> Much simpler…
    Copy & paste the code below to embed this comment.
  69. Different yes, not so sure it is any simpler. If anything, this article shows a more advanced method of accomplishing the same thing. Sure makes implementation a snap.
    Copy & paste the code below to embed this comment.
  70. Why not just give every table you want the effect with a custom attribute?
    <table cellspacing=2 hover=”#ffc”>
    ...
    </table>
    The script will search for all tables with the hover attribute and when the user hovers on a TR the background color will be the value of hover. Simple and easy.
    Copy & paste the code below to embed this comment.
  71. i’m getting a Line 37 Char 28 Object expected error. All i did was copy and paste the html, css, and javascript. Thoughts? Thanks,
    Nico
    Copy & paste the code below to embed this comment.
  72. I have just completed a calendar project that needed this very feature. I opted out for the quick’n dirty by doing a document.getElementsByTagName(‘tr’) and then a onmouseover function with this.style.backgroundImage = “url(calendar_pics/yellowbg.gif).
    I used a dithered background image so the background colour of the table row would still show (rows are color-coded).
    A vertical version is triggered when the user clicks on a month table-header (multiple columns can be selected).
    The table was marked-up using the ‘headers’ attribute for table cells so it was fairly routine to highlight cells that matched the id of the table header to the ‘headers’ attribute of the tds. All works in IE, Mozilla , Opera and Safari.
    Copy & paste the code below to embed this comment.
  73. Thanks for participating so much here, I just came back from a quick trip to denmark, hence no answers until now. Nico, without a link to your example we cannot help you, the examples work here, seems you added something wrong. I will set up a live site with some of the changes and fixes shown here, as I cannot reach the ALA hosted site :-) As to some of the “simple” solutions posted here: There are oh so many different ways to reach this same effect, but I consider neither custom attributes nor inline event calls a good solution. Custom attributes just add to more problems for inexperienced (x)HTML scripters. Let’s face it, in the world of generated code by blind editors it is hard enough to find clean code in big projects, a lot of developers don’t even bother scripting the current HTML correctly, when it works in forgivable browsers. Why add a non-standard attribute when ID and class do fine? The same goes for inline event calls, they are simply unclean scripting IMHO. Why should I add to the document for every TR when I can achieve the same in a javascript loop or a custom event call? It just adds unneccessary page weight and makes me dependent on the markup. The script as it is (with some of the aforementioned changes - multiple classes for example) can work with any clean markup, hand coded, from a CMS output or a database call. For all the people adding links here: Please make sure they work, and tell a bit about them, the multiple class one for example was rather useless, a link to the w3c standards would have made more sense. Please keep it on topic. Same goes for IE vs. other browsers, this is pure evangelism and not for here.
    Copy & paste the code below to embed this comment.
  74. When copy/pasting the JS, make sure to remove the line continuation character and move the lines continued text up to its original position. Chris, my sentiments exactly only couldn’t have put it so concise. XHTML strict compliancy is desired, after all.
    Copy & paste the code below to embed this comment.
  75. your suggestion did the trick, many thanks.
    Copy & paste the code below to embed this comment.
  76. Is it possible to use the ruler method but somehow mark certain cells to NOT have any mousover effect?  Say, for instance, a table that has one cell with a rowspan of multiple rows. I don’t want the “spanning” td to change on mouseover, but I would like the ruler to apply to the other td’s in that row.
    Copy & paste the code below to embed this comment.
  77. I apologize for such a simple question. I realize now that all I needed to do was specify a specific class and default css rule to the cell in question and let inheritance (or lack thereof) override any change made by the script.
    Copy & paste the code below to embed this comment.
  78. I chose custom attributes because:
    1. I never ever use DOCTYPES in my pages (so sue me)
    2. Using a class or Id would be “semantically incorrect”. That’s not what classes and IDs are used for, to relay script data. Besides, you can have simpler code and it’s just easier.
    hovercolor=”#eee”
    is only an extra 21 characters towards the total HTML source. I don’t find that really bloating up the code.
    Now using list items for navigation and every single sort of list would be bloating the code, but let’s not get into that.
    Copy & paste the code below to embed this comment.
  79. Sometimes I do wonder why you here Dante. You do seem to hate everything it stands for ;) As to the article, while I understand it presents an alternative method, I’d rather just use the IE-Hover behaviour if I’m going to be using JS to hack around IE’s issues. Seems a more elegant solution to me, rather than re-inventing the wheel as this article does.
    Copy & paste the code below to embed this comment.
  80. darkcryst: agreed it is easier, but not as customisable. As stated here before, there are loads of ways to achieve this, all with their pros and cons. Dante: using no doctype means not writing HTML, you need a doctype to make it a parseable document and avoid quirksmode/standard mode issues. When you don’t use one, you are at the mercy of browsers to guess what they should display, and any browser that has a bit of pride should display your pages as text. You can use custom attributes, and have a valid document, all you need to do is to define them. IMHO too much hassle.
    Copy & paste the code below to embed this comment.
  81. You’re doing such a tremendous job of keeping me entertained across this thread and others. As somebody who takes pride in learning and writing valid, semantically correct XHTML and CSS by hand - after all, it’s the blind editing of the Dreamweavers and Frontpages of the world that only help to get muppets like you online - I find it to be massively offensive that you wade in here with rarely a useful comment to make chastising all of us for our opinions and practices when you don’t even bother to TRY and do things properly yourself! If you are even remotely serious about your role as a web designer/developer/programmer/whatever then valid, clean markup is essential, Doctypes are a requirement not an option, IE is truly awful but must be catered for, the list goes on. Come back and moan at us for being ridiculous for using semantics or wishing IE dea when you start writing XHTML 1.0 Strict - it’s honestly not that difficult.
    Copy & paste the code below to embed this comment.
  82. Chris - I guess that was my point about the alternative method. While I think that it is a tad pointless and inelegant to use this method as its shown in this example, it could be a valuable springboard. Exactly what AListApart should be really, not how-to’s. So.. you know, great. Shakey - wow… venom there. I agree with the general sentiment of “huh?” reguarding Dante, and you are right, XHTML and CSS isn’t that hard, he just choses not to use it right. His loss, long term.
    Copy & paste the code below to embed this comment.
  83. As you have painstakingly told me.
    1. I have never used FrontPage or Dreamweaver or any soft of WYSIWYG editor to create websites. Nor am I a muppet. Notepad is fine for me.
    2. Please don’t berate me for taking an alternative approach to web development. That is really immature.
    3. Just a question about the script - Why return false on the mouseovers? There isn’t a need for it, is there? Enlighten me.
    4. About IE - Most people only use it because they know of no other alternative. I myself display a “Get Firefox” sticker on my site. Eventually I’ll make Firefox my main browser, but MyIE2 is just too good to leave.
    5. I tried to give an idea: using custom attributes. If I remember someone yelled at me for not being open-minded. Couldn’t you at least consider some sort of approach?
    6. Explain to me how my CSS isn’t used right. My CSS would be 100% valid except that the validator has a bug when it encounters -moz-box-sizing: border-box.
    7. XHTML Strict? Been there done that. Tried it, didn’t like it. I like to use Capital tags sometimes.
    8. Doctypes are required? I really don’t mean to be rude, but if you want to use DOCTYPES, go ahead. I might start using them later. I’m in no hurry. It’s my website, and I’ll code as I wish, as long as it works in as many browsers as possible.
    Now, back to the article…
    Copy & paste the code below to embed this comment.
  84. > Doctypes are required? ... as long
    > as it works in as many browsers
    > as possible. http://www.alistapart.com/articles/doctype/ You offer no real excuse for not including the DOCTYPE declaration, it’s a simple copy/paste and does not cause page rendering problems.
    Try the HTML 4.0 Strict DOCTYPE, it’s quite forgiving. Maybe you’re just saying this to get a rise out of us? It seems quite odd to be concerned about XHTML compliancy, heavy CSS usage, yet claim the use of a DOCTYPE declaration is overkill and unnessasary.
    Copy & paste the code below to embed this comment.
  85. Although I do a lot of things to purposely piss hellbent standards people on my site, removing DOCTYPES is not one of them. The real reason goes back to 2003 when I was extremely anti-standards. Since my editor automatically inserts a DOCTPYE (HTML 4 Transitional), the first thing I did when writing a new page was to remove it. “Screw WaSP” I used to say. Now it’s like a habit I can’t break. Always ditch DOCTYPE. I’m trying to break it, but subconsciously I remove it. I don’t really do it to piss anyone off.
    Copy & paste the code below to embed this comment.
  86. But then, I was never into hairbands :-) Pointless discussion here. I don’t care if you have a habit of praying to bricks, just to be different, or type your web sites with 3 toes to see if you can, fact is that this has nothing to do with this article (advocating CSS and DOM and giving away the benefit of standard mode is a contradiction in terms, but we get used to that). The return false was force of habit, I do that for the onclick and onkeypress ones, hence it slipped into the onmouseover. I don’t see any justification for them other than maybe overruling inline onmouseover calls (which may not work on all browsers), so you _can_ happily remove them. They don’t hurt though whereas a missing doctype does.
    Copy & paste the code below to embed this comment.
  87. ... is to use no Javascript at all.  Don’t get me wrong, Javascript is great and all that, but this is a solution that already has an end-to-end CSS implementation. Given a table row as follows: <tr>
      <td>Column 1</td>
      <td>Column 2</td>
      <td>Column 3</td>
    </tr> You can apply CSS as follows: tr:hover td
    {
      background-color: #fcf6ed;
    } you can also get a bit clever and add borders:
    tr:hover td:first-child
    {
      border-left: 1px solid #f90;
    }
    tr:hover td:last-child
    {
      border-right: 1px solid #f90;
    }
    tr:hover td
    {
      border-top: 1px solid #f90;
      border-bottom: 1px solid #f90;
      background-color: #fcf6ed;
    } Caveat: this won’t work for now on IE - it doesn’t support tr:hover or td:first|last-child.  But I’ve got a sneaking suspicion that Dean Edwards’ current endeavor might make that possible.  In any case, it does work on recent mozilla releases and if MS ever decides to make IE standards-compliant, it’ll work there too.  
    Copy & paste the code below to embed this comment.
  88. So this is like the 8th time someone has mentioned the hover pseudo-class that doesn’t work in IE.
    Copy & paste the code below to embed this comment.
  89. Please don’t feed the trolls, they’ll only come back for more.
    Copy & paste the code below to embed this comment.
  90. We should enforce the same rules as the CSS/Email article discussion has: good grammar only.
    Michael has to leave because he used “it’s” where it should read “its”.
    Oh and using a DOCTYPE does cause a bit of harm on IE6. I don’t wanna take any chances.
    Is Michael implying I’m a troll? OMG that is *so* the Exploring Footers article discussion.
    Copy & paste the code below to embed this comment.
  91. Causes harm in IE6? Do explain, because I’ve found IE6 quite evil when I leave one _out_.
    Copy & paste the code below to embed this comment.
  92. Somewhat similar to Jason Karns comments http://www.alistapart.com/discuss/tableruler/8/#c7519 except… I have a table that uses a rowspan covering two rows per item.  Without nesting all the data in a row, how would I be able to accomplish this?  So when you roll over either of these rows they both highlight. ——Example——
    <tr>
      <td rowspan=“2”>Kraftwerk</td>
      <td>Die Mensch-Maschine</td>
    </tr>
    <tr>
      <td>Dopplereffekt</td>
    </tr>
    ——/Example—— Am I asking too much?
    Copy & paste the code below to embed this comment.
  93. Dear Chris,  I believe a few other people asked about multiple classes before I did. Now you’re complaining about my link when I’m just filling in the blanks that you left out. The discussion on multiple classes has a lot of other comments between. Here’s a recap: You said: “I still don’t see the point in several classes, when you can add in ID and a contextual selector?” My reply:
    How about using different class token for alternate rows? You said:
    the multiple class one for example was rather useless You said:
    The script as it is (with some of the aforementioned changes - multiple classes for example) can work with any clean markup, hand coded, from a CMS output or a database call. Now we get the truth out. That’s why I posted the link, and if you’d read the page more thoroughly before making denigrating statements, you’d see there’s a lot of information that the w3c spec doesn’t include. The page links to the HTML and CSS 2 TRs. To be honest, your example is not really useful in and of itsself, though it could be useful in an application. However, thin client application developers should be able to do this stuff in his sleep.
    Copy & paste the code below to embed this comment.
  94. I am still a novice at this and a lot of the posts above confused me . However, I wanted to say a massive thanks to Chris, I have just put the ruler on my site and I think its looks great. Thanks Ant
    Copy & paste the code below to embed this comment.
  95. Hey guys; Great idea here; I have modified the code to stop it clobbering existing classes on the TRs - it still clobbers the onmouseover/out though.  Thought someone might like this: function tableruler()
    {
    if (document.getElementById && document.createTextNode)
    {
      var tables=document.getElementsByTagName(‘table’);
      for (var i=0;i<tables.length;i++)
      {
    if(tables.className.indexOf(tableRuleClass) >= 0)
    {
    var trs=tables.getElementsByTagName('tr');
    for(var j=0;j<trs.length;j++)
    {
    if(trs[j][removed].nodeName=='TBODY')
    {
    trs[j].
    {
    if (this.className.indexOf(ruledClass) == -1)
    {
    this.className=this.className + ruledClass;
    }
        return false;
        }
        trs[j].
        {
        if (this.className.indexOf(ruledClass) >= 0)
        {
          this.className = this.className.substring(0, this.className.length - ruledClass.length);
        }
        return false;
        }
        }
      }
      }
      }
    }
    }
    Copy & paste the code below to embed this comment.
  96. <style>
    table.ruler{
    border:1px solid black;
    width:300px;
    font-family:Tahoma,Verdana,Arial,Helvetica;
    }
    th{
    background-color:#F2F2F2;
    text-align:left;
    padding-left:3px;
    }
    td{
    border-top:1px solid black;
    padding-left:5px;
    }
    tr.trover{
    background-color:#CECEDE;
    cursor:hand; cursor:pointer;
    color:#2E2E3E;
    }
    tr.down{
    background-color:#FFFFAE;
    cursor:hand; cursor:pointer;
    }
    </style>
    [removed]
    window.onload=function(){
    if(document.getElementById&&document;.createTextNode){
      var taules=document.getElementsByTagName(“table”);
      for(var i=0;i<taules.length;i++){
    var e=taules;
    if(e.className=="ruler"){
    var trs=e.getElementsByTagName("tr");
    for(var j=0;j<trs.length;j++){
    if(trs[j].firstChild.tagName.toLowerCase()!="th"){
    trs[j].clicat=false;
    trs[j].
    this.className="trover";
    return false;
    }
        trs[j].
        if(this.clicat==false){
    this.className="";
    return false;
    }else{
    this.className="down";
    return false
    }
        }
        trs[j].
        this.clicat=!this.clicat;
        this.className=“down”;
        return false;
        }
        }
      }
      }
      }
    }
    }
    [removed]
    <table cellpadding=“0” cellspacing=“0” class=“ruler”>
    <tr><th>NUM</th><th>NOMBRE</th><th>APELLIDO</th></tr>
    <tr><td>1.</td><td>Marc</td><td>Palau</td></tr>
    <tr><td>2.</td><td>Marc</td><td>Palau</td></tr>
    <tr><td>3.</td><td>Marc</td><td>Palau</td></tr>
    <tr><td>4.</td><td>Marc</td><td>Palau</td></tr>
    </table>
    Copy & paste the code below to embed this comment.
  97. now, and took in all the questions about multi classes. http://www.onlinetools.org/tools/domtableenhance.php is the result, enjoy. Still no click event, but I really think things that are no links, should not be clickable.
    Copy & paste the code below to embed this comment.