CSS レイアウト
作成日:2015年5月30日
関連ページ
- レイアウト2
- レスポンシブ Web デザイン 作成資料
- Flexible Box Layout
- CSS Grid(display:grid)の使い方
- CSS Grid + JavaScript で Masonry レイアウト
絶対配置を利用したレイアウト
絶対配置の特徴は、HTML 文書の構造に依存しない配置が可能なことです。最下部に記述された要素を、表示上では一番上に配置させることもできるなど、自由なボックスの配置が可能です。
絶対配置を利用したカラムレイアウト
最終的には以下のようなページのレイアウトを作成します。
実際のサンプル: layout_01_final.html
以下は HTML の記述(構造)です。
h1 要素の見出しがあり、その後に div 要素(#container)が続きます。
div 要素(#container)の中には、div 要素(#main)と div 要素(#navi)があります。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Layout Sample 1</title> </head> <body> <h1>Position Layout</h1> <div id="container"> <div id="main"> <h2>HTML</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Provident, aperiam et veritatis officiis beatae iste earum totam dolores eaque...</p> <h2>CSS</h2> <p>Enim voluptate at sed culpa debitis error similique voluptatum labore asperiores!...</p> <h2>jQuery</h2> <p>Dolorum, praesentium, reprehenderit, id labore excepturi dolorem provident alias vel animi at dolores eius corporis adipisci asperiores ...</p> <h2>PHP</h2> <p>Quasi, natus, iusto, eveniet repudiandae maxime non obcaecati tenetur omnis dolorem dolorum atque molestiae cupiditate. ...</p> <h2>WordPress</h2> <p>Voluptatibus, quas a nulla sunt assumenda consectetur dolor illum optio unde nisi! Ea, aliquam, qui?...</p> </div><!-- end of #main --> <div id="navi"> <ul> <li>HTML</li> <li>CSS</li> <li>jQuery</li> <li>PHP</li> <li>WordPress</li> </ul> </div><!-- end of #navi --> </div><!-- end of #container --> </body> </html>
CSS を何も設定しない場合、以下のように表示されます。
実際のサンプル: layout_01_1.html
各要素に背景色やボーダーを以下のように設定してみます。
body { background-color: #ccc; } #container { background-color: #E4F5DA; border: 1px solid #aaa; } #main { background-color: #fff; } #navi { background-color: #48722E; } h1 { color: #666; font-weight: normal; } h2 { color: #999; background-color: #eee; } p { color: #999; } ul { color: #E1F8AF; }
上記の CSS の設定により、以下のように表示されます。
ブロックレベル要素は親要素の幅いっぱいに広がり、div 要素(#main)と div 要素(#navi)は通常フローに従って、垂直方向に記述順に配置されています。
また、マージンやパディングを指定していないので、ブラウザのデフォルトのマージンやパディングの設定が適用されています。
実際のサンプル: layout_01_2.html.html
ここで少し実験として、ユニバーサルセレクタを使って、以下のように全てのマージンを 0 に指定みます。
* { margin: 0; }
するとブラウザのデフォルトのマージンが 0 になり、以下のように表示が変わります。
実際のサンプル: layout_01_2_2.html
これは単なる実験なので、上記のユニバーサルセレクタを使った指定は削除します。
続いて、以下のように幅やマージン、パディング、フォントのサイズを指定してみます。
body { background-color: #ccc; margin: 1em 20px; /* 追加 */ } #container { width: 800px; /* 幅 追加 */ background-color: #E4F5DA; border: 1px solid #aaa; } #main { padding: 0.2em 0; /* 追加 */ background-color: #fff; } #navi { width: 200px; /* 幅 追加 */ padding: 0.2em 0; /* 追加 */ background-color: #48722E; } h1 { color: #666; font-weight: normal; font-size: 1.875em; /* 追加 */ } h2 { color: #999; background-color: #eee; margin: 0.8em 16px; /* 追加 */ padding: 0.2em 16px; /* 追加 */ font-size: 1.25em; /* 追加 */ } p { color: #999; margin: 1em 16px; /* 追加 */ line-height: 1.6; /* 追加 */ font-size: .875em; /* 追加 */ } ul { color: #E1F8AF; margin: 0.8em 16px; /* 追加 */ padding: 0; /* 追加 */ } li { margin: 0.2em 8px; /* 追加 */ font-size: .875em; /* 追加 */ }
表示は以下のようになります。
実際のサンプル: layout_01_3.html
次に div 要素 #navi に position: absolute を指定し、基点からの距離を top、left プロパティで指定します。これにより、div 要素 #navi は通常フローから外れて絶対配置されます。
このときの基点は、ルート要素の初期包含ブロックになり、表示領域(ウィンドウ)の原点からの距離を top、left プロパティで指定します。
#navi { width: 200px; padding: 0.2em 0; background-color: #48722E; position: absolute; /* 絶対配置を指定 */ top: 86px; /* 基点からの上方向の距離 Firebug等で確認可能*/ left: 20px; /* 基点からの左方向の距離 */ }
表示は以下のようになり、div 要素 #navi は top, left で指定した位置に配置され、div 要素 #main の一部はその背後に隠れます。
実際のサンプル: layout_01_4.html
隣接するボックスは、絶対配置されたボックスが存在しないかのように通常フローに従って配置されるので、div 要素 #main は絶対配置した div 要素 #navi と重なっています。
ここで、重なった div 要素 #main にマージンを指定し、 div 要素 #navi の置かれる領域を確保することでカラムレイアウトを作成することができます。
以下のように div 要素 #main にマージンを指定します。この例の場合、div 要素 #navi には左右のマージンやパディングの余白が指定されていないので、その幅の分だけマージンを指定していますが、マージンやパディングが指定されていればその分も考慮に入れる必要があります。
#main { padding: 0.2em 0; background-color: #fff; margin-left: 200px; /*#navi の幅と余白(0)を足した分のマージン*/ } #navi { width: 200px; padding: 0.2em 0; background-color: #48722E; position: absolute; top: 86px; left: 20px; }
実際のサンプル: layout_01_5.html
絶対配置の基点を変える
前項で作成したカラムレイアウトでは、div 要素 #navi はルート要素を基点として絶対配置したので、中央寄せに変更したいと考えたとき、ルート要素が基点では絶対配置したボックスは、中央に寄る他のボックスに追従させることがません。
ボックスが絶対配置する際に基点となる包含ブロック
- position の値に static 以外の値を指定された、最も近い祖先ボックス
- 該当するボックスが存在しない場合は、ルート要素の生成する初期包含ブロック
これは、祖先ボックスの中から任意のボックスを基点となる包含ブロックに設定できることを意味します。
絶対配置する際、祖先ボックスの中から構造的に関係の近いボックスに「relative」を指定して基準とすることで、より頑丈で柔軟性のあるレイアウトを組むことができます。
マージンとブロックレベル要素のセンタリング
ブロックレベル要素の左右のマージンについて、値に「auto」を指定することで、その要素全体をセンタリングできる。
但し、そのブロックレベル要素に幅が指定されている必要があります。
div 要素 #container を以下の指定で中央寄せします。
#container { width: 800px; background-color: #E4F5DA; border: 1px solid #aaa; margin: 0 auto; /* 中央寄せ */ }
div 要素 #container は中央寄せされましたが、div 要素 #navi はルート要素を基点として絶対配置されているので、中央に寄る他のボックスに追従させることがません。
実際のサンプル: layout_01_6.html
そこで、div 要素 #navi の親要素である div 要素 #container に「position: relative」を指定し、div 要素 #navi が絶対配置する際の基点となるように設定します。
div 要素 #navi の位置は div 要素 #container が基点になるので、top, left の値を変更します。
また、h1 要素も中央寄せするために、幅とマージンを設定します。
#container { width: 800px; background-color: #E4F5DA; border: 1px solid #aaa; margin: 0 auto; position: relative; /* 基点に設定 */ } #navi { width: 200px; padding: 0.2em 0; background-color: #48722E; position: absolute; top: 0; /* 基点(#container)からの上方向の距離 */ left: 0; /* 基点(#container)からの左方向の距離 */ } h1 { color: #666; font-weight: normal; font-size: 1.875em; margin: 0 auto 15px auto; /* 中央寄せ (下方マージン 15px 追加) */ width: 800px; /* 中央寄せ (幅を指定する必要がある)*/ }
これで完成です。
実際のサンプル: layout_01_final.html
最終的な CSS は以下のようになります。
body { margin: 1em 20px; background-color: #CCC; } #container { width: 800px; background-color: #E4F5DA; border: 1px solid #aaa; margin: 0 auto; position: relative; /* 基点に設定 */ } #main { margin-left: 200px; padding: 0.2em 0; background-color: #fff; } #navi { width: 200px; padding: 0.2em 0; background-color: #48722E; position: absolute; top: 0; /* 基点(#container)からの上方向の距離 */ left: 0; /* 基点(#container)からの左方向の距離 */ } h1 { color: #666; font-weight: normal; font-size: 1.875em; margin: 0 auto 15px auto; /* 中央寄せ (下に15px追加) */ width: 800px; /* 中央寄せ (幅を指定する必要がある)*/ } h2 { margin: 0.8em 16px; padding: 0.2em 16px; color: #999; background-color: #eee; font-weight: normal; font-size: 1.25em; } p { margin: 1em 16px; line-height: 1.6; color: #999; font-size: .875em; } ul { margin: 0.8em 16px; padding: 0; color: #E1F8AF; } li { margin: 0.2em 8px; font-size: .875em; }
固定配置を利用したレイアウト
固定配置を利用したレイアウトの例です。
ナビゲーションを常に上部に表示
サイト内のコンテンツを移動するためのナビゲーションを、常にページ上部に表示するレイアウトを作成してみます。
HTML は前項の例とほぼ同じですが、全体を div 要素 #wrapper で囲みます。そしてこの div 要素 #wrapper に margin: auto を指定してコンテンツ全体を中央寄せします。
以下は HTML の構造です。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Layout Sample 2-1</title> </head> <body> <div id="wrapper"> <h1>Position Layout</h1> <div id="container"> <div id="main"> <h2>HTML</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Provident, aperiam et veritatis officiis beatae iste earum totam dolores eaque...</p> <h2>CSS</h2> <p>Enim voluptate at sed culpa debitis error similique voluptatum labore asperiores!...</p> <h2>jQuery</h2> <p>Dolorum, praesentium, reprehenderit, id labore excepturi dolorem provident alias vel animi at dolores eius corporis adipisci asperiores ...</p> <h2>PHP</h2> <p>Quasi, natus, iusto, eveniet repudiandae maxime non obcaecati tenetur omnis dolorem dolorum atque molestiae cupiditate. ...</p> <h2>WordPress</h2> <p>Voluptatibus, quas a nulla sunt assumenda consectetur dolor illum optio unde nisi! Ea, aliquam, qui?...</p> </div><!-- end of #main --> <div id="navi"> <ul> <li>HTML</li> <li>CSS</li> <li>jQuery</li> <li>PHP</li> <li>WordPress</li> </ul> </div><!-- end of #navi --> </div><!-- end of #container --> </div><!-- end of #wrapper --> </body> </html>
以下は、固定配置を使用する前の段階の CSS です。
#wrapper は左右マージンを auto にして、中央寄せします。また、上部にナビゲーションを表示する十分なスペース(この例では 60px )のマージンを指定しています。
body { background-color: #ccc; margin: 1em 20px; } #wrapper { width: 800px; margin: 60px auto 20px; /* 中央寄せ (幅を指定する必要がある)*/ position: relative; } #container { background-color: #E4F5DA; border: 1px solid #aaa; } #main { padding: 0.2em 0; background-color: #fff; } #navi { background-color: #48722E; } ul { color: #E1F8AF; } li { font-size: .875em; } h1 { color: #666; font-weight: normal; font-size: 1.875em; } h2 { color: #999; background-color: #eee; margin: 0.8em 16px; padding: 0.2em 16px; font-size: 1.25em; font-weight: normal; } p { color: #999; margin: 1em 16px; line-height: 1.6; font-size: .875em; }
以下のような表示になります。
実際のサンプル: layout_02_1.html
ナビゲーションを固定配置するために、以下のように CSS の指定を追加します。
- div 要素 #navi に「position: fixed」を指定
- 幅を 100% に指定
- ルート要素からの距離を top、left で指定
- ul 要素に全体と同じ幅(800px)を指定
- ul 要素を中央寄せ
- li 要素は「display: inline」で横並びにする(float を使っても横並びにできる)
- li 要素に幅を指定
#navi { background-color: #48722E; width: 100%; position: fixed; /* 固定配置 */ top: 0; /* 基点(ルート要素)からの上方向の距離 */ left: 0; /* 基点(ルート要素)からの左方向の距離 */ } ul { width: 800px; /* 幅を指定 */ color: #E1F8AF; margin: 0 auto; /* 中央寄せ */ padding: 10px 0; text-align: center; } li { font-size: .875em; display: inline-block; width: 19%; list-style-type: none; }
以下のような表示になります。
実際のサンプル: layout_02_2.html
前述の例では、ナビゲーションの幅を、表示領域(ウィンドウ)いっぱいに表示していますが、ナビゲーションの幅をコンテンツの幅にあわせるには、以下のように CSS を変更します。
#navi { /*background-color: #48722E; こちらの背景色を削除 */ width: 100%; position: fixed; top: 0; left: 0; } ul { width: 800px; color: #E1F8AF; margin: 0 auto; padding: 10px 0; text-align: center; background-color: #48722E; /* こちらに背景色を指定 */ }
実際のサンプル: layout_02_3.html
float を利用したレイアウト
float プロパティを利用したレイアウトの例です。
HTML は以下のようなもので、 div 要素 #main と div 要素 #navi の出現順序が今までの例とは異なります。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Layout Sample 3-1</title> </head> <body> <div id="wrapper"> <h1>Float Layout</h1> <div id="container"> <div id="navi"> <ul> <li>HTML</li> <li>CSS</li> <li>jQuery</li> <li>PHP</li> <li>WordPress</li> </ul> </div><!-- end of #navi --> <div id="main"> <h2>HTML</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Provident, aperiam et veritatis officiis beatae iste earum totam dolores eaque...</p> <h2>CSS</h2> <p>Enim voluptate at sed culpa debitis error similique voluptatum labore asperiores!...</p> <h2>jQuery</h2> <p>Dolorum, praesentium, reprehenderit, id labore excepturi dolorem provident alias vel animi at dolores eius corporis adipisci asperiores ...</p> <h2>PHP</h2> <p>Quasi, natus, iusto, eveniet repudiandae maxime non obcaecati tenetur omnis dolorem dolorum atque molestiae cupiditate. ...</p> <h2>WordPress</h2> <p>Voluptatibus, quas a nulla sunt assumenda consectetur dolor illum optio unde nisi! Ea, aliquam, qui?...</p> </div><!-- end of #main --> </div><!-- end of #container --> </div><!-- end of #wrapper --> </body> </html>
float を指定する前の CSS です。
body { background-color: #ccc; margin: 1em 20px; } #wrapper { width: 800px; margin: 20px auto; position: relative; } #container { background-color: #E4F5DA; border: 1px solid #aaa; } #main { padding: 0.2em 0; background-color: #fff; } #navi { background-color: #48722E; } ul { color: #E1F8AF; } li { font-size: .875em; } h1 { color: #666; font-weight: normal; font-size: 1.875em; } h2 { color: #999; background-color: #eee; margin: 0.8em 16px; padding: 0.2em 16px; font-size: 1.25em; font-weight: normal; } p { color: #999; margin: 1em 16px; line-height: 1.6; font-size: .875em; }
各ブロックボックスは通常フローの中にあるので、垂直方向に上から下へと配置されます。
実際のサンプル: layout_03_1.html
フロートとマージンを使ったレイアウト
フロートしたボックスに後続する通常の(フロートしない)ブロックボックスは、フロートしたボックスの背面に隠れるように重なります。
この重なったブロックボックスにマージンを指定し、フロートしたボックスと重ならないように余白を取ることで、列を分割したレイアウトを作ることができます。
div 要素 #navi に幅と float: left を指定して左寄せします。そして後続の div 要素 #main に幅を指定して、フロートしたボックスと重ならないように余白(margin-left: 250px)を指定します。
#navi { background-color: #48722E; width: 250px; /* 幅を指定 */ float: left; /* フロートを指定 */ } #main { padding: 0.2em 0; background-color: #fff; width: 550px; margin-left: 250px; /* フロートしたボックスと重ならないように余白を指定 */ }
フロートしたボックスと重ならないように指定する余白は、フロートしたボックスに左右のパディングやボーダーが指定されていれば、その分も考慮する必要があります。この例では 0 なので、単純に #navi の幅分を指定しています。
実際のサンプル: layout_03_2.html
複数フロートの横並びを使ったレイアウト
複数フロートの横並びを使ったレイアウトでも、前述と同じようなレイアウトが可能です。
使用する HTML は前述の「フロートとマージンを使ったレイアウト」と同じものを使用します。
CSS では、 div 要素 #navi と div 要素 #main の両方に float: left; を指定します。
ボックスがフロートするとき、先行するフロートしたボックスが存在する場合、それぞれのマージン辺が重ならないように横に並んで配置されます。
但し、フロートするボックスの左右のマージン辺は包含ブロックの左右の内容辺を超えてあふれることは禁止されているため、包含ブロックの左右の内容辺を超えてしまうと、先行するフロートしたボックスの下に配置されてしまい、レイアウトが崩れることになります。
div 要素 #navi の幅は、包含ブロック(div 要素 #container)のボーダーを考慮して、248px に指定します。
#navi { background-color: #48722E; width: 248px; float: left; } #main { padding: 0.2em 0; background-color: #fff; width: 550px; float: left; }
また、包含ブロック(div 要素 #container)の子要素(#navi と #main )が両方ともフロートしているので、高さが算出されません。そのため div 要素 #container にクリアフィックス(clearfix)を指定する必要があります。
CSS に以下のようなクラス(clearfix)を設定します。
.clearfix:before, .clearfix:after { content: " "; display: table; } .clearfix:after { clear: both; } .clearfix { *zoom: 1; }
そして、div 要素 #container にクリアフィックス(clearfix)を指定します。
<div id="wrapper"> <h1>Float Layout</h1> <div id="container" class="clearfix"><!-- clearfix を指定 --> <div id="navi"> <ul> <li>HTML</li> <li>CSS</li> <li>jQuery</li> <li>PHP</li> <li>WordPress</li> </ul> </div> <div id="main"> 以下省略
実際のサンプル: layout_03_3.html
以下のように前述の HTML とは、div 要素 #navi と div 要素 #main の順序が異なる場合に、複数フロートの横並びを使ってレイアウトしてみます。div 要素 #container にはクラス clearfix を指定しておきます。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Layout Sample 2-1</title> </head> <body> <div id="wrapper"> <h1>Float Layout</h1> <div id="container" class="clearfix"> <div id="main"> <h2>HTML</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Provident, aperiam et veritatis officiis beatae iste earum totam dolores eaque...</p> <h2>CSS</h2> <p>Enim voluptate at sed culpa debitis error similique voluptatum labore asperiores!...</p> <h2>jQuery</h2> <p>Dolorum, praesentium, reprehenderit, id labore excepturi dolorem provident alias vel animi at dolores eius corporis adipisci asperiores ...</p> <h2>PHP</h2> <p>Quasi, natus, iusto, eveniet repudiandae maxime non obcaecati tenetur omnis dolorem dolorum atque molestiae cupiditate. ...</p> <h2>WordPress</h2> <p>Voluptatibus, quas a nulla sunt assumenda consectetur dolor illum optio unde nisi! Ea, aliquam, qui?...</p> </div><!-- end of #main --> <div id="navi"> <ul> <li>HTML</li> <li>CSS</li> <li>jQuery</li> <li>PHP</li> <li>WordPress</li> </ul> </div><!-- end of #navi --> </div><!-- end of #container --> </div><!-- end of #wrapper --> </body> </html>
以下のように CSS を指定することで、前述と違う要素の出現順ですが、同じレイアウトを実現することができます。
#main と #navi に幅と float: right; を指定します。
body { background-color: #ccc; margin: 1em 20px; } #wrapper { width: 800px; margin: 60px auto 20px; position: relative; } #container { background-color: #E4F5DA; border: 1px solid #aaa; } #main { padding: 0.2em 0; background-color: #fff; width: 550px; float: right; } #navi { background-color: #48722E; width:248px; float: right; } ul { color: #E1F8AF; } li { font-size: .875em; } h1 { color: #666; font-weight: normal; font-size: 1.875em; } h2 { color: #999; background-color: #eee; margin: 0.8em 16px; padding: 0.2em 16px; font-size: 1.25em; font-weight: normal; } p { color: #999; margin: 1em 16px; line-height: 1.6; font-size: .875em; } .clearfix:before, .clearfix:after { content: " "; display: table; } .clearfix:after { clear: both; } .clearfix { *zoom: 1; }
実際のサンプル: layout_03_4.html
float: left; を指定すると以下のようになります。
#main { padding: 0.2em 0; background-color: #fff; width: 550px; float: left; } #navi { background-color: #48722E; width:248px; float: left; }
実際のサンプル: layout_03_5.html