前書き:
レイアウトの従来のソリューションはボックス モデルに基づいており、表示属性 + 位置属性 + フロート属性に依存しています。たとえば、垂直方向のセンタリングを実現するのが難しいなど、特殊なレイアウトでは非常に不便です。
2009 年に W3C は、さまざまなページ レイアウトを簡単、完全、レスポンシブに実現できる新しいソリューションである Flex レイアウトを提案し、2012 年にさらに改良されました。
2009 バージョンの構文は古い (表示: ボックス) ため、互換性のためにいくつかの接頭辞を追加する必要があります
/* 形如: */ display: -webkit-box; /* Chrome 4+, Safari 3.1, iOS Safari 3.2+ */ display: -moz-box; /* Firefox 17- */ display: -webkit-flex; /* Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 */ display: -moz-flex; /* Firefox 18+ */ display: -ms-flexbox; /* IE 10 */ display: flex; /* Chrome 29+, Firefox 22+, IE 11+, Opera 12.1/17/18, Android 4.4+ */
そのため、新しいバージョンを使用することをお勧めします
2012 が標準の構文になります。将来 (表示: flex)、ほとんどのブラウザはプレフィックスなしのバージョンを実装する予定です。 1. Flex とは何ですか? なぜそれを使用する必要があるのですか?W3C による公式の説明では、これはより複雑なレイアウトを実現するために設計されているとのことです。
Flexbox は本質的に Box-model の拡張であるということは、Box-model が要素のボックス モデルを定義することは誰もが知っていますが、Flexbox はこれらのボックス モデル間の相対関係をさらに標準化します。 。レイアウトに使用すべきではない一部の属性をハッキングするために、非常に不正な方法を使用する必要はありません。
Flex レイアウトの主なアイデアは、コンテナにそのサブアイテムの幅、高さ (さらには順序) を変更して、利用可能なスペースを最適に埋める機能を提供することです (主に、あらゆる種類の表示デバイスやデバイスに対応するため)画面サイズ)。フレックス コンテナーを使用すると、サブアイテム (フレックス アイテム) が拡張して利用可能なスペースを満たすか、サブアイテムがコンテナーからあふれないように縮小します。
最も重要なことは、Flexbox のレイアウト方向は通常のレイアウトとは異なります (ブロックは上から下、インラインは左から右)。従来のものはページ レイアウトには適していますが、大規模または複雑なアプリケーション (特に向きの変更、拡大縮小、伸縮などを伴う場合) をサポートする柔軟性に欠けています。
Flex レイアウトを理解するには、3 つの主要な質問が中心になります
1. これで何ができるのですか?つまり、彼はどのような問題を解決できるのでしょうか?
2. どこで使えますか?この方法はどこで使用できますか?3.なぜ使えるのですか?彼の実装ではどのようなロジックが使用されていますか?
もちろん、これら 3 つの問題は関数の実装にも直接関係するため、その使用方法を理解しましょう。
2. Flex の基本概念
Flex レイアウトは属性ではなくモジュールに相対的なため、グループ属性全体を含む多くのものが関係します。それらの 1 つの部分はコンテナ (「フレックス コンテナ」コンテナと呼ばれる親要素) で、もう 1 つの部分は子要素 (「フレックス アイテム」と呼ばれます) です。
レギュラー レイアウトはブロックとインライン フローの方向に基づいていますが、フレックス レイアウトはフレックス フロー フローに基づいています。この図は、フレックス レイアウトの主なアイデアを説明しています。
コンテナにはデフォルトで 2 つの軸があります: 水平主軸 (メイン軸) と垂直クロス軸 (クロス軸) です。
主軸の開始位置(境界線との交点)をメインスタート、終了位置をメインエンド、クロス軸の開始位置をクロススタート、終了位置をクロスエンドと呼びます。 。
デフォルトでは、アイテムは主軸に沿って配置されます。 1 つのアイテムが占める主軸のスペースをメイン サイズと呼び、1 つのアイテムが占める横軸のスペースをクロス サイズと呼びます。
3. Flex の使い方
Flex も通常のレイアウト操作と同様に CSS 属性の設定に基づいて実装されます。
上の図に示すように、主に親コンテナの属性の設定とサブプロジェクトの属性の設定が含まれます(埋め込みコンテナがある場合も同様です)
(1) 親の属性コンテナ
1.display: flex | inline-flex; (親コンテナに適用)
これは、値セットによってインラインかブロックかを定義するために使用されます。この時点で、そのすべての子要素は、フレックス アイテムと呼ばれるフレックス ドキュメント フローになります。
display: other values | flex | inline-flex;
Webkit コアを備えたブラウザの場合は、-webkit プレフィックスを追加する必要があります。例:
display: -webkit-flex;
ただし、親コンテナが flex を設定した後は、注意すべき点が 2 つあります:
CSS 列は格納可能なコンテナには影響しません。
2.flex-direction (親コンテナに適用)
flex-direction プロパティは、主軸の方向 (つまり、項目の配置方向) を決定します。
flex-direction: row | row-reverse | column | column-reverse
row(デフォルト値)
: 「ltr」書式設定モードでは左から右に配置し、「rtl」書式設定モードでは右から左に配置します。
column-reverse:
row-reverse に似ていますが、下から上に配置されます。那不如来个例子:
现在有一个父容器div,其中有5个子项目div.
为了保证效果展示,父容器暂设width: 40%; min-height: 250px; 子项目分别设置不同宽 width: 10%|15%|20%; 高度暂设固定高度30px(但设置高度会时stretch失效)
基本代码为:(后续例子都是基于这个展开,变动的部分为关键的各 flex属性)
<div class="box"> <div class="item item1 center">item1</div> <div class="item item2 center">item2</div> <div class="item item3 center">item3</div> <div class="item item4 center">item4</div> <div class="item item5 center">item5</div> </div>
<style type="text/css"> html,body,div {margin: 0;padding: 0} .center { padding-top: 5px; text-align: center; background: #abc; font: bold 14px/1.2em Arial, Helvetica, sans-serif ; color: #fff; } .item { border: 2px solid #0f0; } .item1 { width: 10%; height: 30px; } .item2 { width: 10%; height: 30px; } .item3 { width: 15%; height: 30px; } .item4 { width: 15%; height: 30px; } .item5 { width: 25%; height: 30px; } .box { display: flex; display: -webkit-flex; flex-direction: row; margin: 10px auto; width: 40%; min-height: 250px; overflow: hidden; border: 2px solid #0cf; }</style>
更新flex-direction的值,row | row-reverse | column | column-reverse 顺序变化
这个主要用来定义伸缩容器里是单行还是多行显示,侧轴的方向决定了新行堆放的方向。
flex-wrap: nowrap | wrap | wrap-reverse
为了看到wrap效果,先增大子项目宽度
.item1 { width: 40%; height: 30px; } .item2 { width: 40%; height: 30px; } .item3 { width: 60%; height: 30px; } .item4 { width: 60%; height: 30px; } .item5 { width: 80%; height: 30px; } .box { display: flex; display: -webkit-flex; flex-direction: row; flex-wrap: nowrap; margin: 10px auto; width: 40%; min-height: 250px; overflow: hidden; border: 2px solid #0cf; }
更新flex-wrap的值,nowrap| wrap| wrap-reverse 顺序变化
这个是“flex-direction”和“flex-wrap”属性的缩写版本。同时定义了伸缩容器的主轴和侧轴。其默认值为“row nowrap”。
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
比如 column nowrap 和 column wrap-reverse
.box { display: flex; display: -webkit-flex; flex-flow: column nowrap; ... }
这个是用来定义伸缩项目沿着主轴线的对齐方式。当一行上的所有伸缩项目都不能伸缩或可伸缩但是已经达到其最大长度时,这一属性才会对多余的空间进行分配。当项目溢出某一行时,这一属性也会在项目的对齐上施加一些控制。
justify-content: flex-start | flex-end | center | space-between | space-around
这会儿先把子项目的宽度恢复咯
.item1 { width: 10%; height: 30px; } .item2 { width: 10%; height: 30px; } .item3 { width: 15%; height: 30px; } .item4 { width: 15%; height: 30px; } .item5 { width: 25%; height: 30px; } .box { display: flex; display: -webkit-flex; flex-direction: row; justify-content: flex-start; ... }
按顺序 更新 justfy-content
direction为row是这样,为column同理,自行联想吧
这个主要用来定义伸缩项目可以在伸缩容器的当前行的侧轴上对齐方式。可以把他想像成侧轴(垂直于主轴)的“justify-content”。
align-items: flex-start | flex-end | center | baseline | stretch
stretch的使用受到高度的影响,所以可先把item1-3-5取消高度的设置
.item1 { width: 10%; /* height: 30px; */ } .item2 { width: 10%; height: 30px; } .item3 { width: 15%; /* height: 30px; */ } .item4 { width: 15%; height: 30px; } .item5 { width: 25%; /* height: 30px; */ } .box { display: flex; display: -webkit-flex; align-items: flex-start; ... }
按顺序更新 align-items
这个属性主要用来调准伸缩行在伸缩容器里的对齐方式。类似于伸缩项目在主轴上使用“justify-content”一样。
注:请注意本属性在只有一行的伸缩容器上没有效果。
align-content: flex-start | flex-end | center | space-between | space-around | stretch
因为只有一行的伸缩容器看不到效果,那就再把子项目的宽度改回来先,让它换行满足多行的条件
.item1 { width: 40%; height: 30px; } .item2 { width: 40%; height: 30px; } .item3 { width: 60%; height: 30px; } .item4 { width: 60%; height: 30px; } .item5 { width: 80%; height: 30px; } .box { display: flex; display: -webkit-flex; flex-wrap: wrap; align-content: flex-start; ... }
则按顺序更新 align-content
order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
order: <integer>
先将各子项目宽度恢复为小值,设置item5的order值为 -1 ,item2 的为1
.item1 { width: 10%; height: 30px; } .item2 { width: 10%; height: 30px; order: 1; } .item3 { width: 15%; height: 30px; } .item4 { width: 15%; height: 30px; } .item5 { width: 25%; height: 30px; order: -1; } .box { display: flex; display: -webkit-flex; flex-direction: row; ... }
改变 direction row | column 可看到
根据需要用来定义伸缩项目的扩展能力。它接受一个不带单位的值做为一个比例。主要用来决定伸缩容器剩余空间按比例应扩展多少空间。
如果所有伸缩项目的“flex-grow”设置了“1”,那么每个伸缩项目将设置为一个大小相等的剩余空间。如果你给其中一个伸缩项目设置了“flex-grow”值为“2”,那么这个伸缩项目所占的剩余空间是其他伸缩项目所占剩余空间的两倍。负值无效。
flex-grow: <number> (默认值为: 0 即如果存在剩余空间,也不放大。)
暂去掉子项目的order属性,我们先来看看初始时 和 加了 flex-grow后(item1 设为1,item2设为2)的区别
当direction为row时,将剩余空间吃透
当direction为column 时,将剩余空间吃透
根据需要用来定义伸缩项目收缩的能力。负值无效。
flex-shrink: <number> (默认值为: 1 即如果空间不足,该项目将缩小。)
好了,又有机会把子项目宽度设大了。默认 shrink值为1, 为0则不缩小,数字更大则缩小程度更大
.item1 { width: 40%; height: 30px; flex-shrink: 1; } .item2 { width: 40%; height: 30px; } .item3 { width: 60%; height: 30px; flex-shrink: 1; } .item4 { width: 60%; height: 30px; } .item5 { width: 80%; height: 30px; flex-shrink: 1; }
现在shrink值都为1,把item1值设为0不缩小,item3值设为3,item5值设为5 看看变化
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。
浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。 负值无效。
flex-basis: <length> | auto (默认值为: auto)
比如对于item1,设置其basis为100px,加上它的边框总width为104px ,计算后发现主轴还有剩余空间,则按一定规则计算伸展的长度
.item1 { width: 10%; height: 30px; flex-basis: 100px; flex-grow: 1; }
这是“flex-grow”、“flex-shrink”和“flex-basis”三个属性的缩写。其中第二个和第三个参数(flex-shrink、flex-basis)是可选参数。默认值为“0 1 auto”。
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。
默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
align-self: auto | flex-start | flex-end | center | baseline | stretch
.item1 { width: 10%; height: 30px; align-self: flex-start; } .item2 { width: 10%; height: 30px; align-self: flex-end; } .item3 { width: 15%; height: 30px; align-self: center; } .item4 { width: 15%; height: 30px; align-self: baseline; } .item5 { width: 25%; height: 30px; align-self: stretch; }
初始样式和加了 align-self的对比
四、grow shrink 的计算规则
可以看到,各子项目扩张收缩的程度是不同的,那么它们是怎么计算的呢?
flex-grow 计算的原理是跟flex flex-basis属性有关的,flex-shrink 的计算原理也和flex-basis有关
先来了解flex-basis ,这个属性在 flex 容器为横向的时候,其实就是宽度,当我们把 item 指定成 flex: 0 0 480px 时,其实就是把它的宽度设定成 480px。
flex-basis属性 它的默认值为auto,即项目的本来大小
好来看看是怎么计算的
1.先来看看grow
grow 表示在 item 总宽度比容器小的时候,为了让 item 填满容器,每个 item 增加的宽度。
基本が 100px のアイテムが 3 つあるとします。
拡張値を左から右にそれぞれ 3、2、1 とします。次に、フレックスが適用されると、一番左の項目の実際の増加幅はいくらでしょうか。
増加した幅は90pxであることが画像から計算できるため、最後の左端のアイテムの幅は190pxになります。
2. シュリンクを見てみましょう
grow と shrin は実際には双子であり、非常によく似ています
shrink は、アイテムの幅の合計がコンテナーよりも大きい場合に、アイテムをコンテナに詰め込み、各アイテムの幅を縮小します。
ただし、計算式は異なります。なぜ?
加算する場合は関係ありませんが、減算する場合は、割り当てられた縮小値のみを計算すると、最終的な縮小の幅が基準よりも大きくなる可能性が非常に高いため、項目の幅はマイナスの値になります。
それではどう直せばいいのでしょうか?
縮小幅が常に基底よりも小さくなるように、パラメーターとして基底を計算します。
それで、左端の例を例にとると、最終的な計算は 60px の縮小なので、アイテムは 140px になります。
上記が使いにくくても問題ありません。実際、最もよく使われるのは flex: 1 です。
追記:
もちろん、属性の使用法を知るだけでは十分ではなく、それを習得するには、より実践的な演習が必要です
詳細な読書