CSSデザインノートでタグ「float」が付けられているもの

テキストを左右中央寄せにする場合「text-align:center;」でできますが、ulタグを用いた場合ではリストマークが揃いません。リストの先頭を揃えて、かつ、リスト全体を左右中央寄せ少しCSSに工夫が必要です。

CSSコード

ul {
   position:relative;
   float:left;
   left:50%;
}

li {
   position:relative;
   left:-50%;
}

ポイントは、「float:left;」を設定することと、相対配置で親要素を半分ずらした後に、子要素でさらに元の方向にその半分をずらすことで、全体的に真ん中に配置するテクニックを使うことです。

「float」を使うことで、ulに本来指定されていたdisplayプロパティ(display:block;)が無視される(つまり内容物の範囲しかブロックボックスが存在しなくなる)ため、内容物(li内のテキスト)の横幅を基準に中央寄せにすることが可能となります。

例えば、Amazonのアフィリエイトみたいに、書籍の画像と説明文を横並びにする方法です。 説明文が長いとき画像の下に回りこまないのが美しいですよね。方法は二通りあります。

  1. marginで指定
  2. overflowで指定

以下にサンプル画像を示します。

サンプル画像

基本の(X)HTMLコードは以下のようになります。

(X)HTMLコード


<div class="column">
<img src="image.gif" alt="" />
<p>
テキストテキストテキストテキストテキスト
・・・(略)・・・
テキストテキストテキストテキストテキスト
</p>
</div>

1.marginで指定

画像の横幅が固定の場合は、その大きさ分をmarginで空けます。

CSSコード

.column img{
   float:left;
}

.column p{
   margin-left:160px;
}

この場合、次の要素も回り込んだままなので、clearなどを指定して回り込みを解除しなければなりません。

2.overflowで指定

画像の横幅が未知の場合は、余白を固定することが出来ません。overflowを使用することで、テキストが回り込まなくなります。

CSSコード

.column img{
   float:left;
}

.column p{
   overflow:hidden;
   zoom:1;
}

「zoom:1;」はIE6でレイアウトが崩れるのを防ぐために指定します。

横並びのメニューで、左側あるいは右側にmarginで余白を空けた際、最初あるいは最後のメニュー部分だけ余白は必要ではありませんよね。classを指定しないで余白を消す方法です。

横並びのメニュー

first-childあるいはlast-childセレクタを使用すれば簡単に実現できますが、IE6など一部のブラウザでは対応していません。そこで、ネガティブマージンを使用することで、無駄にclassを指定することなく、最後の余白だけ消すことが出来ます。

(X)HTMLコード

<div class="menu">
<ul>
<li>メニュー1</li>
<li>メニュー2</li>
<li>メニュー3</li>
<li>メニュー4</li>
</ul>
</div >

CSSコード

div.menu {
   width:430px;
   border: solid 1px #000;
}

div.menu ul {
   margin:0;
   padding:0;
   margin-right:-10px;
   overflow:hidden;
   list-style:none;
   zoom:1;
}

* html div.menu ul { /* for IE6 */
   margin-right:-20px;
}

div.menu ul li {
   float:left;
   width:100px;
   margin-right:10px;
   padding:10px 0;
   text-align:center;
   background:#ddd;
}

liにmargin-right:10px;を指定して右側に余白を空け、ulにmargin-right:-10px;を指定してリストの一番右側の余白を相殺します。

IE6ではfloatしたボックスのmarginの値が2倍になるバグがあるので、* htmlハックを利用してIE6用に、2倍の-20pxをulの右側の余白に指定します。このバグを回避する方法はいくつかあるのですが(例えば「display:inline;」を指定する)、今回はこのような処置を取ります。

IE6でネガティブマージンを有効にするために「zoom:1;」を指定します。これはhasLayoutプロパティの値をtrueにするためです。hasLayoutに関しては、以下のサイトなどを参考にしてください。

floatを解除するのに「overflow:hidden;」を使用していますが、以下のページに書いてあるような方法でも構いません。

例えば、リストで作成したメニューをfloatで横並びにした場合、親要素(ここではul)の内容が表示されません。ulの内容物が表示されないと、背景やborderが表示されなかったり、marginが効かなかったりして不便です。

その解決方法としては以下の4つがあります。

  1. 親要素にもfloatを指定する
  2. 親要素にoverflowを指定する
  3. 親要素に高さを指定する
  4. 親要素にclearfixを指定する

1.親要素にもfloatを指定する

親要素に「float:left;」を指定することで、親要素の高さが算出され、内容物が表示されます。ただし、floatした次の要素は回り込まれたままなので、解除するには「clear:both;」を次の要素に指定する必要があります。

2.親要素にoverflowを指定する

親要素に「overflow:hidden;」を指定することにより、高さが算出されます。回り込みは解除されています。IE6は「zoom:1;」を同時に指定しないと高さが算出されないので注意です。

3.親要素に高さを指定する

親要素の高さが固定の場合は、heightで高さを指定するとよいです。この場合、次の要素は回り込みは解除されていないのですが、指定した高さが内容物より大きければ、次の要素は下段に表示されます。

4.親要素にclearfixを指定する

clearfixというハックを使用することで、親要素の高さが算出されます。比較的古いブラウザにも対応しているので便利です。clearfixは次の要素の回り込みを解除します。

CSSコード

/* モダンブラウザ(Firefox Opera Safari)対策 */
.clearfix:after{
   content:".";
   display:block;
   height:0;
   clear:both;
   visibility:hidden;
   font-size:0;
}

/* Win版IE7とMac版IE5対策 */
.clearfix{
   display:inline-block;
}

/* Win版IE5および6対策 */
/* Hides from IE-mac \*/
* html .clearfix{
   height:1px;
}

.clearfix{
   display:block;
}
/* End hide from IE-mac */

各方法で若干、余白や表示領域に差が出ますので、CSSで調節してください。

floatを使用してボックスやリストを横並びにした時、次のコンテンツも続いて横並びになってしまうので、回り込みを解除しなければなりません。

また、floatした親要素の内容が0になってしまい、親要素に背景やborderを適用しようとしても表示できません。

これを簡単に解決する方法がいくつかあります。

  1. 次のコンテンツに「clear」を指定する
  2. 親要素に「clearfix」を使用する
  3. 親要素に「overflow」を指定する

まず、サンプルとして共通の(X)HTMLコードを示します。

(X)HTMLコード

<div id="menu">
<ul>
<li>メニュー1</li>
<li>メニュー2</li>
<li>メニュー3</li>
<li>メニュー4</li>
<li>メニュー5</li>
</div>
<div id="contents">
・・・
</div>
</ul>

1.次のコンテンツに「clear」を指定する

回り込みを解除したい要素に「clear:both;」を指定します。

CSSコード

div#contents {
   clear:both;
}

2.親要素にclearfixを使用する

floatの親要素の高さを算出するメジャーな方法に「clearfix」と呼ばれるテクニックがあります。これを考えた人はすごいです。

CSSコード

div#menu {
   margin:0;
   padding:0;
}

div#menu li {
   float:left;
   list-style:none;
}

/* モダンブラウザ(Firefox Opera Safari)対策 */
div#menu :after{
   content:".";
   display:block;
   height:0;
   clear:both;
   visibility:hidden;
   font-size:0;
}

/* Win版IE7とMac版IE5対策 */
div#menu {
   display:inline-block;
}

/* Win版IE5および6対策 */
/* Hides from IE-mac \*/
* html div#menu {
   height:1px;
}

div#menu {
   display:block;
}
/* End hide from IE-mac */

3.親要素にoverflowを指定する

overflowを親要素に指定することにより、高さが算出されます。値はauto、hidden、scrollのいずれかを使用します。

CSSコード

div#menu {
overflow:hidden;
}

確認はしていないのですが、「overflow:hidden;」を使用した場合、ブラウザのバージョン(特に古いバージョン)によっては正常に動作しなかったり、印刷時に問題があったりすることもあるようです。

参考サイト

そのほかにもいろいろとfloatを解除する方法があるようです。

例えば、フッターメニューやblogのページャー(ページネーション/ページ切り替えメニュー)をリストで作成し、floatで横並びした際、メニュー全体をセンタリングさせようと思っても、「margin:0 auto;」や「text-align:center;」など一般的にセンタリングさせる方法が効きません。

その場合、「position:relative」で位置をコントロールするとうまくいきます。

(X)HTMLコード

<div id="menu">
   <ul>
   <li>メニュー1</li>
   <li>メニュー2</li>
   <li>メニュー3</li>
   <li>メニュー4</li>
   <li>メニュー5</li>
   </ul>
</div>

CSSコード

div#menu {
   position:relative;
   overflow:hidden;
}

div#menu ul {
   position:relative;
   left:50%;
   float:left;
}

div#menu li {
   position:relative;
   left:-50%;
   float:left;
}

参考サイト

floatを使用して横並びにした多段カラムの高さが違う場合、ボックスの下辺を揃えるには画像を利用します。

サンプル

左のボックス
余白
余白
余白
余白
余白
真ん中のボックス
右のボックス

(X)HTMLコード

<div class="wrapper">
   <div class="contents">左のボックス<br />余白<br />余白<br />余白<br />余白<br />余白</div>
   <div class="contents">真ん中のボックス</div>
   <div class="contents reset">右のボックス</div>
</div>

CSSコード

div.wrapper {
float:left;
width:320px;
background:url(bg_bottom.gif) 0 100% no-repeat;
}

div.contents {
float:left;
width:100px;
margin-right:10px;
border-top:1px solid #333;
}

div.reset {
margin-right:0;
}

カラムを横並びにする方法は当サイトの以下の記事を参考にしてください。

2段カラムの作り方(float編) - CSSデザインノート

カラムを囲っているdiv要素に以下のような画像を指定します。ポイントは、縦幅が高くてもきちんと表示されるように長めに画像を作ることです。

枠の画像

今回は四角い枠で囲んでいるタイプなので、各カラムの上部にborderをつけていますが、画像でも問題ありません。

カラムの右側にmarginで余白を空けているのですが、最後のカラムの右側のmarginは0にしておきます。これはカラム落ちになるのを防ぐためです。

ここでは記述していませんが、このfloatボックスの次に何か要素がある場合、その要素も回り込んでしまうので、「clear:both;」で回り込みを解除してください。

この方法は、画像をきっちり1pxもずらさずに作らないといけないので結構面倒ではあります。

基本的な2段カラムのテンプレートの作り方を紹介します。ヘッダー、コンテンツ(2段カラム)、フッターからなるテンプレートです。

(X)HTMLコード

<div id="top">
   <div id="header">header</div>
   <div id="contents">
      <div id="mainContents">mainContents</div>
      <div id="subContents">subContents</div>
  </div>
   <div id="footer">footer</div>
</div>
</body>
</html>

CSSコード

body {
   margin:0;
}

div#top {
   width:750px;
   margin:0 auto;
}

div#contents {
   float:left;
   width:750px;
}

div#mainContents {
   float:left;
   width:600px;
}

div#subContents {
   float:right;
   width:150px;
}

div#footer {
   clear:both;
}

HTML、CSSは最低限必要なソースコードです。レイアウトを体裁したい場合は、paddingなどの指定も必要となります。

まずHTMLソースコードですが、テンプレート全体を囲んだほうがデザインに幅が出ます。ここでは<div id=#top"></div>になります。なぜid名がtopなのかというと、ページのトップの戻りリンク先にも併用できるためです。別の名前でももちろん構いません。

2段カラム部分も囲みます。<div id="contents"></div>の部分です。これも先ほどと同様デザインに幅が出るためです。例えば、2段カラムの縦の長さが違っても、カラムの一番下まで背景画像を繰り返し表示できます。

続いて、CSSソースコードを説明します。2段カラム部分(<div id="mainContents"></div>と<div id="subContents"></div>)はfloatにより横並びにします。

また、2段カラムを囲んでいるcontetnsにもfleatを指定します。これによりcontetns領域が2段カラムをちゃんと囲めるようになり、カラムの一番下まで背景画像を繰り返し表示することなどが可能になります。これはCSSの仕様により、フロートボックスの親要素(この場合はdiv#contetns)は子要素の中身がないと計算されてしまうので、div#contetns自身にもfloatを適用することにより子要素の中身が計算されるようになります。

そしてdiv#footerで「clear:both;」を指定して回り込み(というか浮いている状態)を解除します。

注意点ですが、floatを指定した要素には必ずwidthにauto以外の値を指定しなければ内容が0になってしまいます。

CSS2.1の仕様では、内容に合わせて縮めた値になります。

10.3.5 Floating, non-replaced elements
If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.

Visual formatting model detailsより引用

最近のブログ記事