偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

深入理解Flex布局以及計(jì)算

開發(fā) 項(xiàng)目管理
對(duì)于Flex布局,閱讀了 大漠老師和其他老師寫的文章后,我還是不太理解Flexbox是如何彈性的計(jì)算子級(jí)項(xiàng)目的大小以及一些其他細(xì)節(jié)。在大漠老師的幫助下,我去查閱Flexbox 的 W3C 規(guī)范文檔。

起因

對(duì)于Flex布局,閱讀了 大漠老師和其他老師寫的文章后,我還是不太理解Flexbox是如何彈性的計(jì)算子級(jí)項(xiàng)目的大小以及一些其他細(xì)節(jié)。在大漠老師的幫助下,我去查閱Flexbox 的 W3C 規(guī)范文檔。

注:本篇博文不適合未接觸過(guò)Flex 布局的人, 如果想了解flex 布局基礎(chǔ)。請(qǐng)參考理解Flexbox:你需要知道的一切

對(duì)于flex盒模型的設(shè)計(jì)期望

flex盒模型是被期望設(shè)計(jì)成:

  • 在任何流動(dòng)的方向上(包括上下左右)都能進(jìn)行良好的布局
  • 可以以逆序 或者 以任意順序排列布局
  • 可以線性的沿著主軸一字排開 或者 沿著側(cè)軸換行排列
  • 可以彈性的在任意的容器中伸縮大小(今天重點(diǎn)研究的主題)
  • 可以使子元素們?cè)谌萜髦鬏S方向上 或者 在容器側(cè)軸方向上 進(jìn)行對(duì)齊
  • 可以動(dòng)態(tài)的 沿著主軸方向 伸縮子級(jí)的尺寸,與此同時(shí)保證父級(jí)側(cè)軸方向上的尺寸

主軸和側(cè)軸

很有必要先向大家解釋清楚 3個(gè)問(wèn)題

  • 什么是主軸
  • 什么是側(cè)軸
  • 他們是如何切換的

首先每一根軸都包括 三個(gè)東西:維度、方向、尺寸

什么意思呢?

  • 所謂的維度實(shí)際上就是意思就是子元素 橫著排還是豎著排(x 軸 或 y 軸)
  • 方向 即排列子元素的順序 順序還是逆序
  • 尺寸 即width[height] : 每一個(gè)子元素在主軸方向所占的位置的總和 如果主軸是水平的,那么尺寸就是父元素內(nèi)所有itemouterWidth總和,如果主軸是垂直的,那么尺寸就是父元素的outerHeight

主軸是依靠 flex-direction 和 所有子元素在主軸方向上的item-size的總和確定的,flex-direction這個(gè)屬性可以控制子元素的排列方向和排列順序。

側(cè)軸是依靠 flex-wrap 和 所有子元素在主軸方向上的item-size的總和確定的,flex-wrap 可以控制子元素 在側(cè)軸方向上的排列方式以及順序。

而關(guān)于不同種類不同情況下的 item-size 我們會(huì)在下面討論,現(xiàn)在您可以簡(jiǎn)單將它理解為width[height]。

img

盜規(guī)范中的一張圖

為了方便 flex-direction + flex-wrap 合并成了一個(gè)屬性 flex-flow

通過(guò)這個(gè)簡(jiǎn)單而復(fù)雜的屬性,我們就能夠控制所有子元素的水平和垂直方向,逆序排列和順序,換行和不換行。

主側(cè)軸的切換十分簡(jiǎn)單,當(dāng)主軸設(shè)定的時(shí)候,它的垂直面,就默認(rèn)被設(shè)定成了側(cè)軸。如:

flex-flow: row-reverse wrap-reverse;

這條CSS屬性能夠告訴我們那些信息?

  • 子元素是橫著排列的,主軸是水平的橫軸,側(cè)軸是豎直的縱軸
  • 子元素是逆序并沿著主軸排列的,從右到左
  • 子元素是換行的
  • 子元素是逆序并沿著側(cè)軸排列的,從下到上

FFC (flex formatting context)

Flexbox 布局新定義了格式化上下文,類似 BFC(block formatting context)。有多類似呢? 就是除了布局和一些細(xì)節(jié)不同以外的一切規(guī)則都和 BFC 是相同的。

注意 : 我所指的Flexbox 是指設(shè)置了 display: flex; 或 display: inline-flex;的盒子。不是指單單設(shè)置了 display: flex; 的盒子。

例如,設(shè)置了 display: flex; 或 display: inline-flex的元素,和BFC一樣,不會(huì)被浮動(dòng)的元素遮蓋,不會(huì)垂直外邊距坍塌等等。

而對(duì)于設(shè)置了 display: inline-flex 的盒子來(lái)說(shuō),我們可以類比 display: inline-box;行理解。即 一個(gè)被行列化后的 Flexbox。它不會(huì)獨(dú)占一行,但是可以設(shè)置寬和高。

與BFC的細(xì)微區(qū)別

但需要注意的是以下幾點(diǎn)細(xì)節(jié),F(xiàn)lexbox 布局 和 Block 布局是有細(xì)微區(qū)別的

  • Flexbox 不支持 ::first-line 和 ::first-letter 這兩種偽元素
  • vertical-align 對(duì) Flexbox 中的子元素 是沒(méi)有效果的
  • float 和 clear 屬性對(duì) Flexbox 中的子元素是沒(méi)有效果的,也不會(huì)使子元素脫離文檔流(但是對(duì)Flexbox 是有效果的!)
  • 多欄布局(column-*) 在 Flexbox 中也是失效的,就是說(shuō)我們不能使用多欄布局在Flexbox 排列其下的子元素(魚和熊掌不可得兼嘛)
  • Flexbox 下的子元素不會(huì)繼承父級(jí)容器的寬

flex item(flex 子元素)

CSS解析器會(huì)把 定義了 display: flex; 和 display: inline-flex; 的 Flexbox 下的子元素外部裝進(jìn)一個(gè)看不見的盒子里,我們通過(guò)排列這些盒子來(lái)達(dá)到排序、布局、 伸縮的目的。

規(guī)范中把這種盒子 稱為 flex item,而子元素中包括了 標(biāo)簽節(jié)點(diǎn) 以及 文本節(jié)點(diǎn)。標(biāo)簽節(jié)點(diǎn)很容易理解,需要注意的是文本節(jié)點(diǎn)。

默認(rèn)情況下,flex 會(huì)將 連續(xù)的文本節(jié)點(diǎn) 裝進(jìn) flex-item 之中,使文本可以和標(biāo)簽節(jié)點(diǎn)一起排序和定位。

值得注意的是,空格也是文本節(jié)點(diǎn),所以 white-space 會(huì)影響Flexbox 中的布局:

img

設(shè)置了white-space: pre 的Flexbox

flex-item-size 如何計(jì)算的

item-size(尺寸)為主軸方向上item的 content 再加上自身的margin 、 border 和 padding 就是這個(gè) item 的尺寸。

在規(guī)范中 介紹了 flex-item content 的計(jì)算方式

分為以下這幾種情況

1. flex-basis 的優(yōu)先級(jí)比 width[height]: 非auto; 高

如果子元素沒(méi)有內(nèi)容和默認(rèn)固定寬高,且設(shè)置了flex-basis。flex-item contentflex-basis來(lái)決定,無(wú)論width[height] 設(shè)置了多少。

(可理解為 flex-basis 比 width[height]: 非auto;的優(yōu)先級(jí)高)

img

flex-basis的優(yōu)先級(jí)比width[height]高,無(wú)論width[height]設(shè)置多少,flex-item content都以flex-basis來(lái)決定。

2.元素存在默認(rèn)寬高

如果子元素有默認(rèn)固定寬高(例如input 標(biāo)簽)、并且設(shè)置了 flex-basis,那么它的 content以 固定寬高為下限,如果flex-basis 超過(guò)了固定寬高,那么flex-basis則成為其 content,如果flex-basis比固定寬高小,那么以固定寬高為 content。

img

對(duì)于固定元素的尺寸設(shè)定

3.元素存在 min-width[height] 或者 max-width[height]

如果flex-item 有min-width[min-height] 的限制,那么flex-item content按照 min-width 值為下限,如果 flex-basis 的值大于 min-width[min-height] 那么flex-item content以 flex-basis 計(jì)算。

如果flex-basis 的值小于 min-width[min-height] 那么flex-item contentmin-width[min-height] 計(jì)算:

img

如果 min-width[min-height] 的值已經(jīng)超出了容器的尺寸,那么即使設(shè)置了 flex-shrink。 CSS解析器也不會(huì)進(jìn)行將這個(gè)item的 content shrink,而是堅(jiān)持保留它的min-width[min-height]

img

如果Flexbox 設(shè)置的min-width 超出了flex container 的范圍, 不會(huì)對(duì)其進(jìn)行壓縮。

反之,如果設(shè)置了 max-width[height] 的值,那么設(shè)置flex-basis 無(wú)法超過(guò)這個(gè)值,對(duì)于flex-grow 也僅僅只會(huì)增長(zhǎng)到 max-width[height] 這個(gè)上限。

在下面的章節(jié),我們會(huì)仔細(xì)討論這種情況下,布局的計(jì)算。

4.width[height]: auto; 優(yōu)先級(jí)等于 flex-basis。

前面提到,如果給item同時(shí)設(shè)置了width[height] 和 flex-basis的話。flex-item content以flex-basis來(lái)決定。但是實(shí)際上默認(rèn)的 width[height]: auto; 優(yōu)先級(jí)是等于 flex-basis的。

CSS解析器對(duì)比兩者的值,兩者誰(shuí)大取誰(shuí) 作為item的基本尺寸,如果一個(gè)item沒(méi)有內(nèi)容,flex-item content就會(huì)以flex-basis來(lái)決定。

但是如果item有了內(nèi)容,且內(nèi)容撐開的尺寸比flex-basis大,那么flex-item content就會(huì)以width[height]: auto; 來(lái)決定,且無(wú)法被 shrink。反之,如果比flex-basis小,flex-item content就會(huì)以flex-basis來(lái)決定:

img

width: auto; 內(nèi)容長(zhǎng)度比 flex-basis 大,則 flex-item content以內(nèi)容長(zhǎng)度來(lái)決定,且無(wú)法shrink

img

如果 flex-basis 的長(zhǎng)度大于文字內(nèi)容長(zhǎng)度,那么flex-item content以 flex-basis 來(lái)決定

img

同時(shí)設(shè)置了flex-basis: 800px; 和 width: 1px; flex-item content以 flex-basis 來(lái)決定,可以發(fā)生shrink

img

注意2號(hào)盒子我設(shè)置了 flex-shrink: 1; 1號(hào)盒子和3號(hào)盒子我設(shè)置了 flex-shrink: 0; 意思就是我將所有的需要shrink的空間都?jí)旱搅?號(hào)盒子上,總共的需要 shrink的空間為 0 * 600 + 1 * 20 + 0 * 100 = -20;而2號(hào)盒子只有20的空間,理應(yīng)被完全shrink變?yōu)?code>0,但是值得注意的是2號(hào)盒子并沒(méi)有被完全 shrink,還保留了一個(gè)文字的距離。

除此之外,overflow: hidden; 也會(huì)影響

img

overflow: hidden; 把文字長(zhǎng)度限制在了600px; 小于 flex-basis: 700px;所以flex-item content以flex-basis來(lái)決定,可以 shrink

隱藏屬性對(duì) items-size 的影響

我針對(duì)了 display: none; visibility: hidden; visibility: collapse; transform: scale; 等屬性對(duì) items 進(jìn)行測(cè)試。

結(jié)果如下:

  • 如果設(shè)置了 visibility: hidden; | visibility: collapse; | transform: scale;的flex-item content 依然被算進(jìn)主軸尺寸,CSS 解析器依然會(huì)以他們 flex-grow | flex-shrink 將可用空間 或者 負(fù)可用空間 分配給他們
  • 如果設(shè)置了display: none; CSS解析器不會(huì)對(duì)該item的空間進(jìn)行計(jì)算,也不會(huì)對(duì)其grow空間

關(guān)于position: absolute 對(duì)item影響

position: absolute 也是適用 Flexbox 中的子元素的,并且,設(shè)置了position: absolute屬性的子元素,也會(huì)受到 Flexbox 排列的影響。

img

設(shè)置了absolute 的子元素重疊在了一起,但是依然會(huì)受到 align-items: center; 的影響而居中。對(duì)于 Flexbox 來(lái)說(shuō),設(shè)置了position: absolute;并不會(huì)對(duì)其下的子元素產(chǎn)生任何影響。

我們重點(diǎn)看 Flexbox 下的子元素設(shè)置了absolute 后有什么結(jié)果。

根據(jù)我做的實(shí)驗(yàn),我得到了如下的結(jié)論:

flexbox 下設(shè)置了absolute的子元素的位置受3個(gè)方面的影響:

  • flexbox 流下面的 justify-content 和 align-items
  • 單個(gè)子元素的 top、leftright、bottom
  • 單個(gè)子元素的 margin

這里我們不討論 translate 因?yàn)?nbsp;translate 只是視覺(jué)上位置的改變:

img

設(shè)置了absolute 的item 不會(huì)影響布局,如圖,其中1 2 3 4 5 號(hào)是設(shè)置了absolute的item,而 6 7 8 9號(hào)是沒(méi)有設(shè)置absolute的item Flexbox 我設(shè)置了 justify-content: center; 和 align-items: center; 每一個(gè)item我都給了 margin: 20px;

  • 我們可以看到,由于absolute 的原因, 12345號(hào)的item 不會(huì)影響 6789號(hào)的排布。結(jié)論:脫離了文檔流的 item 不會(huì)影響 正常的flex 布局。
  • 如圖上 4號(hào) item, 設(shè)置了absolute 但是沒(méi)有設(shè)置 top / left 這些值,位置居中偏下。結(jié)論:如果對(duì)子元素設(shè)置了 position: absolute; 屬性而沒(méi)有設(shè)置 top left 這些值。子元素受 Flexbox 的justify-content: center 、 align-items: center 和 margin 的影響
  • 如圖上1235 號(hào)item, 我給他們分別設(shè)置 top、left、right、bottom 等值。5號(hào)元素設(shè)置了margin-left: 50px; 和 padding-bottom: -999999px;結(jié)論:top、leftright、bottom 等值會(huì)覆蓋 justify-content: center; 和 align-items: center; 設(shè)置的位置,使item 自由定位。margin自始至終都會(huì)影響item的位置,而padding不會(huì)(我試過(guò)padding 設(shè)500px 的情況,padding 會(huì)影響item的大?。?/strong>
  • 如果對(duì)上圖 12345號(hào)item 不設(shè)置 topleft、rightbottom 等值。對(duì)父級(jí)的 justify-content 和 align-items 設(shè)置center以外的其他值的話:如果設(shè)置了 flex-start 所有元素不分開,定位在 主軸起點(diǎn);如果設(shè)置了 flex-start 所有元素不分開,定位在 主軸終點(diǎn);如果設(shè)置justify-content: space-around;效果等同于center,即所有的元素疊在一起居中,且items不會(huì)產(chǎn)生間隔;如果設(shè)置了 justify-content: space-between; 效果等同于 flex-start, 且items不會(huì)分開;如果設(shè)置了 align-items: flex-start; 所有元素不分開,定位在 側(cè)軸起點(diǎn);如果設(shè)置了 align-items: flex-end; 所有元素不分開,定位在 側(cè)軸終點(diǎn);如果設(shè)置了 align-items: stretch | baseline;也是沒(méi)有任何效果, items 不會(huì)跟隨側(cè)軸拉伸 或是 根據(jù)baseline 對(duì)齊
  • 如果對(duì)單個(gè)item 設(shè)置 align-self,除了 flex-start | flex-end | center 有效之外,其他都失效

通過(guò)上面一系列的測(cè)試我們可以清楚的認(rèn)識(shí)到 justify-contentalign-items 和 top、left、right、bottom 都是位置屬性,而且 top、left、rightbottom 會(huì)覆蓋justify-contentalign-items的值。(以上前提是一定要設(shè)置position: absolute 不然 topleft、right、bottom 無(wú)效)。

而 margin 的優(yōu)先級(jí)是和 top、left、right、bottom 一樣的,也就是說(shuō) margin 和 top、left、right、bottom所設(shè)置的值會(huì)同時(shí)生效。

優(yōu)先級(jí)排序?yàn)椋?nbsp;margin = justify-content | align-items > top、left、right、bottom。

flex-basis、flex-grow、flex-shrink 以及相應(yīng)的計(jì)算

flex-basis、flex-grow、flex-shrink是FFC下特有的屬性,只有父級(jí)元素設(shè)置了 display: flex | inline-flex; 才會(huì)生效,并且只針對(duì)主軸方向生效。

如果 主軸是水平的,即 flex-direction: row; 那么 flex-basis、flex-grow、flex-shrink 控制的就是單個(gè)item的寬度。

如果 主軸是垂直的,即 flex-direction: column; 那么 flex-basis、flex-grow、flex-shrink 控制的就是單個(gè)item的高度。而flex-grow 和 flex-shrink 是用于 主軸方向上對(duì) (負(fù))可用空間 進(jìn)行伸縮的。

這要分兩種情況,換行或者不換行。

1.如果 flex-wrap: nowrap; 即不換行。

那么所有items 都會(huì)在主軸方向上的一條線上排列,CSS解析器會(huì)計(jì)算 items 在主軸方向上所占的空間 相對(duì)于 Flexbox 在主軸方向的所占的空間進(jìn)行比較計(jì)算。

如果 items 所占的空間是小于Flexbox的 那么說(shuō)明Flexbox 還沒(méi)有填滿,CSS解析器就會(huì)計(jì)算還有多少空間沒(méi)有填滿,根據(jù)每一個(gè)item所設(shè)置的flex-grow 設(shè)置的值,將這些空間分配按比例分配給每一個(gè)item。

img

可用空間

如果 items 所占的空間是大于Flexbox的 那么說(shuō)明Flexbox 被填滿了,CSS解析器就會(huì)計(jì)算超出了多少空間,根據(jù)每一個(gè)item所設(shè)置的flex-shrink設(shè)置的值,將這些空間分配按比例縮小每一個(gè)item

img

超出的空間

那么CSS解析器在這種情況下是怎樣計(jì)算的呢?上一章我們勞神費(fèi)力理解的item-size終于派上用場(chǎng)了。flex-grow計(jì)算流程是:

可用空間 = 將flexbox-content - 每個(gè)item-size的總和

將每一個(gè)item所設(shè)置的 grow 全部加起來(lái),將可用空間除以grow,得到單位分配空間。

根據(jù)每一個(gè)item 設(shè)置的 grow 來(lái)算,如果一個(gè)item 的grow 為 2,那么 這個(gè) item 在主軸上的尺寸就需要延伸 2*單位分配空間的大小。

那么 每一個(gè) item 就需要在原基礎(chǔ)上 加上被分配的大小 就完成了grow:

img

分配前

img

分配后

簡(jiǎn)單理解就是,將超出的部分,可能多,也可能少,根據(jù) grow 來(lái)分配成 x 份,在根據(jù)每個(gè) item 所設(shè)置的份數(shù),將相差的部分分割給每一個(gè)item。

注意:flex-shrink 的計(jì)算流程和flex-grow的計(jì)算流程不同。

flex-shrink計(jì)算流程是:先將所有項(xiàng)目 按照 flex-shrink * item-size 的方式加起來(lái) 得到一個(gè)加權(quán)和,然后計(jì)算出 每一份 item 的 shrink比例:

shrink比例 = flex-shrink * item-size / 之前的總和;

然后計(jì)算 子元素超出父級(jí)的部分(負(fù)可用空間),每一個(gè)item 減去這個(gè) shrink比例 * 負(fù)可用空間即可

img

shrink前

img

shrink后

2. 如果flex-wrap: wrap[wrap-reverse]; 即換行

那么items 都會(huì)先在主軸方向上的多條線上排列,CSS解析器先會(huì)計(jì)算 每一條線 在主軸方向上尺寸 相對(duì)于 Flexbox 容器的width[height]進(jìn)行比較計(jì)算,每條線之間互不干擾:

img

未分配之前

img

平均分配后

由于在一行內(nèi) 如果item-size 累加超過(guò)了Flexbox 的尺寸就會(huì)另起一行進(jìn)行排列,所以在這種情況下,不會(huì)存在 shrink 的情況,而只有 grow 的情況。

max-width[height] 情況下 flex-grow 的計(jì)算流程

由于可能存在某一個(gè)或多個(gè)item 設(shè)置了有max-width[height]。所以,CSS引擎會(huì)先進(jìn)行一次分配,分配后,統(tǒng)計(jì)那些有max-width[height]的items, 分配后是否有超出的剩余空間,然后對(duì)這些剩余空間再分配給那些沒(méi)有設(shè)置max-width[height]的item

img

再分配流程

min-width[height] 情況下 flex-shrink 的計(jì)算流程

由于可能存在某一個(gè)或多個(gè)item 設(shè)置了有min-width[height]。所以,CSS引擎會(huì)先進(jìn)行一次 shrink, shrink后,統(tǒng)計(jì)那些有min-width[height]的items, shrink后是否有的剩余的未 shrink空間,然后對(duì)這些剩余空間再分配給那些沒(méi)有設(shè)置min-width[height]的item。

注意:***次 shrink的算法和第二次分配未 shrink剩余空間的算法不同!

img

總結(jié)

Flexbox 布局很棒。免去了我們大量關(guān)于適配方面的工作,但是深入理解,并用好它還是需要一點(diǎn)門檻的。 再次感謝 @大漠老師 的鼎力幫助,謝謝。

責(zé)任編輯:張燕妮 來(lái)源: Owen
相關(guān)推薦

2022-07-06 08:05:52

Java對(duì)象JVM

2021-09-28 09:26:04

云計(jì)算OpenAPI體系

2010-06-01 15:25:27

JavaCLASSPATH

2016-12-08 15:36:59

HashMap數(shù)據(jù)結(jié)構(gòu)hash函數(shù)

2020-07-21 08:26:08

SpringSecurity過(guò)濾器

2023-10-19 11:12:15

Netty代碼

2021-02-17 11:25:33

前端JavaScriptthis

2009-09-25 09:14:35

Hibernate日志

2013-09-22 14:57:19

AtWood

2020-09-23 10:00:26

Redis數(shù)據(jù)庫(kù)命令

2019-06-25 10:32:19

UDP編程通信

2017-01-10 08:48:21

2024-02-21 21:14:20

編程語(yǔ)言開發(fā)Golang

2025-05-06 00:43:00

MySQL日志文件MIXED 3

2017-08-15 13:05:58

Serverless架構(gòu)開發(fā)運(yùn)維

2025-06-05 05:51:33

2024-07-25 14:18:29

2021-09-17 06:55:50

AndroidLayoutView

2015-11-04 09:57:18

JavaScript原型

2013-06-14 09:27:51

Express.jsJavaScript
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)