レイアウトの最近のブログ記事

コンテンツ量が少なくても常に縦スクロールバーを出す方法は、昔に以下の記事を書きました。

これらの記事を書いてから約2年が経ち、ブラウザの実装状況も変わってきました。

2010年5月現在は、主要の最新ブラウザで、以下の記述で、コンテンツ量が少なくても常に縦スクロールバーを出すことができます。

CSSコード

html {
   overflow-y:scroll;
}

最新のブラウザならCSS3の草案を取り入れているようですね。

また、以前は有効であったhtmlの高さを100%にし、マージンを1px空けて、縦スクロールバーを出す方法はFirefox3.6.3では効かなくなっていたので注意です。今のところ他のブラウザ(safari、Opera、Chome)には有効のようです。

CSSコード

html {
   height:100%;
   margin-bottom:1px;
}

マルチカラム構造にしたときなど、ブロック要素の回り込みを解除するのに、Clearfixと呼ばれるテクニックを使用するのが便利です。ブラウザの移り変わりにより、動作対象とする古いブラウザを考慮しなくなってもよくなってきたこの頃ですので、Clearfixのソースコードも以下のようにここまでスリムになりました。

CSSコード

element{
   ⁄zoom:1;
}

element:after {
   content:'';
   display:block;
   clear:both;
}

これはNetScapeとMacのIEを考慮していないソースコードになります。「/zoom:1;」のようにプロパティの前にスラッシュをつけるとIE6と7だけに適用されるようです。今まで知りませんでした。

このclearfixを使う他に、単純に回り込みを解除させたい要素に「overflow:hidden」を適用すればよいというのもあります。印刷時に問題があるらしいのですが、印刷用のCSSを用意する場合は「overflow:auto;」などとしておけばよいので、結構使える技ではあります。

参考

ホームページのデザインによっては、コンテンツ部分が少ないとフッターの下に余白ができてかっこ悪くなる場合があります。 そのような場合には、フッターを固定する事でデザインのくずれを防ぐことができます。

ポイントは「フッター以外の要素を囲むブロック要素」と「フッターを囲む要素」を作る事です。このブロック要素にpading-bottomで、フッター分の余白を設け、フッターをposition:relativeで位置を決めます。ここで重要な事はフッターの縦の大きさは固定でなければならないということです。

サンプル

当サイトで配布しているCSSテンプレート「pub002」をフッター固定にしてみました。

動作確認

Firefox3.5.8、Google Chrome 4.0、Safari 4.0.4、Opera 10.10、IE6 for Windows XPです。

(X)HTMLコード

<div id="top">
   <div id="header"></div><!-- header end -->
   <div id="contents">
      <div id="main"></div><!-- main end -->
      <div id="sub"></div><!-- sub end -->
   </div><!-- contents end -->
</div><!-- top end -->
<div id="footerWrap">
   <div id="footer">
      <div id="totop"></div>
      <div id="footerMenu"></div><!-- footerMenu end -->
   </div><!-- footer end -->
</div><!-- footerWrap end -->

CSSコード

/* ========FOOTER FIX======== */
* {
   margin:0;
}

html,
   body,
   div#top {
   height:100%;
}

body > div#top {
   height: auto;
   min-height: 100%;
}

div#contents {
   padding-bottom:150px;/* フッターの高さと同じ値にする */
}

div#footerWrap {
   position:relative;
   margin-top:-150px;/* フッターの高さと同じ値にする */
   height:150px;/* フッターの高さを指定 */
}

以前、IE6でもposition:fixedと同じ動作をさせるというコラムを書きましたが、実際にデザインしているときに不具合に気づきました。

例えば、fixはしたくないけどもposition:absoluteで絶対配置したいボックスが、スクロールすると画面に固定になってしまうのです。当たり前なのですが。

よってIEの場合、スクロールするためのdivボックス(scrollボックス)を用意し、fix表示したいボックスはscrollボックスより外に出すようにしなければなりません。 scrollボックスでスクロールするようにしているので、htmlおよびbodyではスクロールしないようにします。

ソースコードは以下のとおりです。

(X)HTMLコード

<div id="scroll">
   <div id="contents">
      <div class="absolute">絶対配置で表示したい要素</div>
   </div><! -- /contents -->
</div><! -- /scroll -->
<div id="fix">固定したい要素</div>

CSSコード

/* IE6用 */
* html ,
* html body {
   height:100%;
   overflow:hidden;
}

* html #scroll {
   position:relative;
   width:100%;
   height:100%;
   overflow-y:auto;
   overflow-x:hidden;
}

/* 共通 */
div#contents {
   position:relative;
}

div#absolute {
   position:absolute;
   top:0;
   right:0;
}

div#fix {
   position:fixed;
   top:100%;
   right:100%;
}

/* IE6用 */
* html div#fix {
   position:absolute;
}

参考サイト

例えば、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でレイアウトが崩れるのを防ぐために指定します。

[追記:2009/12/29]
デザインによっては動作不良を起こす事がわかりました。改訂版を用意したのでそちらもあわせてご覧ください。

[追記ここまで]

Webページをスクロールしても、ある要素を固定した位置で表示したいときがあります。例えば、「ページのトップへの戻り」のリンクやヘッダーメニューなどです。

固定配置をするためには「position:fixed;」を使用します。しかし、IE6ではfixedはサポートされていません。そこでCSSを駆使して、IE6でも擬似的に「position:fixed;」と同じ動作するように指定します。

ポイントは、普通スクロールする際、htmlタグのスクロールを使用しているのですが、それを非表示にしてbodyをスクロールさせます。

(X)HTMLコード

<div id="totop">ページのトップへ戻る</div>
<div id="text"> 
<p>テキストテキスト</p>
<p>テキストテキスト</p>
(略)
<p>テキストテキスト</p>
<p>テキストテキスト</p>
</div>

最低限必要なCSSソースコードです。

CSSコード


#totop {
   position:fixed;
   right:0;
   bottom:0;
}

/* IE6用 */
* html {
   overflow:hidden;
}

* html body {
   height:100%;
   overflow:auto;
   margin:0;
}

* html #totop {
   position:absolute;
   right:16px;
}

注意点は、右の基点が、IE6ではブラウザの右端に対して、Firefoxなどの他のブラウザは、スクロールバーを含まない右端になります。つまり、IE6ではright:0を指定するとスクロールバーと要素が重なってしまいます。rightで位置を指定する場合、上記の例で言うと、IE6では「* html #totop」で指定、その他は「#totop」で指定します。

子セレクタは親要素の直下の子要素のみに適用されるセレクタです。しかし、IE6では子セレクタは 実装されていません。しかし、子孫セレクタをうまく組み合わせることで、擬似的に子セレクタと同様の動作をすることが可能です。

(X)HTMLコード

<div class="section">
   <p>
      直接の子要素なので子セレクタが適用されます。文字色は赤です。
   </p>
   <div>
      <p>
         直接の子要素ではありません。文字色は緑です。
      </p>
   </div>
</div>

CSSコード

div.section p  {
   color:red;
}

div.section * p {
   color:green;
}

まず、子セレクタとして適用したいスタイルを、子孫セレクタで指定します。

さらにこの子孫セレクタを上書きします。子孫セレクタの途中に、特定の要素ではなくアスタリスク (*) を入れると、ワイルドカードの役割を果たします。

つまりこの場合、"クラス「section」を指定されたdiv要素の、任意の子孫要素(*) の、さらに子孫要素である p 要素にスタイルシートを適用する"となります。

要は、親要素の直下以外の孫子要素にスタイルが適用されるということです。

参考サイト

例えば、リストで作成したメニューを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;
}

参考サイト