开发者

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

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.


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.


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);
    });
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜