• ベストアンサー

入れ子にしたfloatのclear

初めてこちらを利用させていただきます。 CSSで縦3段、例えば上から『HEADER』、『MAIN』、『FOOTER』などとの段組を作成し、中央の『MAIN』内に『MENU』と『CONTENTS』の左右2段の段組をfloat:leftを利用して作成し、テンプレートとして利用しようとしています。 このテンプレート部分は、『MENU』の幅のみ固定で、『CONTENTS』は可変幅のレイアウトとしております。ここまでは順調に作成できたのですが、肝心のコンテンツの作成でつまづきました。 『CONTENTS』内に、更にfloat:leftで左右にDIVを配置したブロックを複数作ろうとした場合、2つ目のブロックを配置した時、1つ目の右側DIVの高さが1つ目左側DIVよりも高さが低い場合、2つ目以降のブロックが1つ目左側のDIV右に回りこんで表示されてしまいます。これは1つ目のブロックを配置した後、float:leftをclearしていないから当然だと思います。 そこで、1つ目のブロックの後にclearを摘要(<br />などに)させると、テンプレートの、『FOOTER』直上に2つ目のブロックが配置されてしまいます。1つのclearで入れ子になったfloat:leftが全てclearされてしまう様です。 これが『仕様』と言われればそれまでですが、TABLEや、固定幅のfloat:right等を使用すれば回避できそうですが、TABLE脱却・リキッドレイアウトをここまで実現できたのに、肝心のところで妥協するのも悔しい気がします。 まさか、こんな単純な事で丸一日悩むとは思いませんでした。web上を検索して回ったのですが、良い解決策が見つからず、こちらにおすがりした次第です。文章ではうまく表現できずわかりにくいかもしれませんが、何か回避作があれば教えて下さい。

質問者が選んだベストアンサー

  • ベストアンサー
  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.2

前回の回答 > 「詳細度」の高い部分(*1)で2つ目のブロックに「clear:left」を指定 はまちがいでいした。すいません。 float(left)したブロックは包括ブロック(の左辺)を超えてはならないという規則がありますが、clearは例外になると明記さているのでfloatよるレイアウトの限界だと思います。 意図とは異なるような気もしますが、 menuブロックの高さが常にcontentsブロックの高さより低いと決められるのであればabsoluteを利用して配置する事はできそうです。 #main{ position:relative;/*追加*/ } #menu{ /*float: left; 削除*/ position:absolute;/*追加*/ } .data{ clear:left;/*追加*/ }

参考URL:
http://www.y-adagio.com/public/standards/tr_css2/visuren.html#flow-control
go_nta
質問者

お礼

度々ありがとうございます。 >floatよるレイアウトの限界だと思います。 floatによる2段組レイアウトを利用した場合、『段組内で同方向へのfloatは2度と使えない』ということでしょうか・・・ >absoluteを利用して配置 ブロックの高さは不確定です・・・何より、absoluteによる配置だと、リキッドレイアウトはもちろん不可能ですが、ユーザー側でフォントサイズを変えられたときにレイアウトが破綻しますので、画像などを使用して高さや幅が確定されている部分でしか使用していません。 floatによる段組はCSSの作例で必ず紹介されるほどポピュラーなものですが、ネストした物を見たことがありませんでした・・・やはりCSSによるレイアウトの限界でしょうか・・・残念ですがCSSの限界がこんなに低い所にあるとは思いもよりませんでした・・・と言うより、リキッドレイアウトをCSSで実現させようとしたのが間違いだったのでしょうか・・・CSSに不可能な部分はTABLEで代用する他ありません・・・ なんか最後は愚痴っぽくなってしまいましたが、ありがとうございました。

その他の回答 (6)

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.7

#3について。 ごめんなさいです。IEでの確認してませんでした。何かバグに触れてしまったようです。 別に幅の指定は必要ではないです。#3もfirefoxやoperaでは問題ないです。 ですが、状況によっては指定する事でうまくいくのかもしれませんね。

go_nta
質問者

お礼

steel_grayさん申し訳ございません。nuruhho44さんと混同しておりました。 やむを得ず、left_data・right_dataのdiv要素の使用を止め、左側にfloat:leftを適用したimg要素(に限定)、右側にh*要素とp要素をそのまま流し込み、p要素の高さをimg要素と同じ高さをdata毎に個別に指定することにしました。 もちろん、p要素下部に必要以上の余白が出来ることになりますが、ウインドウを小さくして指定した高さ以上にテキストが回り込んでも、レイアウトが破綻せずに思ったとおりにレイアウトできています。 WinIE5.5 IE6.0 Netscape6 Opera Firefox MacIE5でほぼイメージ通りとなっております。ウインドウサイズもSVGA以上では破綻しません。300px以下にするとさすがに破綻するブラウザも出てしまいますが・・・ 個人でやっていて独学ですので経験者のお話大変為になりました。また質問したときはぜひお願い致します。ありがとうござました。

  • nuruhho44
  • ベストアンサー率57% (38/66)
回答No.6

#4です。 全然的外れなことかもしれませんが、以下は私が以前やった方法です。役に立たなかったらごめんなさい。 <HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <META http-equiv="Content-Style-Type" content="text/css"> <TITLE></TITLE> <SCRIPT type="text/javascript"> <!-- AD = new Array("あ","い","う","え"); function Fgh() { for (i=0; i<4; i++) { r = Math.floor(Math.random() * 500); var A = ""; for (j=0; j<r ; j++) { A += AD[i]; } document.getElementById("dd"+i).innerHTML = A; } } //--> </SCRIPT> <STYLE type="text/css"> <!-- * { box-sizing : border-box; } * { -moz-box-sizing : border-box; } .header { width : 100%; background-color : aqua; } .menu { width : 200px; height : 20em; position : relative; z-index : 2; background-color : lime; } .contents{ width : 100%; margin-top : -20em; padding-left : 200px; } .footer { clear : left; width : 100%; background-color : pink; } .c1 { clear : left; } .d1 { width : 49%; float : left; } #dd0 { background-color : #ffff00; } #dd1 { background-color : #ff00ff; } #dd2 { background-color : #00ffff; } #dd3 { background-color : #cccccc; } --> </STYLE> </HEAD> <BODY onload="Fgh();"> <DIV class="header">header<BR>header<BR>header</DIV> <DIV class="menu">menu<BR><A href="javascript:Fgh();">コンテンツ変更</A> </DIV> <DIV class="contents"> <DIV class="c1"> <DIV class="d1" id="dd0"></DIV> <DIV class="d1" id="dd1"></DIV> </DIV> <DIV class="c1"> <DIV class="d1" id="dd2"></DIV> <DIV class="d1" id="dd3"></DIV> </DIV> </DIV> <DIV class="footer">footer<BR>footer</DIV> </BODY> </HTML> スクリプトはコンテンツ内の各ブロックに適当に文字を放り込むためのものです。判り易いように各ブロックに背景色を入れてあります。 これの問題は『MANU』ブロックの高さより『CONTENTS』ブロックの高さが低い場合は、『FOOTER』が『MANU』に重なるということですね。

go_nta
質問者

お礼

サンプルコード試させて頂きました。なかなかいい感じですが、やはり各ブロックを『1文字』などにするとおっしゃってるようにfooterが回り込みますね。 情報量の少ない小規模サイトばかり作ってるので(笑)厳しいですね。とはいえ大変参考になりました。ありがとうございます。

go_nta
質問者

補足

nuruhho44さんすみません・・・ずーっとsteel_grayさんが書き込んでるのかと思ってました(汗)『#4』で初めて気付きました・・・大変失礼しました。 わざわざサンプルコードありがとうございます。まだ確認できていませんが、明日にでも試させてもらおうと思います。

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.5

補足。 対応しているブラウザがないようなのが残念ですが、御希望のようなレイアウトは実はフロートよりもcompactボックスが適しているのではないかと思います。 →参考URL #menu ,.left_data{ display:compact; /*float:left; floatはさせずに、右側に置きたいブロックのマージンの中に配置*/ : : }

参考URL:
http://www.y-adagio.com/public/standards/tr_css2/visuren.html#compact
go_nta
質問者

お礼

>compactボックス 初めて聞きました(汗) >対応しているブラウザがない CSS3が策定されても、結局現在のブラウザが対応してくれなければ使用する事はできませんよね。ヘタに今のブラウザのバグがフィックスされても、バグを利用した個別ブラウザのレイアウトが破綻するだけですし・・・ ヘタなプロパティ作るよりもTABLE要素の機能そのままに名前を変えてレイアウト用の要素を作ってくれる方が・・・(笑) なんかどんどん『愚痴』になってきました・・・すみません。

  • nuruhho44
  • ベストアンサー率57% (38/66)
回答No.4

floatを使ってレイアウトすると、ブラウザによる違いが大きく、なかなかうまくいきませんよね。 並べるブロックの高さが違うと回り込みされてしまいますので、ブロックの高さを統一してみてはいかがでしょうか。 但しheightの指定値は、文字サイズに比例するemやらexを使います。それによって完璧とは行きませんが、文字サイズの変更による崩れはかなり抑えられると思います。 これはabsoluteを使ったレイアウトでも同じです。 しかしem値やex値はブラウザによって解釈が違っているようで、空白部分が大きくなってマヌケなデザインになりかねません。 窮余の一策としては、IEとそれ以外のブラウザによって指定値を変える方法があります。(知ってたらごめんなさい) div { width : 400px; _width : 420px; } という風にすると、IEでは後で指定したアンダーバー付きの指定が有効となり幅420px、その他ではアンダーバー付きは解釈されず幅400pxとなります。 ちなみに記号はアンダーバー以外でもいいみたいです。 floatのいいところはブラウザの表示幅によって勝手に折り返してくれるので、表示幅に合わせた段組が可能となるところで、これはtableでは無理です。 最近作ったHPで、なんとかfloatで内容量の異なるブロックを段組みすることはできたのですが、商用サイトということで、表示の不安定さに限界を感じて最後はやむなくtableを使いました。残念!!

go_nta
質問者

お礼

テンプレート部分ではほとんどのブラウザ、様々なディスプレイ環境でほぼ同一の表示にさせることが出来ました。まぁ、ここで『あとは簡単』と高を括っていたのがこの様です。 em等を使った幅・高さの指定も『文字数や、行数が予め決まっている場合』にしか使えませので、absolute配置の際、文字サイズに影響されたくない部分(メニュー等)に限って利用しています。コンテンツ部分に使用するとウインドウサイズでレイアウトが破綻する場合がありますから。SVGAなら数行使うところがSXGAだと1行で済んでしまったりしますので・・・ アンダーバーを使う方法は知りませんでした(汗)なんせ独学なもので・・・普段は『*』や『>』で子孫セレクタを指定する方法をとってました。 私も今での商用サイトはNetscape4.xを考慮し、全てTABLEでレイアウトしていました。CSSに移行するのはWeb屋の意地と言うか、自己満足だけと言うか・・・(笑)前回制作したものはテンプレートを非リキッドなCSSで、コンテンツ部分はTABLEレイアウトのサイトと自動生成用スクリプトを共用しているのでTABLEを使って・・・と普通の『ハイブリットデザイン』とは逆なことをしている気がしないでもないです(笑) TABLEという本来の意味とはかけ離れた物をレイアウトに使うのを止めると言うことは賛同できますが、CSSの為にデザインを制限されるのは納得いかないところです。結果として『TABLEっぽいレイアウトを強引にCSSで再現させる』状態になっていましてコードはDIVだらけです(笑)『CSS命』な方々からは怒られそうですが、『多くの間違った使い方が存在する』よりは『多くの無意味な物が存在する』方がいくらかマシかと思ってますので。

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.3

話題がずれますがabsoluteを利用しての配置について。 前回回答での利用の仕方においては先に挙げた制約以外はリキッドレイアウト、文字サイズ変更とも問題ないはずです。 回答どおりで positionはabsoluteにしますが、topやleft等の指定は不要です。(あえて書くならtop:0;left:0;になりますので。)

go_nta
質問者

お礼

なるほど。左上基点でボックスを重ねるような状態ですね?教えて頂いたスタイルをコピペしただけですが、IEではレイアウトできませんでした。ですが、しっかり作りこめば大丈夫かもしれません。検討の余地有りですねありがとうございます。 ところで、position:relative;を含包ブロックに指定して基準ボックスとする場合、幅の指定が必須ではなかったでしょうか?リキッドレイアウトの為になるべく幅や高さを明示しないようにごまかしてきたのですが(笑) ブロック要素のwidth:100%;がTABLE要素のwidth="100%"と同じ解釈をしてくれればどんなにありがたいか・・・CSSに厳格なブラウザではレイアウトが破綻する場合がありますね・・・

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.1

「詳細度」の高い部分(*1)で2つ目のブロックに「clear:left」を指定してみては? > 文章ではうまく表現できずわかりにくいかもしれません?が、 現状のコード(htmlとcss)を単純化したモデルを記述してもらえると、回答する方も検証できるかと。 *1:他のCSSがhead部に書かれているなら、インライン(style属性)で。

go_nta
質問者

お礼

ご回答ありがとうございます。本日は帰宅してしまいましたので明日職場から単純化モデルを作成し掲載させていただきます。もしよろしければまた見てやってください。

go_nta
質問者

補足

単純化モデルを作成してみました。 スタイル部分です。 #header{ margin: 0; padding: 0; background-color: #09F; } #main{ margin: 0; padding: 0; background-color: #CCC; } #menu{ float: left; width: 200px; margin: 0; padding: 0; background-color: #FC9; } #contents{ margin: 0 0 0 210px; padding: 0; background-color: #FFF; } .data{ margin: 0; padding: 0; background-color: #9C9; } .left_data{ float: left; width: 150px; margin: 0; padding: 0; background-color: #00F; } .right_data{ margin: 0 0 0 155px; padding: 0; background-color: #F00; } #footer{ clear: both; margin: 0; padding: 0; background-color: #F9C; } HTML部分です。 <div id="header">HEADER</div> <div id="main"> <div id="menu">MENU<br />menu-1<br />menu-2<br />menu-3</div> <div id="contents"> <div class="data"> <div class="left_data">DATA-1<br />DATA<br />DATA</div> <div class="right_data">DATA</div> </div> <div class="data"> <div class="left_data">DATA-2<br />DATA<br />DATA</div> <div class="right_data">DATA</div> </div> <div class="data"> <div class="left_data">DATA-3<br />DATA<br />DATA</div> <div class="right_data">DATA</div> </div> </div> </div> <div id="footer">FOTTER</div> もちろん実際にはもっと複雑ですが、この程度でも同じ状態になっています。普通に考えれば"data"クラスを適用した各DIV要素の後でclearしないとダメだと思うのですが・・・ "data"クラスを適用したDIV要素に『whidth:100%』を指定したり、擬似要素afterで空のブロック要素を生成、clearプロパティを適用してみましたが、Opera、Firefox、MacIEなどでは改善できませんでした。なにかお気づきの点があれば教えてください。

関連するQ&A

専門家に質問してみよう