Re: 質問:IE でmain 要素のwidth,height 指定が無視されるのはなぜでしょうか?

3,374 views
Skip to first unread message

はるピヨ

unread,
Jul 14, 2015, 12:18:31 PM7/14/15
to html5-dev...@googlegroups.com
追記です。
float を指定すると表示されるようになりました。

        main {
            width: 800px;
            height: 600px;
            background-color: Blue;
            float: left;
        }

謎です...

2015年7月14日 19:06 はるピヨ <haru...@gmail.com>:
こんにちは。harupiyo と申します。
初めて投稿させていただきます。

IE11 では、main 要素へのwidth, height 指定が無視されてしまうようで、その理由を知りたいです。

ソースを貼り付けます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        /* IE でwidth,height が無視されるのはなぜ? */
        main {
            width: 800px;
            height: 600px;
            background-color: Blue;
        }
    </style>
</head>
<body>
<main></main>
</body>
</html>

Firefox, Chrome では青色のボックスが出てきますが、IE では出てきません。
html5shiv を読み込ませても同じ動きでした。

ご存知の方いらっしゃいましたらどうぞよろしくお願いします。

坂巻 翔大郎

unread,
Jul 14, 2015, 12:20:42 PM7/14/15
to html5-dev...@googlegroups.com
main要素に display: block; を指定してください

2015年7月14日 19:32 はるピヨ <haru...@gmail.com>:

--
このメールは Google グループのグループ「html5j」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには html5-developer...@googlegroups.com にメールを送信してください。
このグループに投稿するには html5-dev...@googlegroups.com にメールを送信してください。
http://groups.google.com/group/html5-developers-jp からこのグループにアクセスしてください。
その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。

Toru Yoshikawa

unread,
Jul 14, 2015, 12:22:41 PM7/14/15
to html5-developers-jp

html5jの吉川です。

質問への回答ではなく、お詫びです。

メールの送信を許可する際に誤って1通目を削除してしまいました…。1通目の内容はメールの引用部分を読んでいただければと…

#初回投稿の場合はスパム防止のため承認が必要でした

モバイルより送信

2015/07/15 午前1:18 "はるピヨ" <haru...@gmail.com>:

main.coeurl

unread,
Jul 14, 2015, 5:19:57 PM7/14/15
to html5-dev...@googlegroups.com
debiru (@debiru) です。

良い質問ですね。
以下、項目を区切って回答を付けてみます。

■(1) width, height 指定が無視されるのは何故か。
width 指定が効くのは「非置換インライン(span など)、テーブル列(col)、テーブル列グループ (colgroup)」以外の種類でレンダリングされる要素です。
height 指定が効くのは「非置換インライン(span など)、テーブル行(tr)、テーブル行グループ(tbody など)」以外の種類でレンダリングされる要素です。

つまり、img や input などの置換インラインや、div, table など、高さと幅を指定できそうな要素にしか指定が効きません。ただし、レンダリング時のレイアウトに関する要素の種類は要素ごとに決まっているわけではなく、CSS の display プロパティで変更ができます。div には効くと言っても display: inline が指定された div には width 指定などは効きません(無視されます)。

また、レンダリングされない要素にも効きません(display: none の状態では幅と高さが確保されないのもこのためです)。余談ですが、これはしばしばSNSサービス等の埋め込みボタンなどを非表示領域において予め挿入する際に問題を起こします。

https://developer.mozilla.org/en-US/docs/Web/CSS/width
https://developer.mozilla.org/en/docs/Web/CSS/height

■(2) main 要素は display: block ではないのか。
HTML5 で定義された新しい要素には、仕様として inline として振る舞うものもあれば block として振る舞うものもあります。例えば time, mark, ruby(ルビ)はインライン要素のように振る舞い、article, section, main などはブロック要素のように振る舞います。

「ブロック要素のように振る舞う」のはブラウザがそれらの要素に対して、デフォルトスタイルとして display: block を適用しているためです。Firefox や Chrome では main 要素に対して display: block が適用されています。

■(3) IE11 で main 要素に width や height が効かないのは何故か。
IE11 で main 要素に width, height を指定してもその指定が効かないのは、IE11 が main 要素に対応していないからです。IE9 から徐々に HTML5 に対応している事実からすれば、これは直感に反するかもしれません。

IE11 は2013年11月7日にリリースされました。
http://blogs.msdn.com/b/ie/archive/2013/11/07/ie11-for-windows-7-globally-available-for-consumers-and-businesses.aspx

しかし main 要素には対応していません。
https://connect.microsoft.com/IE/feedback/details/893334/html5-main-element-not-supported

とはいっても main 要素が仕様に追加されたのは、他の要素に比べて後だったので仕方のないことでもあります。
https://hyper-text.org/archives/2013/04/add_main_html5_cr.shtml

■(4) 未実装の要素はどのように振る舞うのか。
IE11 にとっての main 要素、Firefox や Chrome にとっての未知の要素(例えば存在しない hoge 要素)は、インライン要素のように振る舞います。これは display プロパティの初期値が inline であることに依ります。

https://developer.mozilla.org/ja/docs/Web/CSS/display

Firefox や Chrome で <div>foo<hoge>bar</hoge>baz</div> のようなマークアップをレンダリングさせるとどうなるでしょうか。IE11 にとっての main 要素と同じように振る舞うはずです。

https://jsfiddle.net/wjrcd21m/

■(5) IE11 でも main 要素を float: left したら効いたのは何故か。
float: left または float: right によって floating element として扱われる場合、そのレンダリング時のレイアウトに関する要素の種類は inline の場合は block に変更されます。float プロパティを指定したことで間接的にレイアウトが block 扱いになったため、幅や高さが指定できる状態になったということです。

https://developer.mozilla.org/ja/docs/Web/CSS/float

余談ですが、IE6 で float と同じ方向に margin を指定すると margin 値が倍になるというバグがありました。このバグに対する解決策として、float を指定する要素に display: inline を指定するという方法がありましたが、IE6 以外のモダンブラウザに display: inline 指定の影響がなかったのは、この float によるレイアウトの暗黙的な変更がされていたためです。

■(6) ところで HTML5 ではインライン要素やブロック要素というものは無くなったのでは。
その通りです。HTML 4.01 までは要素が「ブロック要素」か「インライン要素」か「それ以外(例えば head 要素など)」か、という分類を行っていました。HTML5 ではコンテントモデル(コンテンツモデル)という概念で要素を分類しています。ブロックかインラインかという分類は視覚上のものでしたが、論理的な名称の分類を主として分類しようということです。

しかし、レンダリング時のレイアウトに関する要素の種類としての inline や block という概念は残っています。これは display プロパティによって決められるものです。このレイアウト情報を指して HTML5 でも「インライン要素」や「ブロック要素」という表現が出ることがあります(あるいは HTML 4.01 以前の概念を引き継いで説明する場合でしょうか)。

http://www.html5.jp/tag/models/
http://www.tohoho-web.com/html/memo/html5.htm

この回答を書いていて見つけましたが、2009年7月にコンテンツモデルおよび同様の問題について、このメーリングリストにトピックがありましたね。興味があればご覧ください。
https://groups.google.com/forum/#!topic/html5-developers-jp/XeT3DfkCStI

■(7) HTML5 の新要素を document.createElement するのは何なのか。
個々の要素のレイアウト情報とは別に、未知の要素について、DOM ツリー(要素の入れ子の状態)がどうなるのかという問題がありました。例えば、<div>A<hoge>B<p>C</p>D</hoge>E</div> というマークアップがあったとき、どのような DOM ツリーが構築されるのかという問題です。

https://jsfiddle.net/q8L7bdug/

これが、書いた通りの入れ子関係になればよいのですが、ブラウザが「hoge の中には p は入れられない」と判定すれば、<div>A<hoge>B</hoge><p>C</p></hoge>E</div> と、p 要素の手前で hoge が閉じられてしまう(DOM として親子でなく兄弟になる)ことになります。そんな判定をしなければいいと思うかもしれませんが、この判定があるお陰で HTML 4.01 や HTML5 では要素終了タグの省略ができるのです。XML が好きな人は「そんな判定はするな」と思うかもしれません。実際、<p>X<div>Y</div>Z</p> とマークアップすれば、大抵のブラウザは <p>X</p><div>Y</div>Z</p> に相当する DOM ツリーを構築するでしょう。

https://jsfiddle.net/10yk5bf5/

未知の要素の中身に任意の要素を入れられないのは IE8 以下や Firefox 2 でした。他のモダンブラウザでは、未知の要素には任意の要素を入れることができます(記述した通りに DOM ツリーが構築されます)。

IE8 以下の場合は、未知の要素の DOM ツリーが親子にならずに兄弟になるわけでもなく、先ほどの例であれば <div>A<hoge />B<p>C</p>D</hoge/>E</div> のように、未知の要素の開始タグと終了タグがそれぞれ空要素のように扱われ、未知の要素に対するスタイルが全く効きません。DOM ツリーがおかしくなることに加え、未知の要素が無視されると解釈してよさそうです。

この DOM ツリーがおかしくなる問題(および IE では未知の要素が無視される問題)に対して、document.createElement で未知の要素を作ると解決するため、この方法が採られるようになりました。

http://www.html5.jp/html5doctor/how-to-get-html5-working-in-ie-and-firefox-2.html
http://osaka.cssnite.jp/vol20/slide/02_hatano.pdf#20

■(8) html5shiv を読み込んでも IE11 で解決しなかったのは何故か。
html5shiv では、HTML5 の新要素に対して document.createElement をして、かつブロック要素として振る舞うべき要素に display: block を指定します。これを行えば IE6 や IE7, IE8 でも HTML5 でマークアップされたページをある程度期待通りに表示させることができます。

しかし html5shiv のソースコードを見てみると、display: block を指定する箇所では、直前に条件分岐が行われています。
> if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS)
IE11 ではこの if 文を通らずに display: block が指定されないのかもしれません(手元に環境がないので未確認です)。あるいは IE11 ではそもそも html5shiv を読み込んでいなかった(コンディショナルコメントで IE9 未満にしか読み込ませていなかった)のかもしれません。

https://github.com/aFarkas/html5shiv/blob/3.7.2/src/html5shiv.js#L231
https://github.com/aFarkas/html5shiv/

■(9) まとめ
現在の IE の最新版 IE11 であっても main 要素をサポートしていません。このため main 要素を使う場合は CSS で main 要素に対して display: block を指定してブロック要素として振る舞わせる必要があります。DOM ツリーの問題は、IE については IE8 以前に限った問題なので、IE11 に対して document.createElement を行う必要はありません。(未知の要素には任意の要素を入れることができます。)

「main要素に display: block; を指定してください」と回答されているのはこういう訳です。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/main

■ 最後に
私の回答内容は全てが正しいとは限りません。鵜呑みにせず参考にしていただければ幸いです。
誤りや不適切な点、補足などがあればツッコミをお願いします。

長々と失礼しました。


2015年7月14日 19:32 はるピヨ <haru...@gmail.com>:
追記です。

harupiyo

unread,
Jul 17, 2015, 4:15:35 AM7/17/15
to html5-dev...@googlegroups.com
吉川様、さかまき様、debiru様、ありがとうございました。

疑問は解消しました。
対処方法だけでなく、その背景の解説までいただけたことがとても役に立ち、嬉しかったです。
お礼申し上げます。


調査したことがあるので先に記載します。


> ■(8) html5shiv を読み込んでも IE11 で解決しなかったのは何故か。
> if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS)
> IE11 ではこの if 文を通らずに display: block が指定されないのかもしれません(手元に環境がないので未確認です)。

IE10 ではhtml5shiv を読みこめばmain がdisplay:block として表示されました。
IE11 では、ご指摘いただいた行の条件のそれぞれが、
    html5.shivCSS: true
    supportsHtml5Styles: true
    data.hasCSS: undefine
つまり
if( true && ! true && ! undefined)

if( false )
となり、main にdisplay:block 指定が追加されていませんでした。

IE10 ではできていたものが、IE11 ではできていない、ということはhtml5shiv 側に問題がありそうだという印象を受けました。


さて、以下からはそれぞれの記事への感想になります。


> IE11 が main 要素に対応していないからです。IE9 から徐々に HTML5 に対応している事実からすれば、これは直感に反するかもしれません。

そうなんです!やられました。


> ■(5) IE11 でも main 要素を float: left したら効いたのは何故か。
> float: left または float: right によって floating element として扱われる場合、そのレンダリング時のレイアウトに関する要素の種類は inline の場合は block に変更されます。float プロパティを指定したことで間接的にレイアウトが block 扱いになったため、幅や高さが指定できる状態になったということです。

この結果から、ひるがえって、main はblock 扱いされていないのは何故だろう?と思っていましたが、IE11 ではmain は未対応、よってデフォルトの display:inline が効いている、とわかり納得です。

> コンテンツモデルおよび同様の問題について、このメーリングリストにトピックがありましたね。
> https://groups.google.com/forum/#!topic/html5-developers-jp/XeT3DfkCStI

この内容の、以下の部分が意外で印象に残りました。

>>    各要素のdisplayスタイルがどうか、ということは(少なくとも今のところ)
>>     HTML5の仕様として文書化・資料提供されていない
>>     ↑HTML4でもinformative(つまり参考資料)としてしか提供されていない
>>    ●現在section等のHTML5新要素は、各ブラウザでデフォルトスタイルが
>>     与えられていない
>>     →「未知の要素の場合は内容をそのまま出力する」という仕様に沿って
>>      普通に表示はできる。

>>    なお、HTML 4 の「ブロックレベル要素」「インライン要素」と
>>    CSS 2.1 の「ブロックレベル要素」「インラインレベル要素」とは
>>    定義が異なります。


これは知りませんでした。驚きでした。

>    実際、<p>X<div>Y</div>Z</p> とマークアップすれば、大抵のブラウザは <p>X</p><div>Y</div>Z</p> に相当する DOM ツリーを構築するでしょう。
>    https://jsfiddle.net/10yk5bf5/




> ■(9) まとめ
> 現在の IE の最新版 IE11 であっても main 要素をサポートしていません。このため main 要素を使う場合は CSS で main 要素に対して display: block を指定してブロック要素として振る舞わせる必要があります。
> 「main要素に display: block; を指定してください」と回答されているのはこういう訳です。

ありがとうございました。


2015年7月15日水曜日 6時19分57秒 UTC+9 debiru:
Reply all
Reply to author
Forward
0 new messages