CSSの【float】についてちょっと本気出して説明してみた。
HTMLとかCSS ひよこちゃん向けシリーズ、【float】編です!CSSの【float】について本気出して説明してみた。left right ,clearってなに!??

HTMLとかCSSとかこれから!な、ひよこちゃん向けシリーズ、【float】編です!
2016/07/15 一番最後のほうにfloat clearfixの修正版追加しました。
float(フロート)とはなんぞや?
floatとは、要素(<div>とか<p>とか)を右に寄せたり、左に寄せたりするときに使います。 よくサイトで見られるサイドバーとかサイドメニューとかもfloatで配置することが多いですね。
まずは、プロパティをおさらいしておきましょう!
- left 【左に寄せる】
- right 【右に寄せる】
- none 【やっぱフロートやめる】
- inherit 【継承させる】←使うことあまりない
プロパティは以上です。基本的にinheritは使う場面はほとんどありませんね!
それではfloatとはなんぞや?っと言うお話をしていきましょう
基本floatは左右に要素を寄せるときに使いますね。しかし、ただただ寄ってるだけではないのです。そこで
【ポイント1】float=(浮動化)と考えます。
このようにコンテンツという入れ物の中身がフロート(浮動)することで右へ左へと寄っていきます。
では実際にHTMLでやってみましょう!
<div id="Contents"><!-- コンテンツ --> <div id="Main"><!-- フロートで左に寄せるよ --> メインとか</div> <div id="Side"><!-- フロートで右に寄せるよ --> サイドとか</div> </div>
CSSをこのようにしておきます
<style> #Contents { width: 700px; margin:0 auto; background:#CCCCCC; } #Main { width:300px; height:300px; background:#333DFF; } #Side { width:300px; height:300px; background:#27C42A; } </style>
するとこのようなボックスモデルが出来上がりました。
では、さっそくフロートさせていきましょう! まずは、メインに対してfloat:left;を与えます。
#Main { float:left;/* 浮かせて左に寄せるよ */ width:300px; height:300px; background:#333DFF; }
はい!サイドの文字だけ残して緑色のボックスが消えましたね!
これはどういうことでしょう?
立体化するとこんなことになってます! なぜ文字が?っというのはメインもサイドもボックスのサイズを同じにしましたね?なので、メインがサイドに乗っかってしまったため、行き場をなくした文字が下に追いやられたんですね。
この状態、実は画像と文字の組み合わせだと結構使えます!新聞記事のようなレイアウトをするときに画像と文字の回り込みを使うんですね。
これは後ほど使用例を挙げましょう。
では、両方の要素にfloat:left;を与えてみましょう。
#Main { float:left; width:300px; height:300px; background:#333DFF; } #Side { float:left; width:300px; height:300px; background:#27C42A; }
あれあれ?何かおかしいですね?お気づきになりましたか?
そう! コンテンツの背景がなくなってるんです! これはサイドにfloat:right;を与えても一緒です。
どういうことが起きているのか、図でご説明しましょう。
というように、ブロック要素は内包する要素が無いと高さは無いものとなるのです。
ここで出てくるのがclearプロパティやclearfix、overflow:hidden;です。次はfloat解除について見て行きましょう。
なぜ解除するん?【clearについて】
先ほど内包する要素が浮いてしまったため、高さがなくなってしまったコンテンツくんを救ってあげましょう。
その前に、なぜ救ってあげないといけないのか!
それはまず、floatは次の要素へ影響を及ぼす事
次に、親要素にpadding、marginを中の要素を内包した状態で設定できない事が理由として挙げられます。
要は色々と具合が悪いんですね
なので、必ずfloatは解除してあげましょう。これはもう決まり事のようなものです。
それでは解除の方法をおさらいしてみましょう!
方法その1 clearプロパティ
- clear:both; 【左寄せも右寄せも解除します】
- clear:left; 【左寄せされた要素に対する解除です】
- clear:right;【右寄せされた要素に対する解除です】
clearプロパティを使って解除する方法が今までは一般的でしたが、今回のボックスモデルのような場合
clearを与える要素が無いため、空のdivにclass=”clear”を与えるなどして、対応していました。
それを解決したのが次の方法です。
方法その2clearfix
clearfixという解除用classを親要素へ与え、子要素のfloatを解除する方法です。
.clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .clearfix {display: inline-table;} /* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */
色々とバリエーションがありますが、これが一般的な原型です。
このstyleをbase.cssやreset.cssに入れ込んで使用します。
方法その3禁術 overflow:hidden;
親要素にこのおまじないを与えることで、高さを取り戻します。
おまじないの秘密は、高さ(height)がautoの状態で、overflowがvisible以外のブロック要素がフロートした子要素を内包している場合、その高さはフロートした子要素を含むように広げられる…ということらしいです。
しかし、この禁術はもともと切り抜くプロパティーです。つまり、1pxでもはみ出たらそこはばっつり切られます。
box-shadowなどを使用する場合、ばっつりと切られて表示されないなんてことがあるので注意です。
また、制作現場ではoverflow:hidden;での解除はあまり良く思われてない事もしばしばあるので、あまりおすすめはできませんね
では、方法その1 clearプロパティから実際に使用してみましょう!
このままではclearプロパティを設定できないので、従来通りclear用の空divを作りましょう。
<div id="Contents"><!-- コンテンツ --> <div id="Main"><!-- フロートで左に寄せるよ --> メインとか</div> <div id="Side"><!-- フロートで右に寄せるよ --> サイドとか</div> <div class="clear"></div> <!-- クリアー用の空divだよ --> </div>
.clear { clear: both;/* 左寄せしてるけど、右寄せに変えたりするからbothにするよ */ }
するとこうなりました~!
ちゃんと背景も出てきましたね!
しかし、ここで安心はできません!このclearプロパティにはちょっとした落とし穴があります。
よくある使い方として、このようなレイアウトのとき、clearプロパティをフッターに与えることがありますが
そこにちょっとした落とし穴が…
【clearプロパティを与えた要素にはmargin-topが効かない!】という事態が起きます。
しかし、これは効いてないのではなく、フロートした子要素を無視して、ヘッダーとフッターの間のmarginとなるのです。 なんのこっちゃ?っとなると思いますが、clearプロパティは通常フローに戻すといった役割があり、フロートちゃん達との辻つまをあわせるため クリアランスという謎余白が自動的に追加されてます。
ためしにフッターのmargin-topをフロートした子要素を超える360pxなどにするとちゃんと余白がでます。
といったようなややこしい仕様の為、空divを使う方法が一般化していったのでしょうね
しかし、今どき空divはあまり使いません。
それは、clearfixという便利なものができたからです。
では、方法その2 clearfixを使ってみましょう。
<div class="clearfix" id="Contents"><!-- コンテンツにclass="clearfix"を追加したよ --> <div id="Main"><!-- フロートで左に寄せるよ --> メインとか </div> <div id="Side"><!-- フロートで右に寄せるよ --> サイドとか </div> </div>
style
#Contents { width: 700px; margin:0 auto; background:#CCCCCC; } #Main { float:left; width:300px; height:300px; background:#333DFF; } #Side { float:left; width:300px; height:300px; background:#27C42A; } .clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .clearfix {display: inline-table;} /* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */
と言った感じになりました。
classを足すだけでさっくりと解除できましたね! この方法が一番良く使うのではないでしょうか?
しかし、これにも少しばかり落とし穴があります。
【footerに設定すると下になぞの余白ができる】という事が起きます。
これは、clearfixが:afterという擬似要素とcontentプロパティーでブロック要素を作り、それにclear:both;を与えるという仕様によるものだと思われます。 つまり、見えないブロック要素の1行分隙間が出来てしまうのです。
この解決法については色々とあるけれど、一例を記載します。
.clearfix:after { content: " ";/* ピリオドを消してスペース入れました。 */ display: block; height: 0; clear: both; visibility: hidden; }
なぜピリオドなのか?
それはNetscapeというブラウザに対応させていたからです。
今どきNetscape使うことなんて無いとはいいませんが、わたしもこの事調べるまで見向きもしなかったので、未対応でもいいんじゃないか?と思います。
いや!わたしは完璧なのがいい!っという方は1px×1pxの透過gifを作って、content: url(透過gif.gif);で読み込んでください。
おそらくは、最強のclearfixになるのではないかと思われます。
最後に禁術overflow:hidden;です。
使い方は簡単で、親要素のstyleにoverflow:hidden;を与えるだけです。
ですが、注意するべきは切り取られているということ!
では実際、どうなることを言っているのかご説明いたします。
<div class="clearfix" id="Contents"><!-- コンテンツ --> <div id="Header">ヘッダーとか</div> <div id="Main"><!-- フロートで左に寄せるよ --> メインとか </div> <div id="Side"><!-- フロートで右に寄せるよ --> サイドとか </div> <div id="Footer">フッターとか</div> </div>
<style> * { margin:0; padding:0; } #Contents { width: 700px; margin:20px auto 0; background:#CCCCCC; } #Header { height:40px; background:#FCAAAB; } #Main { float:left; width:500px; height:300px; background:#333DFF; } #Side { float:left; width:200px; height:300px; background:#27C42A; box-shadow:5px 5px 2px rgba(0,0,0,0.3); } #Footer { clear:left; height:200px; background:#FFF242; } .clearfix:after { content: ""; display: block; height: 0; visibility: hidden; clear: both; } .clearfix {display: inline-table;}/* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */ </style>
このようなボックスモデルを用意しました。
サイドにドロップシャドウをつけていますね! 現在はclearfixにてfloatを解除しています。
では、これをoverflow:hidden;に変えてみましょう!
<div id="Contents"><!-- コンテンツ class="clearfix"を消したよ --> <div id="Header">ヘッダーとか</div> <div id="Main"><!-- フロートで左に寄せるよ --> メインとか </div> <div id="Side"><!-- フロートで右に寄せるよ --> サイドとか </div> <div id="Footer">フッターとか</div> </div>
style
#Contents { width: 700px; margin:20px auto 0; background:#CCCCCC; overflow:hidden; /* 追加したよ */ }
するとコンテンツの大きさで切り取られるのでこうなります。
このようなことが起きますので、clearより楽で、よく原因がわからずカラム落ちなどしたときにひよこちゃん達は多様しがちですが
冒頭で説明したとおり、あまり現場では好まれません。よって、clearfixやclearを用いることを推奨しますよ。
カラム落ちに悩める子羊たちへ
カラム落ちは始めのうち悩まされるものの一つでしょう
ほぼ原因は、100%フロートです
では、なぜカラム落ちが起きるのか!
そのほとんどがwidth計算が合ってないことが原因です。
たとえば、
- paddingやmargin、borderを計算に入れていない
- そもそもwidthを設定していない。
- 高さの違うものを2段以上フロートで並べている
などあります。
カラム落ちしたときはまず、widthを疑ってみましょう。
たとえば、width:700px;のコンテンツにpadding:0 10px;を与えると、widthは720pxになります。
中の子要素達のwidthが同じように増えたら辻つまを合わせて挙げないと行けません。
では、例を挙げてみましょう。
<div id="Contents"><!-- コンテンツ --> <ul class="clearfix"> <li>100px</li> <li>100px</li> <li>100px</li> <li>100px</li> <li>100px</li> <li>100px</li> </ul> </div>
<style> * { margin: 0; padding: 0; } #Contents { width: 700px; margin: 20px auto 0; padding: 20px 0; background: #CCCCCC; overflow: hidden; } ul { list-style: none; } ul li { float: left; width: 100px; height: 60px; padding-top: 40px; margin-left: 14.3px; background: #24B1FF; text-align: center; } .clearfix:after { content: ""; display: block; height: 0; visibility: hidden; clear: both; } .clearfix { display: inline-table; } /* Hides from IE-mac \*/ * html .clearfix { height: 1%; } .clearfix { display: block; } /* End hide from IE-mac */ --> </style>
このようなボックスモデルを用意しました。
では、liにpadding: 40px 10px 0;で両幅を10pxずつ足してみましょう
width:700px;におさまりきらないので、一つ下に落ちました。
カラム落ちと同じですね! では、100pxにもどしていきましょう!
計算はwidth:80px;とpaddingが両脇10pxで100pxに収まりますね!それではやってみます。
ul li { float: left; width: 80px; /*100px→80pxへ*/ height: 60px; padding-top: 40px; padding: 40px 10px 0; margin-left: 14.3px; background: #24B1FF; text-align: center; }
これで、きっちりと並びました!
marginも同じです、ちゃんと収まるように計算しましょう!
もう一つ例をあげます。
左端と右端がコンテンツの端にぴったりくっつく様に並べる方法です。
ひよこさんはこれでよくoverflow:hidden;などつかってしまいがちではないでしょうか?
では、色々方法はありますが一つやってみましょう!
先ほどのボックスモデルを使います。
単純計算でボックスが6つ並べび、両端はくっついていれば隙間は5つになりますね!
100pxのliが6つあるので、合わせて600px
親要素のコンテンツは700pxなので、余白は100px、それを5で割ると余白は20pxです。
では、実際にHTMLを書いてみましょう
ul li { float: left; width: 80px; height: 60px; padding: 40px 10px 0; margin-left: 20px; /* 左に20px */ background: #24B1FF; text-align: center; }
このように崩れますね。
一番左のliについているmargin-left:20px;が邪魔になってるんですね。
このままリストが増える事が無いのであれば、li:first-childにmargin-left:0;とすれば揃いますが、今回は増えても大丈夫なように作っていきましょう。
ulのstyleをこのようにします。
ul { list-style: none; width:720px; /* はみ出た分も足す */ margin-left: -20px; /* 入れ物自体、左へ20px寄っていただく */ }
このようにネガティブマージンを使って、リストを並べることが出来ます。
この考え方をすると、カラム落ちは回避できるようになると思います。
高さがバラバラな場合は高さを合わせるか、CSSの display: inline、display: block、display: inline-block をマスターしよう!を参照しましょう。
また、javascriptやjQueryで自動的にliの高さをそろえる方法もありますがそれはまた別の機会で!
その他、わざと回りこませたりする使い方
記事のようなレイアウトをするときに、文字が回りこむようにするときも、フロートをつかいます。
このようなボックスモデルを用意しました。
<div class="clearfix" id="Contents"><!-- コンテンツ --> <div class="photo"></div> <p class="text">あなたは結果はたしてこの発音ようという訳のところをしでます。ようやく十一月が料簡方は人知れずその運動ましませだけに通じているんには関係知ったずて、全くにも受けないんたなく。気の毒に来たのはけっして結果がよくでしなけれだ。何しろ大森さんが会得置どう学習にありた人間こういう差ここか出入りからというお自覚でありでしょますて、その前もあなたか春程度の出さが、岡田さんののに党派の私をともかくご攻撃と存じからここがたにお真似に出ようにもっとお品評を思えありらしいて、まあおっつけ[#「をおくなけれてならならのの上りですた。 だからそうして肝国に起るのぞそれだけ立派ともっんが、この国家にはすたてという先輩を臥せってくるなくう。こういう日珍の頃その兄弟はそこ中があれないかと岡田さんで廻らずだ、個性の前ますに対してお享有ないですないと、途の時を衣食がほかぐらいの無法に絶対思ってならて、そうの今日と察せでこの所にとにかくやまですでとなりたのなて、なけれたなかってわざわざ実国家あっですのただな。そうして此年か不愉快か満足からしませが、今上寸毫に見て出しです以上が皆合点の結果を向っでな。 将来のももし聞いて駈けたらうででて、無論よくなりて仕事も実際なかろですものです。しかしながらお病気に持ってもいですのないし、こだわりがは、いくらこれかなるて帰っれですななるせるでしょあっときて、社会もやりばいだで。 とうとうもしも常に自分というしまえたて、あなたがは当時ごろばかり私のご話は若い限らならたた。私もいよいよ見当の事が小矛盾も防ぐでいんたでしますば、十二の他をとても忘れるたというお話ですて、なおこういう学校の個人がなりられるながら、どこかに私の事に乱暴が知れているでしょのたですと創設役に立つので威圧見るいけたな。モーニングにすなわち岡田さんにそれでそう当てましものですなでしょ。 大森さんはこう叫び声がありてなっん事ないならた。(そうして本領を至るうちますますでてだも蒙りたたらて、)元々進んた主命を、三井の鷹狩まで受けるてしに対する、畸形の話も事実の上まで思うあり事を読みないて創作屋進むでしまうですというご会だ事で。 それはどうもただが感ずるたように連れていただくたのんからまたますます目黒ご覧眺めるなまし。 それで当然一年は無理矢理を黙って、事実のけっして申したなと圧しが、若いですありてだからお尊重を云わでだ。 価値の今を、この非に今が着けなど、元来中をこう昨日万一何軒にするくらいの右が、彼らか尽さなくっ講義にしあり将来はどうしても思っれのなし、何とも始終がたをないて、この方にいうのが自由だない釣っんた。 そうして時々今一一一軒を云っなりもあるですという厄介た記憶から受けるて、誂でその上その時で降るて来ないものた。ちっともに事に慚愧いただきない四何度場合に働かと、やつかなりですばいるたという方を多少会ったものますで、近頃するのを不思議ませば、そのうち事が起ってかい摘んてくれだう。</p> </div>
<style> * { margin: 0; padding: 0; } #Contents { width: 658px; margin: 20px auto 0; padding: 20px 20px; border:1px solid #ccc; } .photo { width:250px; height:90px; padding-top:60px; background:#8B8B8B; text-align:center; } .text { } .clearfix:after { content: ""; display: block; height: 0; visibility: hidden; clear: both; } .clearfix { display: inline-table; } /* Hides from IE-mac \*/ * html .clearfix { height: 1%; } .clearfix { display: block; } /* End hide from IE-mac */ </style>
これをphotoを取り囲むようにしたレイアウトを作ってみましょう。
photoに対してfloat:left;をかけるだけで、文字が回りこんできます。 textにはフロートもwidthも指定していない状態です。
.photo { float:left; width:250px; height:90px; padding-top:60px; background:#8B8B8B; text-align:center; }
次にtextにfloat:right;とwidthを与えてみましょう。
.text { float:right; width:400px; }
このように左のphotoに回りこまないレイアウトも出来ました。 応用次第で、いろいろなレイアウトができますね!
まとめ!!
floatを使用する上で大事な事は以下です!
- 1.floatしたら必ず解除するべし!
- 2.floatは基本widthを必ず指定すること!
- 3.positionでstatic以外の値が指定されている要素にはfloatは効かない!
floatとclearfixに関しての追加分ここから
ふと昔の記事にもどってみたらなんかおかしい・・・と思い、新たに追加しました。ごめんなさい。
先で#Contentsで全体を囲って(headerとfooterを含んで)、clearfixをかけていましたが、ほんとはこっちの方法を取ります。
理由としては、レスポンシブやheader、footerの背景を100%にしたい時に具合が悪いからです。
ボックスモデル
ソース
<!-- HTML5のタグを使用していますので、xhtmlの場合はheaderなどのタグをdivに変更してください。 --> <header id="Header"> <div class="inner"> ヘッダー </div> </header> <nav> <ul id="Navi" class="clearfix"><!-- ここにclearfix ※floatさせる要素の直の親要素に付ける --> <li>ナビ01</li><!-- liを全部 float leftで横並びに --> <li>ナビ02</li> <li>ナビ03</li> <li>ナビ04</li> <li>ナビ05</li> </ul> </nav> <div id="Contents" class="clearfix"><!-- ここにclearfix ※floatさせる要素の直の親要素に付ける --> <div id="Main">メイン</div><!-- float leftさせる --> <div id="Side">サイド</div><!-- float leftさせる rightでもよい --> </div> <footer id="Footer"> <div class="inner">フッター</div> </footer>
<style> /* ========================================================= Header ========================================================= */ #Header { width:100%; /* 横幅を100%に */ background:#FFE5E5; } #Header .inner { width:700px; min-height:30px; margin:0 auto; padding-top:30px; background:#FFC9CA; text-align:center; } #Header .inner p { padding-top:30px; text-align:center; } nav { width:100%; /* 横幅を100%に */ background:#E5DDFF; } /* ========================================================= nav ========================================================= */ nav #Navi { width:700px; margin:0 auto; background:#C4C9FF; } nav #Navi li { float:left; width:20%; /* ナビは5つなので100÷5=20で計算 */ min-height:40px; margin:0; background:none; box-sizing:border-box; /* border分足されるので、box-sizingでborderを含むwidthに変更 */ border:#E1EAFF solid; border-width: 0 1px 0 1px; list-style:none; } /* ========================================================= Contents ========================================================= */ #Contents { width:700px; margin:0 auto; padding:10px; background:#D4D4D4; box-sizing:border-box; /* 同じくpaddingを含むwidthへ変更 */ } /* ========================================================= Main ========================================================= */ #Contents #Main { float:left; /* 左に寄せるよ */ width:480px; min-height:400px; background:#D5A4FF; text-align:center; } /* ========================================================= Side ========================================================= */ #Contents #Side { float:left; /* 左に寄せて#Mainの横に並べるよ */ width:190px; min-height:400px; margin-left:10px; background:#FDFFBF; text-align:center; } /*========================================================== Footer ========================================================= */ #Footer { width:100%; /* 横幅を100%に */ background:#DAFFDA; } #Footer .inner { width:700px; min-height:80px; margin:0 auto; background:#7BF469; text-align:center; } </style>
記述が増えましたが、やっていることはfloatをさせる要素を囲う一番近い親要素にclearfixを指定しているだけです。
先の記述だと、headerやfooterを含んでいましたので、widthをコンテンツ幅きちきちに計算しなくはいけませんでした。
後の記述だと、header/nav/footerが独立しているので、widthに縛られず、自由に編集できます。
最近ではこの形が多いのではないでしょうか?
後付ですみませんでした。このような形を取ることが多いので、CSSのに見慣れたらこちらの方法を是非
ではまた次回~(・ω<)ノシ