目次
Webデザインにおけるfloatプロパティの役割を一言で表すなら「各要素の位置を右寄せ・左寄せにする」です。
Webデザインでは、hmlタグで囲まれた各要素をhtmlファイルにテキストベースで書き込んでいきます。
通常書き込まれた各要素は、縦にどんどん積まれていくか、横にどんどん並んでいくかのどちらかになります。この縦に積まれていくタイプの要素を「ブロック要素」、横に並んでいくタイプの要素を「インライン要素」と言います。
たとえば、以下のhtmlコードをブラウザーで表示すると画像のようになります。
※この記事ではstyleタグを用いてCSSコードをhtmlファイル内に記述しています。
<style>
.inline{background-color: aquamarine;}
.block{background-color: beige;}
</style>
<div class=”inline”>
<span>インライン要素</span>
<span>インライン要素</span>
<span>インライン要素</span>
<span>インライン要素</span>
</div>
<div class=”block”>
<div>ブロック要素</div>
<div>ブロック要素</div>
<div>ブロック要素</div>
<div>ブロック要素</div>
</div>
ブロック要素に属するのは、 <p><h1><div> などのタグで作る要素です。インライン要素には <span> <a> 等のタグで作る要素が属します。
また、インラインブロック要素というブロック要素+インライン要素の属性をもつものもあり、代表的なものに <img> があります。インラインブロック要素も横に並びます。
ただし、ブロック要素・インライン要素(インラインブロック要素)の属性はタグに固有の物ではなく、displayプロパティで変更が可能です。
例えば、<div>はブロック要素なので基本的に縦に並びますが、displayプロパティをinlineに変えれば横に並べることもできるわけです。先のコードで以下のプロパティを付け加えると、blockクラス内のdiv要素がインライン要素になり、横並びになります。
.block div {display: inline;}
このようにdisplayプロパティを使えば、要素の種類にかかわらず縦⇔横のレイアウトを切り替えることができます。
レイアウトの種類が縦並びと横並びしかないのでは、柔軟なWebレイアウトができません。
例えば「メイン」「右サイドバー」と要素があったら、「右サイドバー」は「メイン」の右へ配置したいものです。そんなとき、各要素の位置をfloatで指定してあげると「縦」と「横」しかなかったhtmlブロックのレイアウトに「右寄せ」「左寄せ」の選択肢が生まれます。
ここからは、floatプロパティの具体的な使い方についてみていきましょう。floatプロパティには以下の3つの値を指定できます。
前述したとおり、初期値では各要素は縦に並ぶか横に並ぶかのどちらかになります。floatプロパティは「ブロック要素」「インライン要素」のどちらの要素に対しても使うことができます。
ただし、floatプロパティを使うと「インライン要素」は自動的に「ブロック要素」に変わります。
では、具体的にfloatプロパティを書き、その効果を見てみましょう。まず「メイン」「右サイドバー」の2つのdiv要素を用意します。
<div class=”sidebar”>
ここが<br>サイドバー
</div>
<div class=”main”>
ここがメイン
</div>
分かりやすいように、「メイン」と「サイドバー」の背景に違う色を付けます。どちらも高さは300pxにそろえ、文字の大きさを50pxに、テキストが中央に来るようtext-alignプロパティをcenterにします。
<style>
.main
{
background-color: burlywood;
width:400px;
height: 300px;
text-align: center;
font-size: 50px;
}
.sidebar
{
background-color: cyan;
width: 200px;
height: 300px;
text-align: center;
font-size: 40px;
}
</style>
div要素はもともとブロック要素なので、この時点でサイドバーとメインは縦に並んでいます。
ここで、floatプロパティの登場です。サイドバーの要素(class=”sidebar”)にfloat:rightを指定します。
.sidebar
{
float:right;
}
そうすると、サイドバーの水色部分が右側に移動します。floatプロパティを使って、要素の位置を動かすことに成功しました。
これまでの説明を見て、「floatは要素の位置を左右に動かせる便利なプロパティなのだ」と感じた人は多いのではないでしょうか。
しかし、実はflaotはただ要素を動かすだけのプロパティではありません。floatプロパティが他の要素に対してどのような影響を与えるのか、しっかり把握しておかないとレイアウト崩れが起きてしまいます。これから、floatプロパティのトラブルと解決法について一つひとつ見てきましょう。
前述の「メイン」と「サイドバー」の事例を見たとき、なぜ「サイドバー」の要素を先に書いて「メイン」の要素を後に書くのか不思議に思った人はいませんか。
その理由はfloatを付けた要素が、「自分の後ろにある要素を指定した値の反対に回り込ませる」からです。
例えば、float:right(右寄せ)と指定した要素の「後」に書かれた要素は、左側に回り込んで配置されます。以下の画像では、写真を配置しているimg要素にfloat:rightを設定しています。
<style>
img
{
float:right;
}
</style>
<img src=”○○”>
<p>テキスト…</p>
そのため、写真は右寄せされて、後ろに入力されたテキストが写真の左(画像の反対側)に回り込んで表示されています。
これを踏まえ、メインとサイドバーの例で以下のようなコードを書いたとしましょう。
<style>
.sidebar{ float:right;}
</style>
<div class=”main”>
ここがメイン
</div>
<div class=”sidebar”>
ここが<br>サイドバー
</div>
そうすると、表示結果は画像のようになってしまうのです。
サイドバーは先に書かれた要素の「メイン」の右側に配置されず、意図していたレイアウトとは違う表示になっているのが分かります。
これは、メイン要素がサイドバー要素の後ろではなく前に入力されているためです。floatしたサイドバーは前に入力した要素に対しては、回り込みを指定することができないのです。
そのため「メイン」→「サイドバー」という順番ではなく「サイドバー」→「メイン」という順番で要素が並んでいたというわけです。
この順番でコードを書くことで、後に来る要素の「メイン」を「サイドバー」の左に回り込ませることが可能になっていたのです。floatを使うときは、並べたい要素を書く順番に注意が必要です。
前述したとおり、floatが付いた要素は自分の「後ろ」の要素を回り込ませる性質がありました。それを踏まえたうえで、下のコードを見てください。幅300pxのA、200pxのB、500pxのCの3つのdiv要素が並んでいます。
<style>
.a{
background-color: aquamarine;
width:300px;
height: 200px;
font-size:50px;
}
.b{
background-color: beige;
width:200px;
height: 200px;
font-size:50px;
}
.c{
background-color: fuchsia;
width:500px;
height: 200px;
font-size:50px;
}
</style>
<div class=”a”>
A 300px
</div>
<div class=”b”>
B 200px
</div>
<div class=”c”>
C 500 px
</div>
この中でAとBにfloat:rightを設定すると、左方向の回り込みが行われるはずです。そして後続要素であるCは、AとBに対して右方向に回り込むことが予想されます。
.a{float:left;}
.b{float:left}
このコードの実行結果を見ると、画像のような不思議な現象が起こります。
Cの背景色が消えて、文字だけが置いてけぼりになっています。実は、消えたCの背景色は、AとBのブロックの下に入り込んでしまっているのです。これは、floatというプロパティがもつ本来の意味が関係しています。
floatというのは、もともと英単語で「浮く」という意味の動詞です。floatプロパティを指定した要素は、後続要素の上に「浮いた状態」で左右に移動しているのです。
つまり、今回の場合ではAとBはCの要素の上に浮かびながら、左に移動したのです。後続要素は、浮いている要素の隙間を埋めるようにせりあがってきます。画像の例ではAとBが浮かんで空いた空間に、Cがせりあがっています。Cの幅は500px、つまりA+Bの幅と同じだったため、ぴったり後ろに隠れてしまったのです。
では、「C 500px」という文字はどうしてそのまま残っているのでしょうか。
floatには、「後続のインライン要素や文字列を避けて浮かぶ」という性質があります。例えばimg要素(画像要素)をfloatで右に浮かせて、そのあとに文章を打ち込んだとしても、画像が文章の上にかぶってしまうことはありません。
このようなfloatの性質により、Cの背景色はAとBの後ろに隠れてしまった一方で、文字だけは浮かんだABの後ろに隠れることなく表示されているのです。floatプロパティをつけていない後続要素が隠れてしまうのは、レイアウト的に問題があります。
そこで、後続要素にたいして「floatを解除する」という方法を取る必要があります。この例では、Cに対して次のようなCSSコードを指定します。
.c{
clear:both;
}
A,Bのfloatに対し、後続要素Cが後ろ側に回り込むのを避けることができました。後続要素が浮いている要素の後ろに隠れてしまうのを防ぎたいときには、clear:bothを上手に使うようにしましょう。
floatを使う上でよく遭遇する、もう1つの問題があります。
次のようなコードで要素を作成したとします。image-boxクラスのdiv要素の中に、img要素とp要素が入っています。このとき、div要素をimgとpの親要素と呼びます。逆にimgとpはdiv要素の子要素と呼ばれます。
<div class=”image-box”>
<img src=”○○”>
<p>
テキスト…
</p>
</div>
画像を右に配置してテキストを画像の左に回り込ませるために、img要素にfloat:rightを設定します。
記事全体を囲うimage-boxは、記事が目立つように背景色(background-color)を薄水色にし、要素の角(border-radius)を少し丸みのあるものにしています。
<style>
.image-box{
background-color:rgb(176, 240, 240);
border-radius: 20px;
}
img{
float:right;
}
</style>
img後続のp要素はテキストなので、floatの性質上、画像の下に重ならずに配置され問題はないはずです。
ところが、実際には、以下のような表示になります。
画像が親要素であるimage-boxを突き破って、下にはみ出してしまいました。トラブルの原因は、floatを設定した子要素は親要素から「なかったこと」にされてしまうという性質にあります。
この例では、float:rightを設定された画像img要素は、親要素のimage-boxにとっては透明人間のような存在になっており認識されません。そのため、image-boxは認識できるp要素内のテキストに合わせて高さを決めたのです。結果高さが無視された画像はimage-boxからはみ出してしまいました。
なお、この例の場合はp要素があったためimage-boxの姿が表示されています。しかし、子要素すべてにfloatが設定されている親要素の場合、「中身がない要素」としてつぶれてしまいます。
<div class=”image-box”>
<img src=”○○”>
</div>
先のコードからp要素のみ削除して、ブラウザーで表示してみましょう。imgという子要素をもっているにもかかわらず、水色の親要素image-boxは全く表示されません。
デザインのために設定した親要素が子要素のfloatによって、知らないうちに非表示になってしまうことがあるのです。これを回避するための方法は2通りあります。
1つは親要素にoverflow:hiddenを設定することです。
.image-box{
overflow:hidden;
}
このようなコードを追加することで、画像がimage-box内にぴったり納まります。
overflowは親要素に納まりきらない子要素がある場合、「折り返し」や「スクロールバー」を設定できるプロパティです。
overflowには初期値以外の値を設定することで、floatした子要素の高さを認識できるようになるという特徴があります。この特徴を利用して、子要素のはみだしを防ぐという手法です。
clear:bothはfloatを解除し、後続要素の回り込みを回避する効果がありました。floatしている要素の後続要素にclear:bothを設定すれば、その時点でfloatは解除され、親要素は正しい高さを維持できます。
この例では、img要素の後ろにあるp要素にclear:bothを設定すれば、画像の高さを親要素に含めることができます。
p
{
clear:both;
}
ただし、その結果は以下のようになります。肝心のテキストの回り込みまで解除されてしまっているのが分かります。
そこで、p要素の下にfloat設定を解除するためのdiv要素(中身は空)を追加します。そして、このdivに対してclear:bothを設定します。
<style>
.clear
{
clear:both;
}
</style>
<div class=”image-box”>
<img src=”○○”>
<p>
テキスト…
</p>
<div class=”clear”>
</div>
</div>
画像がimage-box内にぴったり収まりました。
この<div class=”clear”>は特に中身をもたない空要素で、floatを解除するためだけに作成されました。
しかし、このような空要素をいちいち作成するのは面倒ですし、コードもごちゃごちゃしてしまいます。
そこで使われるのがclearfixと呼ばれる手法です。まず親要素image-boxにclearfix(任意の名前)というクラス名を追加します。
<div class=”image-box clearfix”>
<img src=”○○”>
<p>
テキスト部分
</p>
</div>
そして、clearfixクラスのCSSを以下のように書いていきます。
<style>
.clearfix::after{
content : “”;
display: block;
clear:both;
}
</style>
::afterというのは疑似要素とよばれるもので、本来は存在しない要素を疑似的に作り上げることができます。
.clearfix::afterコードの中身を簡単に説明すると「中身のない(content:””)ブロック要素(display:block)を作成し、clear:bothを設定する」と書かれています。
つまり、divでclear:both用の要素を作成する代わりに、疑似要素を使っている形です。このコードでも、空のdiv要素を付け足したときと同じ効果を得ることができます。
効率的なclearfixの使い方を考えてみましょう。
まずCSSコードとして、最初にCSSでclearfix::afterの設定を書いておきます。そうすると今後clearfixのクラス名を付けた親要素すべてに、この疑似要素を使いまわすことができます。
いちいち空のdiv要素を子要素として付け足すよりも、疑似要素を使った方がずっと簡単で手間がかかりません。
floatは要素を左右に配置するのに便利ではありますが、後続要素や親要素に与える影響が大きいというデメリットもありました。このfloatの癖を修正するためには、clear:bothを使いこなす必要があります。
一方、近年floatに頼らないレイアウト手法も生まれてきています。それがflexboxというプロパティを使う方法です。
flexboxではfloat以上に柔軟なレイアウトが可能です。比較的新しいプロパティなので、未対応のブラウザがあるのが欠点ですが、今後対応するブラウザが増えていくことは予想できます。これからはflexboxの使い方にも注目してください。
floatはhtml各要素を思った位置に配置するために、とても重要なプロパティです。
ただし、floatには要素を浮かせる性質があるため、後続要素や親要素に大きな影響を与えます。clear:bothプロパティを使いこなすことで、floatの挙動を制御することができます。
意図しないレイアウトになってしまったら、慌てないでfloatの性質をもう一度見直してみましょう。