border-collapse: collapseの指定

[統計] HTMLからXHTMLへの移行を進めていますか?



0   名前: あきら : 2007/03/01(木) 00:37  ID:jWdvXKzr sub-99
rowspanのあるtableで、tdタグに対してborder-collapse: collapseの指定をすると、
Firefox2.0では罫線の一部が表示されないという問題が起きます。
https://bugzilla.mozilla.org/show_bug.cgi?id=244135

なので、head部のstyleタグ内では、border-collapse: separateで指定しておいて、
javascriptで時間差を付けてborder-collapse: collapseの設定をしたいのですが、
どのように記述したらよいかわかりません。

<input type=button onclick="document.getElementsByTagName('td').style='border-collapse:collapse'">

こんなことをしてみましたが、何も起きませんでした。

tdタグ全体に対して、あるいは、特定のクラスに対して
border-collapse: collapse
の設定をする方法をご存じの方、教えてください。
よろしくお願いします。

1   名前: 匿名 : 2007/03/01(木) 00:37  ID:9jO6XtAy sub-kJ
Gecko、Opera、Safari:
if (document.implementation &&
    document.implementation.hasFeature ('HTML', '2.0') &&
    document.implementation.hasFeature ('StylsSheets', '2.0') &&
) {
    var element = document.getElementsByTagname ('head')[0]
                          .appendChild (document.createElement ('link'));
    element.rel = 'stylesheet';
    element.type = 'text/css';
    element.href = 'data:text/css,td{border-collapse:collapse;}';
}


Gecko、Opera:
if (document.implementation &&
    document.implementation.hasFeature ('HTML', '2.0') &&
    document.implementation.hasFeature ('StylsSheets', '2.0') &&
    document.implementation.hasFeature ('CSS', '2.0')
) {
    var element = document.getElementsByTagname ('head')[0]
                          .appendChild (document.createElement ('style'));
    element.type = 'text/css';
    element.sheet.insertRule ('td { border-collapse: collapse; }', 0);
}

IE:
if (typeof document.createStyleSheet != 'undefined') {
    document.createStyleSheet ()
            .addRule ('td', 'border-collapse: collapse', 0);
}

# 揚げ足だが「タグ」にはスタイル指定できないよ。

2   名前: 匿名 : 2007/03/01(木) 00:37  ID:9jO6XtAy sub-kJ
訂正:getElementsByTagname → getElementsByTagName

3   名前: 匿名 : 2007/03/01(木) 00:37  ID:9jO6XtAy sub-kJ
ついでに。もし text/html ではなく application/xhtml+xml な XHTML ならば:

Gecko:
if (document.implementation &&
    document.implementation.hasFeature ('XML', '2.0')
) {
    document.insertBefore (
        document.createProcessingInstruction (
            'xml-stylesheet',
            'type="text/css" href="data:text/css,td{border-collapse:collapse;}"'
        ),
        document.documentElement
    );
}

4   名前: あきら : 2007/03/01(木) 00:37  ID:jWdvXKzr sub-99
匿名さま、ありがとうございました。
教えていただいたコードを使ってみましたが、症状は改善されませんでした。
タグ全体に対して、という表現は、

<style>
tagname {
}
</style>

に相当する指定をjavascriptですることを指していました。用語がわからず失礼いたしました。
なぜjavascriptで記述したかったかというと、通常のstyleタグ内での指定では、Firefoxの
バグにより、borderが表示されなくなるため、ブラウザがいったん描画を終えてからcollapseの
指定をすることで、再描画してくれないかと思ったからでした。うまくいかなかったようです。

5   名前: 匿名 : 2007/03/01(木) 00:37  ID:dNetjyhh sub-kJ
Firefox に対しては separate で、それ以外のブラウザには collapse で、という意味かと思ってたけど。

> 再描画してくれないかと思ったから

Bugzilla に、描画のタイミングで改善できるというコメントはありましたっけ。



ついでに、>>1 の if (...) の最後の && は不要(エラー)。失礼。

あと、タグに関して蛇足ながら、
・タグというのは < から > まで(<!、<? を除く)。
・タグ内に書けるのは属性のみ(<style type="text/css">)。
・要素は開始タグ(<style>)と終了タグ(</style>)によってマークアップされる。
・要素は内容を持ちうる(<style>style 要素の内容</style>)。
・CSS セレクタに使用するのは要素名。

・タグ名は混乱して使用されてるかも(QName を含んだり含まなかったり)。

6   名前: あきら : 2007/03/01(木) 00:37  ID:jWdvXKzr sub-99
返信ありがとうございます。

> Bugzilla に、描画のタイミングで改善できるというコメントはありましたっけ。

Ondra Zizkaさんの#13のコメントで、
As I mentioned before, Gecko re-renders the table properly when the DOM is
completely loaded. So we can force it to re-render the tables by unsetting and
setting the border-collapse: collapse; .
とありました。DOMが完全にロードされていればGeckoはテーブルを適切に再描画する、
と訳しました。そこで、後からjavascriptでborder-collapseの指定をすればうまくいく
かなと思ったのです(素人判断です)。

Ondra Zizkaさんのサンプルコードは、クラスを追加して削除して、という処理をしている
ようですが、結局何をしているかわかりません…。それに、このコードを実装しても、
症状が改善されませんでした。バグだからしょうがないといえばそれまでですが、現状でも
確実にborderを描画する方法があればいいと思い質問しました。

> あと、タグに関して蛇足ながら、
> ・タグというのは < から > まで(<!、<? を除く)。
> ・CSS セレクタに使用するのは要素名。

確かにそうですね。幼稚な表現をしてしまいました。

7   名前: 匿名 : 2007/03/01(木) 00:37  ID:dNetjyhh sub-kJ
# ご承知とは思いつつ、場所柄「タグ」の使い方には敏感になってしまうので(特に DOM が絡むと、データ層とシリアライズ層との混同を避けたい)。すみません。
# なお、border-collapse が指定可能なのは table/inline-table 要素のみなので、>>1-3 で td 要素に指定したのは間違い。すみません。

>>6
把握しました。Bugzilla のテストケースで Firefox 1.5 でも現象の発生を確認。Ondra Zizka(#13)氏の再レンダリング法で改善されうることを確認。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<title>TEST</title>

<style type="text/css">
table { border-collapse: collapse; }
table, tr, td { border: 1px solid #999; }
</style>

<!-- rowspan="4" のセルが存在し、かつレイアウト計測すると確実に発生 -->
<table>
<tbody>
<tr><td rowspan="4">td[@rowspan="4"]</td><td>text</td><td>text</td><td>text</td></tr>
<tr><td>text</td><td>text</td><td>text</td></tr>
<tr><td>text</td><td>text</td><td>text
    <script type="application/javascript">document.body.offsetHeight</script></td></tr>
<tr><td>text</td><td>text</td><td>text</td></tr>
</tbody>
</table>

<script type="application/javascript; version=1.5">

// 一旦 table { border-collapse: separate; } を与え、すぐ削除
if (document.implementation &&
    document.implementation.hasFeature ('HTML', '2.0') &&
    document.implementation.hasFeature ('StyleSheets', '2.0') &&
    document.implementation.hasFeature ('CSS', '2.0')
) {
    var element = document.getElementsByTagName ('head')[0]
                          .appendChild (document.createElement ('style'));
    element.type = 'text/css';
    element.sheet.insertRule ('table { border-collapse: separate; }', 0);
    element.parentNode.removeChild (element);
}
</script>

もしうまくいかなければ、setTimeout で削除のタイミングをずらす。

8   名前: あきら : 2007/03/01(木) 00:37  ID:jWdvXKzr sub-99
ありがとうございます。
結果からいうと、教えていただいたコードで改善されました。すべての場合においてか
どうかはわかりませんが…。
ただ、やはり最後の removeChild() を遅らせて実行させる必要がありました。

window.setTimeout('element.parentNode.removeChild (element)', 200);

が一番よいようでした。これ以上大きくすると、一瞬separateなテーブルに戻るのが見えて
しまいました。これより小さいと、効果がないようでした。テーブルが大きいので、初期
描画に時間がかかっているのかもしれません。

# Bugzillaも、同様にsetTimeoutをかませばうまくいったのかもしれません。

これで様子を見させていただきます。大変ありがとうございました。

一覧へ戻る