- 締切済み
格子状に並んだdivボックスの効率的な指定方法
css初心者です。 DIVボックスを格子状に並べたいです。 例えば横幅30pxのボックスを、横幅110pxのスペースの中に3つ横並びにさせるとします。 □ □ □ ↑30 ↑10 このように、ボックスとボックスの間は10pxです。 で、同様の並びが何行か続きます。 現在、1、2番目のボックスには右余白を指定し、3番目のボックスには余白を指定しない方法で、体裁を整えています。 つまり、1、2番目のボックスと3番目のボックスでは、別のクラスを指定するなど、HTMLが微妙に違います。 ですが、実はこの箱、任意に増やしたり減らしたりしたいのです。 箱を数字で表すと… 123 456 789 例えばこうなっているものの、「5番を削除」したいとします。 そうしたら、 123 467 89 と、このようにしたいのです。 ですが、現在の作り方だと、6は余白なし、7は余白ありですから、それぞれのクラス指定を書き換える必要があります。 同様の修正が多々入る可能性があるため、5だけを削除したりコメントアウトするだけで、 うまくそれ以下のボックスが回り込んでくれるようにしたいのですが、出来ないでしょうか? なお、外枠のサイズを120にし、中の箱すべてに左右5ずつの余白を付けることも考えましたが、レイアウトの都合上、外枠に余裕を持たせておくことが不可能です。 ちなみに中の箱は横幅固定(すべて同じ)で、縦は最小サイズ固定の可変式です。 箱の中には画像とテキスト(定義リスト)などが入ります。 初心者にもわかりやすく解説していただけると助かります。 宜しくお願いします。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- ORUKA1951
- ベストアンサー率45% (5062/11036)
・項目数が変動する。 ・縦サイズが異なる。 以上から、tableではなくリストで並べるほうが良いでしょう。要は何を優先するかです。特に後日の項目の削除、追加が行われるのであればtableや一つ一つにclass名をつけるのは避けたほうが無難でしょう。tableは、行および列にグループが並ぶという意味からも違うと思います。【参照】→「ページレイアウトの目的で表を用いる。 ( http://www.asahi-net.or.jp/%7Esd5a-ucd/rec-html401j/present/styles.html#h-14.1 )」 それなら、何を見直すかというと、「レイアウトの都合上、外枠に余裕を持たせておくことが不可能です。」だと思います。--必要なら、ややこしいコマのマージン以外でこれを調整する簡単な方法がありますけど-- そもそも、私が提示したサンプルは商品のナビゲーションリストを携帯端末から幅広のウィンドウに対応させるリキッドデザイン用のものです。そのため、(ひとつのコマサイズ×横幅)と親コンテナブロックのサイズによると右端の隙間が変化します。 HTMLの本来の目的「HTMLは、どんな環境からもWebの情報を利用できるようにすべきだという方針の下に開発されている。 ( http://www.asahi-net.or.jp/%7Esd5a-ucd/rec-html401j/intro/intro.html#h-2.2.1 )」を考えると、ガチガチに固めてしまうことを目的にするのは誤りではないかと思っています。もし、デザインを優先するのなら、PDFというそのための仕様があります。 今日は忙しいので、暇を作ってサンプル作ってみます。
- tracer
- ベストアンサー率41% (255/621)
このケースはWEB制作では有名ですね。 つまり、最右にくる要素のmargin-righがいらねーよってことでclassをつけてるけど、class管理することで、並べ替えがめんどいということですよね? こんな感じでどうでしょう。 classとか不要でシンプルにいけます。 標準モード前提ですがIE6でもいけますよ。 <head> <style type="text/css"> *{ margin:0; padding:0; list-style:none; } body{ text-align:center; } div#wrap{ width:110px; overflow:hidden; background:#00f; margin:0 auto; } ul#hoge{ width:120px; overflow:visible; margin-left:-10px; position:relative; } ul#hoge li{ float:left; margin:0 0 5px 10px; width:30px; background:#f00; overflow:hidden; display:inline; } </style> </head> <!-------------------HTML-------------------------> <body> <div id="wrap"> <ul id="hoge"> <li>123</li> <li>123</li> <li>123</li> <li> <dl> <dt>12</dt> <dd>34</dd> <dt>45</dt> <dd>67</dd> </dl> </li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li> <dl> <dt>12</dt> <dd>34</dd> <dt>45</dt> <dd>67</dd> </dl> </li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li>123</li> <li> <dl> <dt>12</dt> <dd>34</dd> <dt>45</dt> <dd>67</dd> </dl> </li> </ul> </div> </body> この方法ではliの高さが極端に違うと並びの順序が崩れます。 まあ、高さ対応させるなら一般的にはJS使うのではないでしょうか。 純粋な格子状が欲しいのであれば、html&CSSレベルなら素直にtableを使うのがベターがかと思います。 トリッキーなことをすればCSSだけでいけるかもしれませんが、制作の効率を落としてまでも文書構造にこだわる必要はあまりないかもしれませんね。
- ORUKA1951
- ベストアンサー率45% (5062/11036)
floatがベストですが、途中に縦長のものがあると、それに続くものが縦に並んだりします。 各コマの高さを固定し、そのうえで必要なら内側に枠を引く。 CSS3のセレクタを使わないなら、兄弟セレクタで指定することになります。しかし、本来は >レイアウトの都合上、外枠に余裕を持たせておくことが不可能です。 みなおすべきです。 下記は他の目的で作成していたものを少し変更して流用したもので、ウェブ標準 ★Another HTML-lint gateway( http://openlab.ring.gr.jp/k16/htmllint/htmllint.html ) ★The W3C Markup Validation Service( http://validator.w3.org/#validate_by_input ) でチェック済みです。IE6以前には対応していません。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="ja"> <head> _<meta http-equiv="content-type" content="text/html; charset=Shift_JIS"> _<title>サンプル</title> _<meta name="author" content="ORUKA1951"> _<meta http-equiv="Content-Style-Type" content="text/css"> _<link rev="made" href="mailto:oruka1951@hoge.com" title="send a mail" > _<link rel="START" href="../index.html"> _<style type="text/css"> <!-- #productList ul,#productList ul li{ display:block; list-style:none; margin:0;padding:0; } #productList ul{ width:400px; border:solid 1px green; padding:0; } #productList ul li{ width:120px; text-align:center; float:left; margin: 5px 10px 5x 10px; height:160px; margin-right:20px; } #productList ul li+li+li{ margin-right:0; } #productList ul li+li+li+li{ margin-right:20px; } #productList ul li+li+li+li+li+li{ margin-right:0; } #productList ul li+li+li+li+li+li+li{ margin-right:20px; } #productList ul li+li+li+li+li+li+li+li+li{ margin-right:0; } #productList ul li+li+li+li+li+li+li+li+li+li{ margin-right:20px; } #productList ul li div{ border:solid 1px; padding:0.5ex 0.5em; } #productList ul li dl{ text-align:left; margin:0;padding:0; } #productList ul li dl dd{ margin-left:1em; font-size:0.9em; text-indent:1em; } #productList ul li.dummy{ clear:left; float:none; height:1px; visibility: hidden; } --> _</style> </head> <body> _<h1>サンプル</h1> _<div id="productList"> __<ul> ___<li> ____<div> _____<img src="./images/thumbnail/80_48_1.jpg" width="80" height="48" alt="商品A"> _____<dl> ______<dt>商品名</dt> ______<dd>サイズ</dd> ______<dd>価格</dd> ______<dd>補足説明</dd> _____</dl> ____</div> ___</li> ___<li> ____<div> _____<img src="./images/thumbnail/80_80_1.jpg" width="80" height="80" alt="商品B"> _____<dl> ______<dt>商品名</dt> ______<dd>サイズ</dd> ______<dd>価格</dd> ______<dd>補足説明</dd> _____</div> ____</dl> ___</li> ___<li> ____<div> _____<img src="./images/thumbnail/80_49_1.jpg" width="80" height="49" alt="商品B"> _____<dl> ______<dt>商品名</dt> ______<dd>サイズ</dd> ______<dd>価格</dd> ______<dd>補足説明</dd> _____</div> ____</dl> ___</li> ___<li> ____<div> _____<img src="./images/thumbnail/80_50_1.jpg" width="80" height="50" alt="商品C"> _____<dl> ______<dt>商品名</dt> ______<dd>サイズ</dd> ______<dd>価格</dd> ______<dd>補足説明</dd> _____</div> ____</dl> ___</li> ___<li> ____<div> _____<img src="./images/thumbnail/80_51_1.jpg" width="80" height="51" alt="商品D"> _____<dl> ______<dt>商品名</dt> ______<dd>サイズ</dd> ______<dd>価格</dd> ______<dd>補足説明</dd> _____</div> ____</dl> ___</li> ___<li> ____<div> _____<img src="./images/thumbnail/80_51_2.jpg" width="80" height="51" alt="商品E"> _____<dl> ______<dt>商品名</dt> ______<dd>サイズ</dd> ______<dd>価格</dd> ______<dd>補足説明</dd> _____</div> ____</dl> ___</li> ___<li> ____<div> _____<img src="./images/thumbnail/80_51_3.jpg" width="80" height="51" alt="商品F"> _____<dl> ______<dt>商品名</dt> ______<dd>サイズ</dd> ______<dd>価格</dd> ______<dd>補足説明</dd> _____</div> ____</dl> ___</li> ___<li> ____<div> _____<img src="./images/thumbnail/80_52_1.jpg" width="80" height="52" alt="商品G"> _____<dl> ______<dt>商品名</dt> ______<dd>サイズ</dd> ______<dd>価格</dd> ______<dd>補足説明</dd> _____</div> ____</dl> ___</li> ___<li> ____<div> _____<img src="./images/thumbnail/80_54_1.jpg" width="80" height="54" alt="商品H"> _____<dl> ______<dt>商品名</dt> ______<dd>サイズ</dd> ______<dd>価格</dd> ______<dd>補足説明</dd> _____</div> ____</dl> ___</li> ___<li class="dummy">ここまで</li> __</ul> _</div> </body> </html>
本当はそういうある意味で動的なものってHTMLとCSSだけでやるものではないですが…… 外ボックスのwidthを指定し、各ボックスにfloatをかけると求める答えが見えてくるかと思います。 >外枠に余裕を持たせておくことが ここの表現があいまいなので、これに該当する部分があるのかもしれませんが、一応一通り回答します。 小ボックスと間隔のサイズをそれぞれ固定とします(30pxと10px)。 小ボックスには「左」マージンを10px指定。そして外側のボックスのwidthを130pxに。これで計算上、質問者さんの望みどおりの「配置」は実現されます。 ┃10px┃←30px→┃10px┃←30px→┃10px┃←30px→┃10px┃ 「外枠に余裕を持たせておくことが」が「外ボックスのwidthを110pxより大きくできない」という意味ならこの方法は使えませんが、10pxを5pxにすれば計算上は同じように配置できます。 ちなみに、レイアウトから察するに小ボックスは全て対等かと思われるので、「別のクラスを指定する」のがよろしくないということはお気づきかと思います。上記のような指定を行えば、そちらの問題も解決されますがいかがでしょうか。 なお、兄弟セレクタのような方法もあるにはありますが、小ボックス数が不定のようですからおすすめはしません。
補足
前回質問に引き続き、回答して頂きありがとうございます(^^* 察しの通り、「外ボックスのwidthを110pxより大きくできない」という意味でした。 そしてなおかつ、一番左の小ボックスの左辺から一番右の小ボックスの右辺までを110にする。 要するに小ボックスは、110サイズの外ボックスの左右ぴったりに寄せねばなりません。 つまり、小ボックス間のマージンを変更することができません(^^; ちなみに、外ボックスとは、全頁共通で使っている、メインコンテンツエリアです。 しかし、回答を見て気付いたことが…。 「外ボックスの幅を広げる=小ボックスの左右に空きを確保する」と思い込んでいましたので、外ボックスのサイズ変更は難しい(右側はサイトの外に飛び出ちゃうので)と思っていましたが、もしかしたら、外ボックスの「左側」だけになら、空きが確保できるかも…。 ┃10px┃←30px→┃10px┃←30px→┃10px┃←30px→┃ にして、外ボックスを120にすればいいですよね。 難しく考えすぎて、css以前のこんな単純なことに気づきませんでした…(汗 『小ボックスには「左」マージンを』のたった一言でハッとしました。 「左」を強調してくれたところがポイントです(笑 ただ、外ボックスには他の要素も入っているため、全部の要素に左10pxマージンをかけないといけませんね。 また、外ボックスは全頁共通のコンテンツエリアですので、このページのみ、別の横幅指定をしたコンテンツエリアにしなくてはいけません。 (それこそ、「左側にも余裕がない」ページもあるため、幅を広げたコンテンツエリアを全頁に適用はできません) これも、大きく見れば「対等の要素に別のクラスを指定する」に類するかとも思いますが、同ページ内、同レベル要素に別のクラスを指定するよりずっといいですよね? とりあえず、外ボックスを広げずに済む前の方の方法がスマートなので、うまくいくかどうかチャレンジしてみます。 ダメそうなら、今回の質問のレイアウトページのみ、すべて外ボックスの左側だけ広げる方法でやってみます!
- yambejp
- ベストアンサー率51% (3827/7415)
>レイアウトの都合上、外枠に余裕を持たせておくことが不可能 こうなるともうなんとしがたいですが・・・ IE以外はこれでいけます やはりIEもいりますか? <style> div#hoge{ width:110px; height:120px; background-Color:blue; }div#hoge div{ text-align:center; float:left; height:28px; line-height:28px; margin-bottom:10px; width:28px; border:solid 1px #000000; background-Color:yellow; } div#hoge div:nth-child(3n-2),div#hoge div:nth-child(3n-1){ margin-right:10px; background-Color:red; } </style> <div id="hoge"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> </div>
補足
残念ながら、IE必須です…(涙 ちなみに全くの初心者ですので、nth-childというのをはじめて知りました。 すっごく便利そうで、まさに望んでいたものです! IE対応ではないのが残念ですが、「nth-child ie」で検索したところ、jQueryを使えばIEにも対応できそう(?)な感じなので、ちょっと難しそうですが、なんとか使えないかやってみます。 ありがとうございました!
お礼
すでに補足を使ってしまい、こちらからのコメができませんでしたので、お礼の項目を利用してコメント失礼します。 先ほどの補足に書いた、 >ご提示いただいたようにそれぞれを天地調整用小箱に入れ、その箱を「最大値可変」で、 >なおかつ「横3つの中の最大のものに合わせる」みたいな指定ができれば最高なんですが…。 に対応できるものとして、display boxというのを発見しました。 まさに希望通りの指定ができると思ったのもつかの間、IE未対応とのこと。 (IEユーザーだったんですが、ホントIE嫌いになりそうです…(>< 最初の回答者様の教えてくれたnth-childのように、なにかうまいことIEにも対応できる方法が開発されているのではないかと色々探しましたが、今のところ見つけられていません。 そのような方法は、現状存在しないのでしょうか? もしご存知でしたら教えてください。 ↑が使えない場合、そろそろあきらめて、「横3箱をまとめて囲む」方法で妥協しようか思案中です。 その際、以下の3つの選択肢で悩んでいます。 ・質問者様の例のようにリストタグを使って3箱ずつ囲むか (小箱関係全体をulで囲むので統一感?は出る。 でも、小ボックス3つ分がリストの1項目ではないですから、意味的におかしいですよね?) ・divで囲むか (divなら箱に意味はない(?)のでいいけど、小箱関係全体を囲まないで、3つごとに囲むだけになるので、統一感もなく、不自然?) ・例に挙げたようにテーブルで囲むか (一応表と言えば表なので(質問者様のサンプルなら「商品一覧表」ですよね?)、意味的にもOK? 小箱関係全体をtableで囲めるし、1セルに一箱入れるので、見栄えもそこそこ綺麗。 テーブルなら同じ行のセルの高さは勝手にそろってズレる心配なし。 でも、テーブルとdivをコラボさせたことがないので、うまくいくか不安&この手でいいかどうかの自信なし。) いかんせんまだ良く分かっていないので、とんでもなくありえない間違いをしてしまいそうで…(^^; 上の3つでどれがいいのか、どれでもいいのか、どれか「ありえない」ようなものはあるのか、はたまた別のいい方法があるのか、アドバイスいただけると嬉しいです。 なお、お礼のスペースを使ってしまったので、もうこちらにいらっしゃらなかった時に備え、先にお礼させていただきます。 前回に引き続き、今回も丁寧に回答していただき、ありがとうございました。 今後もたびたびお世話になってしまいそうな予感ですが、どうぞよろしくお願いします(^^
補足
成程。確かに天地を可変にしているので、変な回り込みになったり2行目以降の箱の頭が揃わなくなったりしそうですね。気付きませんでした。 提示していただいたサンプルを確認してみました。 (2つ目以降の小ボックスの</div>と</dl>タグの位置が逆なようだったので、修正しました) 確かにこれなら揃いますね。 小ボックスをliで作ったボックス(?)に入れ、高さ調整をしているということですよね? また、このHTMLなら、「不要な部分だけコメントアウト」にも対応できそうです。 ですがこれだと、 (1)ブラウザで文字表示サイズを最大にされるなど、縦に伸びて想定していた天地サイズを超えてしまった場合、下の箱と重なってしまいます。 (2)かといって最大値を可変にしてしまっては、箱を二重にした意味がない。 (「標準サイズプレビューの時は崩れなくする。」という意味はありますが) (3)小ボックスの最大想定サイズに合わせているため、サンプルの2段目など、天地の低い箱ばかりが並ぶ場合、その次の段との間が空きすぎてしまいます…。 横に並んだ3つのボックスをまとめて囲い、最大値可変にすれば上記問題は解決しますが、HTMLの途中に不規則なタグが入ってしまうため、結局当初の目的である「不要な部分だけコメントアウト」ができなくなってしまいますよね…う~ん(汗 「不要な部分だけコメントアウト」をあきらめて、レイアウトを揃えるために↑の方法をとるなら、「横3つ用のバラバラの箱」を用意するより、いっそtableでくくって <table> <tr> <td><div>箱1</div></td> <td><div>箱2</div></td> <td><div>箱3</div></td> </tr> <tr> <td><div>箱4</div></td> <td><div>箱5</div></td> <td><div>箱6</div></td> </tr> <tr> <td><div>箱7</div></td> <td><div>箱8</div></td> <td><div>箱9</div></td> </tr> </table> とでもしたほうが、意味合い的にも綺麗なHTMLになるでしょうか…? どちらにせよ、箱5を消す場合、箱7を上のtr内に移動しなければならない手間が発生しますが…(^^; ご提示いただいたようにそれぞれを天地調整用小箱に入れ、その箱を「最大値可変」で、なおかつ「横3つの中の最大のものに合わせる」みたいな指定ができれば最高なんですが…。 最初の方に教えていただいたnth-childのように、なんとか計算式的なもので、上記指定ができないものでしょうか…。 仮に可能だとしても、私のスキルでは無理っぽい感じもしなくもないですが…(^^; とりあえず「兄弟セクレタ」に関しては、各ページ毎の箱の最大数が大体決まっているので、 念のためちょっと多めに指定を作っておく(?)位で、何とか使えそうではあります。 ちなみに、兄弟セクレタを #productList ul li+li+li+li+li+li,#productList ul li+li+li+li+li+li+li+li+li{ margin-right:0; } のようにまとめるのはマズいのでしょうか? なんだかcssが膨大になってしまいそうなので、少しでもキレイにできたらな…と思っております。 以上、再度回答いただけると嬉しいです。 宜しくお願いします。