floatプロパティ
floatを使うことができる要素はブロックレベル要素だけです。
ブロックレベル要素とインライン要素
一般にタグというのは、ブロックレベル要素とインライン要素の二つに大きく分類でき、インライン要素には"a"のように幅や高さの指定できないものもあります。
またブロックレベル要素でなければhtml strictやxhtml strictのbody直下に置く事はできません。
| ブロック要素 | h,p |
| ul,ol | |
| div | |
| hr | |
| table | |
| address | |
| インライン要素 | i,b,s |
| em,strong | |
| a | |
| img | |
| br | |
| iframe | |
| sub | |
| span | |
| input | |
| textarea |
ブロックレベル要素のタグを並べて記述すると自動的に改行されますが、インライン要素のタグは並べると改行されずに横並びになってしまいます。
ブロック型のメニューを作りたいときは、下のようにインライン要素をブロックレベル要素に変える必要があります。
floatを使った配置
floatプロパティを指定したいブロックレベル要素に対して
/* CSS */
a {
display:block; /* aはinlineをblockへ */
float:left; /* 左に回りこみ(右はright) */
}
のように指定するだけです。
簡単そうに見えますが、実際に使ってみると
- floatで回り込みした要素の次の要素がきちんと配置されない
- width(幅)の設定ミス(もしくはミスしたつもりないのに)でカラム落ち
の大きく2点でつまづくことになるかと思います。
実際に確認するため、サンプル(index.html)のbody内を全面改装します。最初はdivによる骨格作りからはじめます。
<!-- XHTML1.0、HTML5共通 -->
<body>
<div id="a1234">
<div id="a1">
</div>
<div id="a23">
<div id="a2">
</div>
<div id="a3">
</div>
</div>
<div id="a4">
</div>
</div>
</body>
骨格だけだと幅も高さも指定していないので以下の左図のようになっています。(高さ無視してます)
このdivにwidthを指定して右図のように整理します。floatによるレイアウトを行う場合は幅をきちんと指定しておくことが重要です(図でいう全てのdiv要素に)。
図で言うa2とa3にfloatプロパティを適用して横並びにします。
a4の位置がなんか変じゃない?と思うと思います。これが流し込みで、floatによる流し込みとはfloatされるボックスの高さが異なるとき、本当ならa2の下に配置されなければならないa4が、右の高さの低いボックスの後に流し込まれてしまうと言うことを意味します。
floatの流し込みを解除する
流し込みを解除するためには、floatを指定した要素の後の要素に対して、clear:both;を指定します。
/* CSS */
#a4 {
clear:both;
}
clearfix(クリアフィックス)
a4のような次に続く要素がなく、clear:bothを指定できない時は、after擬似要素を使って後に続く要素を擬似的に生成し、そこにclear:bothを指定します。
/* CSS */
.clearfix:after {
content: ".";
display: block;
clear: both;
height: 0;
visibility: hidden;
}
.clearfix {
min-height: 1px;
}
* html .clearfix {
height: 1px;
/*\*//*/
height: auto;
overflow: hidden;
/**/
}
この例でもしa4がなかったら、a23に対してclass="clearfix"を指定して、contentプロパティでピリオドを生成、ピリオドはインライン要素なので、ブロックレベル要素にして、ピリオドをheightとvisibilityで見えなくして、それにclearを指定すると、diva23の直前に擬似的なブロック要素が生成して回り込みを解除できる。
他の記述はMacやらIEの古いのやらに対応させるスターハック命令です。
この記述法はclearfix(クリアフィックス)と呼ばれています。
clearfixの記述の方法は実に様々で、検索してもサイトにより書き方が微妙に違くてかえって悩んでしまうことがあるかもしれません。実は上の記述はもっとも短くまとめようとするならば、
/* CSS */
.clearfix:after {
content: "";
display: block;
clear: both;
}
.clearfix {
zoom:1;
}
のように書くことができます。
最初の記述の代入コンテンツがピリオドなのはNetscapeに対応させるためらしく、Netscapeなんか使っている人がもはやいないであろう今(2012)においてはピリオドである必要はないとのこと。
ピリオドにすることでheightやvisibilityを指定しなければいけなくなって行が増えるので、コンテンツは空にしておきます。
zoom:1のところはIE6、7用の記述です。IE6,7がafterに非対応であることへの対処としての記述です。zoomはIEの独自仕様です。スターハックはスタープラスハックでそれぞれ記述しても問題ありません。
そもそもなぜzoomなのか?
IEはhasLayoutというプロパティ持っていて、これがfalseだと他の要素に影響されて幅や高さが広がりますが、trueだと他の要素関係なく親要素に高さを出すことができます。 初期状態ではfalseになっていますので高さの低いBOXのほうへ回り込んでしまいますが、trueにすれば親自体が高さを持つので回り込むことはありません。
このhasLayoutプロパティをtrueにするには、親要素に対して下記の値をどれか一つ設定する必要があります。
| プロパティ | value |
|---|---|
| display | inline-block |
| height | any value |
| float | left or right |
| position | absolute |
| width | any value |
| -ms-writing-mode | tb-rl |
| zoom | any value |
この中で一番汎用性が高いのがzoomということで、zoom:1を指定しています。(any valueはauto以外の値なんでもということ)
コンテンツの代入
ここまでのことを踏まえて、div骨格の中に今まで作ってきた果物のコンテンツを入れていきましょう。
<!-- XHTML1.0、HTML5共通 -->
<body>
<div id="a1234">
<div id="a1">
<h1>果物info</h1>
<ul id="b1">
<li>トップページ</li>
</ul>
</div>
<div id="a23">
<div id="a2">
<ul id="b2">
<li>りんご</li>
<li>みかん</li>
</ul>
</div>
<div id="a3">
<h2>りんごについて</h2>
<p>リンゴの木は、落葉高木で晩春頃に白い5弁花が開花する。リンゴの果実は直径約3-15 cm、重さ約35-1000 g。色は赤や黄緑で、または黄色をしている。熟すると蝋状の分泌物に覆われる。</p>
<h3>りんごの種類</h3>
<ul class="b3">
<li><a href="apple/apple1.html">ふじのページへ</a></li>
<li>ゴールデンデリシャス</li>
</ul>
<h3>りんごの栄養</h3>
<p>食物繊維やビタミンC、ミネラル、カリウムが豊富。1日1個のリンゴは医者を遠ざける (An apple a day keeps the doctor away.)という諺があるように、リンゴは栄養価が高い果実として食されてきた。</p>
<p>リンゴに含まれるリンゴポリフェノールには脂肪の蓄積を抑制する効果があるともいわれる</p>
<table>
<tr>
<th colspan="3">りんごの栄養素一覧</th>
</tr>
<tr>
<td rowspan="2">ビタミン</td>
<td>ビタミンC:4mg/100g</td>
</tr>
<tr>
<td>ビタミンB1:0.02mg/100g</td>
</tr>
<tr>
<td>ミネラル</td>
<td>カリウム:110mg/100g</td>
</tr>
</table>
<h2>みかんについて</h2>
<p>甘い柑橘ということから漢字では「蜜柑」と表記される。古くは「みっかん」と読まれたが、最初の音節が短くなった。</p>
</div>
</div>
<div id="a4">
<p><small>Copyright © 2012 nkdesk all right reserved.</small></p>
</div>
</div>
</body>
ちょこちょこ内容変えたのでコピーして書き換えてもいいかもしれません。
このまま表示させてみると、サンプル。
IE6のマージンに関するバグ
そしてスタイルシート(style.css)をいじってfloatによるレイアウトをして見ましょう。
floatするボックスに対して左右のmarginは指定しないでください。IE6でfloatされた要素へのマージンが2倍(margin-left:10pxとしたのに実際は20pxになる)に広がるため、カラム落ちします。
/* CSS */
@charset "UTF-8";
* {
border:0;
margin:0;
padding:0;
line-height:1.5em;
font-weight:normal;
font-style:normal;
}
body {
text-align:center;
background:#eef;
}
#a1234,#a1,#a23,#a4 {
width:600px;
}
#a1234 {
margin:auto;
text-align:left;
}
#a1 {
}
#a23 {
margin-top:10px;
}
#a2 {
width:150px;
float:left;
}
#a3 {
width:450px;
float:right;
}
#a4 {
clear:both;
background:#333;
}
h1,h2,h3 {
font-weight:bold;
}
h1 {
font-size:28px;
background:#333;
color:#fff;
border-bottom:solid 5px #fff;
margin-top:10px;
padding-left:20px;
}
h2 {
width:430px;
font-size:18px;
border-left:solid 10px #000;
border-bottom:solid 1px #000;
background:#fff;
padding-left:10px;
color:#000;
}
h3 {
width:420px;
font-size:16px;
margin-top:10px;
border-left:solid 10px #000;
border-bottom:dotted 1px #000;
padding-left:10px;
}
p {
width:420px;
font-size:15px;
margin:5px 0 5px 12px;;
}
p small {
font-size:14px;
color:#fff;
}
table,th,td {
width:350px;
border:solid 1px #00f;
border-collapse:collapse;
}
table {
margin:10px 0 20px 12px;
}
th {
background:#55f;
color:#fff;
}
td,th {
padding:2px 5px;
}
ul#b1,ul#b2,ul.b3 {
text-align:left;
list-style-type:none;
}
ul#b1 li:before {
margin:0 3px;
content:">";
}
ul#b2 li {
display:block;
width:120px;
background:#333;
margin:0 0 2px 0;
padding:1px 5px;
color:#fff;
}
ul.b3 {
margin-left:12px;
}
ul.b3 li {
padding-left:20px;
background:url(../gif/point.gif) left center no-repeat;
}
適用後のサンプル。
先ほどIE6の表示バグのためにmarginを指定しないようにと言いましたが、実はmarginを指定できるようにすることもできます。それはfloatする要素に対してdisplay:inlineを指定することです。
リスト要素の回り込みを例にすると、
<ul> <li><a href="#">menu1</a></li> <li><a href="#">menu2</a></li> </ul>
ul {
width:600px;
}
li {
width:250px;
float:left;
display:inline; //liはもともとinline要素なので書く必要なさそうだけど。。。
margin:10px 25px;
}
li a {
display:block;
postion:relative;
}
のようになります。inline要素をfloatできるの?という疑問がわきますが、何やらfloatされた要素のdisplayは無視されるらしいので、inlineでもきちんとフロートされます。
であればwidthだって指定できちゃう。li aにwidth指定はコンテンツがはみ出たりするのでご法度。
li aにdisplay:blockとrelativeの指定をするのはテキストコンテンツをボタンっぽく表示させたりするときにマウス範囲を広げるための記述。画像ならいらないかも。
コメントor補足情報orご指摘あればをお願いします。
- << 前のページ
- 次のページ >>
