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/widthhttps://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/displayFirefox や 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.htmlhttp://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#L231https://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■ 最後に
私の回答内容は全てが正しいとは限りません。鵜呑みにせず参考にしていただければ幸いです。
誤りや不適切な点、補足などがあればツッコミをお願いします。
長々と失礼しました。