目次
rowspan指定が他に影響してしまう謎動作
どういうことが起きたか?を簡単に書きます。
rowspan="5"の2つの列の間に、rowspan指定をしない行を挟み込むようなテーブルがあったと思ってください。。
HTMLはこんな感じです。
実際はもっと複雑ですけど、説明用にごく単純なものにしています。
<html> <head> <link rel="stylesheet" type="text/css" href="./my.css" media="all" /> </head> <body> <table style="border: solid 1px"> <tbody> <tr> <th>A</th> <th>B</th> <th valign="middle">C</th> </tr> <tr> <td rowspan="5" valign="middle">5行にまたがる</td> <td valign="middle">1行ずつ表示したい★★★★★★★</td> <td rowspan="5" style="height: 100px"> <textarea style="width: 100%; height: 100%"> TEXTAREAを表示</textarea> </td> </tr> <tr> <td valign="middle">2行目。</td> </tr> <tr> <td valign="middle" class="">3行目</td> </tr> <tr> <td valign="middle" class="">4行目</td> </tr> <tr> <td valign="middle" class="">5行目</td> </tr> </tbody> </table> </body> </html>
ここで読み込んでいるCSS(my.css)も、テーブル要素のごく簡単な設定をしているだけです。
table, tbody, tfoot, thead, tr, th, td { margin: 3px; padding: 3px; border: solid 1px; }
普通に考えて、おかしくなる要素はありません。
ある日突然レイアウトが崩れた?!
それなのに・・です。
いきなり、こんな風にレイアウトが崩れて表示するようになりました。
HTMLは変更していません。
見たところ、 rowspan="5" しているTDタグの「valign="middle"」の指定がきかなくなっているだけでなく、A列、C列のrowspanが他の列(B列)の1行目にだけ影響してしまっているように見えます。
しかも。
奇妙なことに、C列から<textarea>を除くと、もとに戻るのです。
最初にこの現象を見たときは、正直、途方にくれました。
vertical-align: baseline;指定のせいだった
実際は上記のような単純なHTMLでもCSSでもなく、全部で数千行くらいあるものだったので、原因を見つけるのに時間は相当かかったのですけど・・。
なんとか原因をつきとめることはできました。
いつもながら、わかってしまえば、原因は単純です。
誰かが「my.css」の定義の一部を以下のように修正していたのです。
table, tbody, tfoot, thead, tr, th, td { margin: 3px; padding: 3px; border: solid 1px; vertical-align: baseline; }
そう。
table関連要素の共通設定に
vertical-align: baseline;
が追加されていたのです。
これは、要素のベースラインを親要素のベースラインに揃えるというものなので、table関連のような階層関係(まあ、親子関係といえなくもない)のものに指定すると、一見よさげに見えるのですけれど・・実は落とし穴がありました。
こちらに、そのあたりが、さらっと書いてあります。
引用すると。
baseline
要素のベースラインを親要素のベースラインに揃えます。 <textarea> のような、一部の 置換要素 のベースラインは HTML 仕様で未定義であり、このため、このキーワードの挙動はブラウザにより異なるかもしれません。
ということです。
つまり、vertical-align: baseline;の指定をしたTDタグ内とかに、<textarea>のように「ベースラインがHTML仕様で未定義」な要素を置くと、何がおきても知らないよ・・というわけです。
まさしく、今回おきたこと・・まんまじゃないですか。
教訓:vertical-align: baseline;を安易に使わない
今回の問題は、vertical-align: baseline;の記述をCSSから消したらおさまりました。
なのですけど。
普通に使ってて問題なさげに見えても、<textarea>を配置したとたんに、周囲が崩れていく・・という挙動はやばすぎますよね。
時限爆弾みたいなものです。
しかも、今回、たまたま<table>の<td>タグでしたが、たぶん<div>とかでも起こりえる話なので、ネストしたDIVタグで複雑なレイアウトなんか組んでた日には、何がおきるのかなんて、たぶん誰にもわかりません。
今回のように、<textarea>の配置された箇所ではなく、隣の要素が崩れたりすると、原因がどこにあるのかの当たりをつけるだけでも、なかなか大変な作業になります。
絶対、避けるべし!!
自分はそう思い知りました。
だから、教訓です。
共通利用のCSSで「vertical-align: baseline;」は使わないように徹底すべし!!
どうしても使いたいなら、ヤバさをちゃんと認識したうえで、<textarea>禁止にするか、局所的なStyleで使うようにするとか・・したほうがいいみたいです。
ではでは。