IE7 table cells made invisible by CSS cannot be made visible by later class changes (??)
Asked Answered
V

2

5

Here are two test files:

http://gutfullofbeer.net/good-table.html

http://gutfullofbeer.net/bad-table.html

The markup on those two page is all almost the same. There's a table with two columns. The <th> and <td> elements of one column (the second one) are all given the class "junk".

In the "good" page, when you load it you'll see a checkbox unchecked at the top. If you check the checkbox, the second column should disappear. If you uncheck it, the second column comes back. In the "bad" page, the checkbox starts out checked. Unchecking it has no effect in IE7, though it works in other browsers that are not possessed by fundamental evil.

The checkbox is hooked to a little Javascript routine that just adds or removes the class "compact" from the <table> tag. There's a stylesheet that includes this:

table.compact th.junk, table.compact td.junk {
  display: none;
}

Thus what should happen is what happens on the "good" page. However, it appears that in IE7 (maybe 6 too) if table elements start out such that when initially rendered they're styled to be invisible, they'll never be seen, regardless of subsequent changes to the DOM that would bring new style rules into effect and leave them visible. (This appears be an issue with <table> parts in particular; I'm using the same mechanism elsewhere with other elements and they all work fine.)

So, the question is: does anybody know of some hack — however revolting — that can be used to get around this idiotic behavior? Obviously I could try and arrange for IE7 to start its views with the relevant toggle control set so that the table cells are visible, but in my case this happens around a table that's produced as an AJAX response, and so it'd be a big mess I'd rather avoid. (The table is really a table, too; it's a display of tabular information, not a layout hack.)

I've googled around and not found anything, which shouldn't be surprising if you consider how many hits you get from "IE7 layout bug" searches.

Veii answered 19/6, 2010 at 21:11 Comment(2)
Perhaps you can change the table-layout, let a DOM/CSS refresh occur, and set it back...Nasal
@pst that's my current best idea - I can have the AJAX-loaded content include an IE7-only script tag that sets the control such that everything's visible, and also launches a timeout so that 1/4 second later it gets reset to what it's really supposed to be (plus I trigger my Javascript stuff). Ugly but it works. I'm just curious about whether there's some weird CSS hack to make it a little less insane. Thanks though!Veii
K
2

I don't have IE 7 installed, but it was the same issue with IE 6. Here's what I did to fix it:

$(function() {
  $('#click').click(function() {
    $(".compact th+th,.compact td+td").toggleClass('junk',this.checked);
  });
});

The problem was with you selector. Toggling on compact would not add visibility to junk.

Kephart answered 19/6, 2010 at 21:44 Comment(2)
I don't think that's true. In the page that works, the CSS is exactly the same, and you can toggle from visible to invisible and back again all you like. It's kind-of fun. However, when things start off such that the content is hidden, then things do not work.Veii
Well, obviously IE 6 and IE 7 has some issues. Anyway, My code above works in IE 6 and FF.Kephart
G
2

This is a rendering bug. IE6/7 doesn't use a proper table display model. Unfortunately I can't recall a specific name/label for this particular bug and I can't seem to find authorative resources confirming this.

At least, I found 2 CSS ways to fix this.

  1. The easiest, use visibility: hidden; instead of display: none;. Unfortunately this doesn't work nicely if you have more columns after the to-be-toggled column or have a table border. It still leaves a space. Adding position: absolute; to .junk fixes this issue in FF, but you fall back to the same rendering problem in IE.

  2. A hack which abuses the IE's erroneous ability to apply styles for <col>.

    <!DOCTYPE html>
    <html>
        <head>
            <script src="http://code.jquery.com/jquery-latest.min.js"></script>
            <script>
                $(function() {
                    $('#click').click(function() {
                        $('table').toggleClass('compact', this.checked);
                    });
                });
            </script>
            <style>
                table.compact .junk { display: none; }
            </style>
            <!--[if lte IE 7]>
            <style>
                table.compact .junk { display: block; }
                table.compact col.junk { display: none; }
            </style>
            <![endif]-->
        </head>
        <body>
            <input type="checkbox" id="click" checked>
            <table class="compact">
                <col />
                <col class="junk" />
                <tr>
                    <th>Hello</th>
                    <th class="junk">World</th>
                </tr>
                <tr>
                    <td>Foo</td>
                    <td class="junk">Bar</td>
                </tr>
                <tr>
                    <td>Foo</td>
                    <td class="junk">Bar</td>
                </tr>
            </table>
        </body>
    </html>
    

Alternatively, you can also just toggle the elements of actual interest in jQuery:

$(function() {
    $('#click').click(function() {
        $('table.compact .junk').toggle(!this.checked);
    });
});
Gorcock answered 20/6, 2010 at 1:35 Comment(2)
I played around a bit more with Pointy's code and came to the same conclusion... changing display: none; to visibility:hidden; makes it work. Good post (+1).Kephart
Well the whole point is to keep the table width under control, so "hidden" won't really do it. However, I will definitely try that "col" thing; I've never seen it before! Thanks @BalusC!! You are like some sort of browser ninjaVeii

© 2022 - 2024 — McMap. All rights reserved.