ホームページ >ウェブフロントエンド >htmlチュートリアル >3カラム適応幅レイアウトからCSSへの議論_html/css_WEB-ITnose
左右に 100 ピクセル、中央がブラウザの幅に適応する 3 列のアダプティブ レイアウトを実装するにはどうすればよいですか?
最初に思いつくのは、テーブル レイアウト を使用し、テーブルの幅を 100% に設定し、3 つの TDS、最初と 3 番目の固定幅を 100 ピクセルに設定し、中央の幅をアダプティブにすることです。リアルタイムデモ:
左 | 中央 | 右 |
ただし、テーブル レイアウトは、CSS が普及する前に使用されていたレイアウトであり、テーブルが読み込まれる前にテーブル全体が空白になり、ページがわかりにくくなるなど、多くの欠点があります。表のレイアウトや組版を変更するのは非常に面倒で困難です。
テーブル レイアウトを使用しない場合の 2 番目のアイデアは、以下に示すように、float を使用して、左の div を左にフロートし、右の div を右にフロートさせることです:
アクション 1 まず、左と右の div をフロートにします。
左フロート
右フロート
中央に div が 2 番目にランクされている場合:
<div style="float:left;">left</div><div>middle</div><div style="float:right;">right</div>
その結果は次のようになります:
アクション 2 右の div が 2 番目にフロートされます。行
左
中央
右
div のデフォルト表示はブロックであるため、幅が設定されていない場合、ブロックレベルの要素は可能な限り多くの水平スペースを占有します。 width: 200px が設定されている場合、効果は次のようになります:
アクション 3 右側の div は引き続き 2 行目にフロートします
float left
middle
right
float であるため、3 番目の div は依然としてラップされます。 right 現在の行のできるだけ右に配置されます。つまり、コンテナ ボックスの端またはその隣にある前の float 要素です。現在の行にスペースがない場合は、移動を続けます。十分なスペースができるまで押し下げます。真ん中はブロックボックスなので、widthを設定しても現在の行のスペースが占有されてしまいますので、右は次の行までのスペースしか取れません。
同時に、真ん中は200pxに設定されているのに、左側は幅100pxのように見えることに気づきました。これは、フロート要素は通常のドキュメント フロー内にありますが、隣接する (非フロート) 要素のコンテンツを周囲に配置することのみが可能であり、依然として隣接する要素の背景と境界スペースを占有するためです。中央に白い境界線を追加すると、次のようになります。
アクション 4 フローティング要素は、ドキュメント フロー内の対応する要素の背景とエッジ スペースを占有します
float left
middle
right
当然のことなので、float left 要素が中央の背景と境界線のスペースを占め、中央のコンテンツが左側の周囲に配置されます。これを理解することが重要です。
真ん中に p タグがあり、p タグの内容が比較的長いとすると、周囲のエフェクトは次のようになります。
アクション 5 フローティングサラウンドエフェクト
float left
middle
いったん周囲の要素float 要素を超えます 高さ以降は通常の幅で表示されます
float right
上で述べたように、float 要素の行では、隣接する要素のコンテンツの幅が調整されて短くなりますfloat 要素が占める幅まで拡大し、float 要素の面積を超えると、隣接する要素のコンテンツ表示幅は通常になります。
デフォルトの div は 1 行を占めるため、中央を 2 番目の div に配置することはできませんが、3 番目の div に配置する必要があります。 2 番目の div と 3 番目の div の順序を変更します:
<div style="float:left;">left</div><div style="float:right;">right</div><div>middle</div>
float の右 div を最初にレンダリングし、次に中央の div をレンダリングします。左にレンダリングした後、左の行にはまだスペースがあるためです。これは、左にフローティングした後、現在の行の背景と境界のみを占有し、現在の行にはまだ多くのスペースがあるためです。 2 番目のステップは、左と同じになります。 同じ行、効果:
アクション 6 まず、左と右の div をレンダリングし、次に中央の div をレンダリングします
左
右
中央
中央の幅を設定しない場合、中央は左右を囲みます。左と同様に、右も中央のスペースを占めます。
アクション 7 中央の div が左と右の div を囲みます
左
右
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ middle围绕着left和right环绕,同时left和right占据着middle的空间 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
为了让middle和left/right中间有一个margin值,设置下middle的左右margin各为110px,这样就和左右和中间就各有10px的间距:
Action 8 设置中间div的margin值为100px + 10px
left
right
middle 设置margin: 0 110px;
这种办法的优点是实现简单,支持性好。
这种自适应宽度的原理是利用了float的围绕特性,占据自然文档流的background/border位置。这个围绕特性不仅会影响当前行的内容,还会影响下一行的内容,如下说明:
<p>第一段内容,略<img src="" style="<strong>float:left;</strong>"></img></p><p>第二段内容,略</p>
Action 8 float元素占据了下一行的空间
第一段落围绕着图片排列
图片的float属性也影响了第二段落,也就是说float会占据自然文本流相应位置元素的背景和边框,即使和float的元素不在同一行
网上还有一种margin负值法。margin负值法的步骤是:第一步让中间的middle占100%的宽度,而middle的内容设置左右margin各为100px,这样就实现了middle居中自适应宽度的效果:
<div style="width:100%;"> <div style="margin: 0 100px;">middle</div></div>
middle
接下来让left的margin-left值为-100%,由于这个比例是相对于浏览器窗口大小的,所以要是left和middle是在同一行的话,left就可以跑到middle的最左边。但是因为middle的容器盒是一个普通的div,会占据一整行,left就会排到下一行,这个时候设置margin-left为一个负数时就跑出屏幕了。所以让middle float一下,left就会排到第一行最左边,同时middle覆盖在上面:
<div style="width:100%; <strong>float:left</strong>;"> <div style="margin: 0 100px;">middle</div></div><div style="margin-left: 0">left</div>
middle
left
从上面可以看到:这样实现,导致left的内容被挤出目标区域,因为正如上面所说,middle占据了left的背景空间,上面的情况是把它占满了,left内容只能overflow了。所以这样实现是有问题的,得让left也向左float一下,这样left就紧挨在middle后面了,由于middle占了100%的宽度,所以再让left向左边margin了-100%后,left就刚好在最左边了。
<div style="width:100%; float:left;"> <div style="margin: 0 100px;">middle</div></div><strong><div style="float: left; margin-left: -100%;">left</div></strong>
middle
left
注意这里,虽然left float之后看起来也是被排到下一行了,但和默认的div独占一行是不一样的。float之后的left仍然和middle是同一行的,因为空间不足的时候,float只是把当前行盒的空间撑大,就和一个div块盒里面有很多个display为inline-block的行内级盒是同样的道理。例如:
<style> button{ width: 150px; }</style><div style="width: 300px;"> <button>按钮1</button> <button>按钮2</button> <button style="margin-left: -200px;">按钮3</button></div>
按钮3设置了一个很大的margin-left的负值后并不是跑到屏幕外了,而是在和其它两个按钮同一行的位置,显示如下:
按钮1 按钮2 按钮3
注意,设置了float的元素并不是把display改成了 inline-block,大部份display的css计算值都变成了block,同时对原本是display: flex的没有改变:
inline | block |
inline-block | block |
inline-table | table |
テーブル行 | ブロック |
テーブル行-グループ | ブロック |
テーブル列 | ブロック |
ブロック | |
ブロック | |
ブロック | |
block | |
block | |
flex、ただし float はそのような要素には影響しません | |
インラインフレックスただし、float はそのような要素には影響しません | |
unchanged |