web布局13

在 CSS 中有很多種類型的函數,其中可用于尺寸屬性的函數主要有 calc()min()max()clamp() 等。這些 CSS 函數都可用來設置網格軌道尺寸,除此之外,還有一些專門用于設置網格軌道的函數,比如 repeat()minmax()fit-content() 等。接下來,我們主要來看看這些函數是如何用于設置網格軌道尺寸的,它們給網格布局又能帶來哪些不一樣。

repeat() 函數

我們先從 repeat() 函數開始。

在前面介紹網格軌道尺寸設置的課程中,常會看到給 grid-template-columnsgrid-tempalte-rowsgrid-auto-columnsgrid-auto-rows 設置多個相同的長度值,比如:

.container {grid-template-columns: 1fr 1fr 1fr;
}

表示列軌道設置了三個相同的值。針對于這樣的場景,網格布局中提供了一個 repeat() 函數,可以讓上面的代碼變得更簡潔:

.container {grid-template-columns: 1fr 1fr 1fr;/* 等同于 */grid-template-columns: repeat(3, 1fr);
}

網格中的 repeat() 函數主要用來設置網格軌道列表(<track-lists>)的重復片段,允許以更緊湊的形式寫入大量顯示重復模式的網格軌道(列或行)。該函數可以用于 grid-template-columnsgrid-template-rows 屬性,用來設置網格軌道尺寸大小,但它不能用于 grid-auto-rowsgrid-auto-columns

repeat() 函數具有一定的語法規則,它接受兩個參數:

  • 第一個參數表示重復的次數,比如 repeat(3, 1fr) 中的 3 ,該參數除了可以是正整數之外,還可以是 auto-fitauto-fill 兩關鍵詞。
  • 第二個參數是一個長度列表值,即重復的網格軌道的列表值,比如 repeat(3, 1fr) 中的 1fr ;另外該參數的值還可以是一個復合值,比如 repeat(3, 1fr 20px [col]) 中的 1fr 20px [col]

我們通過幾個示例來向大家展示 repeat() 函數的幾種常用的使用方式。先從最簡單的開始,即:

.container {grid-template-columns: 1fr 1fr 1fr 1fr;/* 使用 repeat() 函數 */grid-template-columns: repeat(4, 1fr);
}

img

Demo 地址: https://codepen.io/airen/full/xxjNjeL

repeat() 函數中的第二個參數還可以是一個列表值,比如 1fr 200px

.container {grid-template-columns: repeat(3, 1fr 200px);/* 等同于 */grid-template-columns: 1fr 200px 1fr 200px 1fr 200px;
}

代碼中的 repeat(3, 1fr 200px) 意思是 1fr 200px 會重復 3 次,相當于創建了一個六列的網格:

img

Demo 地址: https://codepen.io/airen/full/RwymJZO

repeat() 函數的第二個值除了可以是網格軌道列表值之外,也可以顯式給網格線命名,比如:

.container {grid-template-columns: repeat(3, 1fr [col]);/* 等同于 */grid-template-columns: 1fr [col] 1fr [col] 1fr [col];
}

要是在 repeat() 函數中重復網格線名稱的話,結束的網格線名稱最終會與下一條開始網格線名稱共享同一個網格線名稱:

img

Demo 地址:https://codepen.io/airen/full/WNJBKVg

如果你在使用 repeat() 給網格軌道設置尺寸時需要顯式命名網格線名稱,還可以像下面這樣使用:

.container {grid-template-columns: repeat(3, [col-start] 1fr [col-end]);/* 等同于 */grid-template-columns: [col-start] 1fr[col-end col-start] 1fr[col-end col-start] 1fr[col-end];
}

另外,可用于設置網格軌道尺寸的值,都可以被用于 repeat() 函數的第二個參數,比如:

.container {grid-template-columns: repeat(3, minmax(min(300px, 100%), 1fr));/* 等同于 */grid-template-columns: minmax(min(300px, 100%), 1fr) minmax(min(300px, 100%), 1fr) minmax(min(300px, 100%), 1fr);
}.container {grid-template-columns: repeat(3, min-content auto max-content);/* 等同于 */grid-template-columns: min-content auto max-content min-content auto max-contentmin-content auto max-content;
}

但需要注意的是,repeat() 函數中不能嵌套 repeat() 函數!

auto-fill vs. auto-fit

你可能已經發現了,前面幾個示例中 repeat() 函數的第一個參數都是整數值。一般在你已經知道網格軌道要重復的次數時才用,但很多時候,你可能并不知道網格軌道重復的數量,更希望的是它能自動匹配。

慶幸的是,repeat() 函數的第一個參數除了可以接受一個整數值之外,還可以接受 atuto-fitauto-fill 兩個關鍵詞。它們會告訴瀏覽器處理網格軌道的大小和斷行(或斷列),以便當容器空間不足以容納元素時,元素會自動換行(或列)而不會造成溢出。但 auto-fillauto-fit 兩者之間還是有一些細微差異的。

img

  • auto-fill :在同一行中填充盡可能多的列。因此,只要能容納新的列,就會自動創建隱式列,因為它試圖在同一行中填充盡可能多的列。新添加的列(隱式列)可以是空的,但是它們仍然會在行中占據指定的空間。
  • auto-fit :將當前可用的列擴展到空間中,以便它們占用容器可用空間。當容器有可用空間時,瀏覽器會將可用空間均分給列,讓列自動變寬填滿整個容器;當容器可用空間為負值時,會另起一行排列。

簡單地說,auto-fit 將擴展網格項目以填補可用空間,而 auto-fill 不會擴展網格項目。相反,auto-fill 將保留可用的空間,而不改變網格項目的寬度

在實際使用過程中,網格容器中有多個和僅有一個網格項目時,使用 auto-fillauto-fit 的差異:

img

上面兩張圖展示了 auto-fitauto-fill 在網格布局中的差異。那它們兩者又是如何工作的呢?我們以一個實例來向大家介紹 auto-fitauto-fill 是如何工作的。

<div class="container"><div class="item"></div><!-- 此處省略兩個 Item --><div class="item"></div>
</div>
.container {--width: 100%,--auto-size: auto-fit;display: grid;grid-template-columns: repeat(var(--auto-size), 120px);gap: 10px;width: var(--width); /* 它的父元素 width = 1000px */padding: 10px;
}

示例中網格容器的寬度是 1000px ,并且設置了 10px 的內距(padding),grid-template-columns 指定的列網格軌道尺寸是 120px ,網格溝槽(列網格軌道之間的間距)是 10px

你會發現,repeat() 函數的第一個參數不管是 auto-fit 還是 auto-fill ,瀏覽器都會根據相關的參數(比如網格容器的寬度、網格軌道尺寸和網格溝槽等)創建出最適合于網格容器可用空間的網格列軌道數量,即,在保證網格項目不溢出網格容器之下,創建最多數量的網格列(或行)軌道

網格容器寬度 = 網格列軌道尺寸 × 網格列軌道數量 + (網格列軌道數量 - 1) × 網格溝槽
980       =   120px      ×     ?          (     ?      - 1) × 10     

瀏覽器計算出這個“? ” 大約會是 7.66667 ,所以瀏覽創建了一個七列的網格。不同的是 auto-fit 會把空的網格軌道折疊在一起(空網格軌道是指沒有放置網格項目的網格軌道)。折疊的軌道尺寸大小會被視為 0px。瀏覽器為了找到自動重復的軌道數,會將軌道尺寸限制為用戶代理指定的值(比如 1px),來避免被零除。

img

auto-fill 則不會將創建的空網格軌道折疊在一起:

img

repeat() 函數中使用 auto-fitauto-fill 關鍵詞替代重復的次數時,又被稱為自動換行 。當網格容器無法容納網格軌道時(有網格項目的),就會自動創建新的一行:

img

Demo 地址:https://codepen.io/airen/full/PoevxOp

雖然在 repeat() 函數中使用 auto-fitauto-fill 都可能創建盡可能多的列,但每個網格軌道的尺寸是固定的,它并不是一個自動尺寸。不過,可以將 fr 單位值和 minmax() 函數結合在一起,讓網格軌道尺寸是自動的 ,即網格軌道尺寸是自動匹配的(在一個范圍內)。

把上面示例稍微調整一下,將 repeat(var(--auto-size), 120px) 中的 120px 替換成 minmax(120px, 1fr) ,即:

.container {--width: 100%,--auto-size: auto-fit;display: grid;grid-template-columns: repeat(var(--auto-size), minmax(120px, 1fr));gap: 10px;width: var(--width); /* 它的父元素 width = 1000px */padding: 10px;
}

auto-fit 時,創建的重復軌道尺寸是 0 ,網格軌道的尺寸會介于 120px ~ 1fr 之間,最小是 120px ,最大是 1fr ,而且 1fr 會根據網格容器可用空間計算出網格軌道尺寸。由于創建的重復軌道尺寸是 0 ,所以網格容器可用空間更大(1000px - 10px × 2 - 10px × 3 = 950px),對應的 1fr = 1 / 4 = 25% × 950px = 237.5px ,所以你將看到的網格項目被拉伸了:

img

auto-fill 創建的重復軌道尺寸也是 minmax(120px, 1fr) ,而且不會被折疊,所以網格容器的可用空間分的等份就更多(因為創建的三個空網格軌道,它位置占著),即 7fr 。同時網格容器可用空間也更小 (1000px - 10px × 2 - 10px × 6 = 920px),對應的 1fr = 1 / 7 = 14.28% × 920px = 131.43px ,即網格軌道尺寸是介于 120px ~ 1fr (相當于 120px ~ 131.43px)之間:

img

Demo 地址: https://codepen.io/airen/full/mdLZwey

你要是將 repeat() 函數和 minmax(min,max)1frauto-fill(或 auto-fit)結合起來,可以很容易幫我們實現像下圖這樣的響應式布局效果:

img

實現上圖這樣的效果,代碼很簡單:

.container { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; 
}

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

Demo 地址: https://codepen.io/airen/full/mdLZMBp

這種布局技術也被稱為 RAM(Repeat, Auto, Minmax) 布局,一種無需依賴任何 CSS 媒體查詢特性的響應式布局。

minmax() 函數

minmax() 函數是用于設置網格軌道尺寸的另一個函數,它可以用于 grid-template-columnsgrid-template-rowsgrid-auto-columnsgrid-auto-rows 屬性上。該函數可以接受兩個參數值,即 MINMAX 。每個參數都可以是:

  • <length-percentage> 值,比如 px%
  • <flex> 值,比如 fr
  • 關鍵詞,比如 automin-contentmax-content
  • 函數表達式,比如 min()max()clamp()clac()

minmax(MIN, MAX) 可以輸出一個范圍值,它定義了一個大于或等于 MIN 值且小于或等于 MAX 值的尺寸范圍 。簡單地說,minmax(MIN, MAX) 函數將返回MIN ~ MAX 范圍中的一個值。我們可以像下面這樣使用 minmax(MIN, MAX) 函數:

grid-template-columns: minmax(200px, 300px);
grid-template-columns: minmax(min-content, 320px);
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-template-columns: minmax(min(200px, 100%), 1fr);
grid-template-columns: minmax(300px, 50%);

接下來,我們花點時間來看看, minmax(MIN, MAX) 函數取不同類型值是如何工作的。

先來看最簡單的 <length> 值類型,比如:

.container {grid-template-columns: minmax(100px, 220px) 1fr 1fr;
}

img

Demo 地址:https://codepen.io/airen/full/JjvQrJp

使用 minmax(100px, 220px) 指定網格第一列的列寬保持在 100px220px 之間,隨著網格容器尺寸的變化,該列的寬度也會有改變,但總是在這兩個值的范圍內變化:

  • 當網格容器寬度足夠寬時,minmax(100px, 220px) 返回的值是 220px,即第一列的網格軌道寬度是 220pxMAX的值)。
  • 當網格容器寬度調到很小時(比如 222.5px),minmax(100px, 220px) 返回的值是 100px,即第一列的網格軌道寬度是 100pxMIN的值)。
  • 另外,minmax(100px, 220px) 還會返回一個 100px ~ 220px 之間的值,比如當容網格容器寬度是 300px 時,minmax(100px, 220px) 返回的值就是 177.34px

img

正如你所看到的,示例中網格的第二、第三列的收縮和擴展會根據網格容器可用空間變化(因為它們的軌道寬度設置的值是 1fr),但第一列網格軌道的寬度總是保持在 100px220px 之間,最小不小于 100px ,最大不大于 220px

我們把上面這個示例中的 220px 換成一個<percentage>% 值),比如 50%

.container {grid-template-columns: minmax(100px, 50%) 1fr 1fr;
}

img

Demo 地址:https://codepen.io/airen/full/QWrXOJm

minmax(MIN, MAX) 的值為百分比值時(示例中的 MAX=50%),那么它們就是一個動態值。上一節課程中我們聊到過,網格軌道的值是一個百分比值時:

  • grid-template-columnsgrid-auto-columns 值是百分比值時,它相對于網格容器內聯軸(inline-size)尺寸計算;
  • grid-template-rowsgrid-auto-rows 值是百分比值時,它相對于網格容器塊軸(block-size)尺寸計算。

所以我們示例中的 MAX 值相對于網格容器寬度來計算,即示例中的 MAX 的值等于 W × 50% (其中 W 是網格容器的寬度):

  • W = 1000px 時,MAX = 50% × (1000px - 20px) = 490px
  • W = 800px 時, MAX = 50% × (800px - 20px) = 390px
  • W = 500px 時, MAX = 50% × (500px - 20px) = 240px
  • W = 300px 時, MAX = 50% × (300px - 20px) = 140px
  • W = 200px 時, MAX = 50% × (200px - 20px) = 90px

這樣一來,minmax(100px, 50%) 代表的范圍值也會隨著網格容器寬度而變化,并且計算出來的 MAX 值也有可能會比 MIN 值小,比如當你把網格容器寬度調整到 200px 時,計算出來的 MAX 值就要比 MIN 值小。出現這種現象時,MAX 值將會被忽略,minmax(MIN, MAX) 函數最終會取 MIN 值作為函數的返回值。

這個觀點是通用的:

minmax(MIN, MAX) 函數,如果 MAX 小于 MIN 時, MAX 將會被忽略,最終 minmax(MIN, MAX) 函數將會返回 MIN 的值

img

minmax(MIN, MAX) 函數中的兩個參數都可以取百分比(%)值,比如:

.container {grid-template-columns: minmax(30%, 50%) 1fr 1fr;
}

但是這樣使用,有可能計算出來的值會比網格軌道中網格項目內容(元素)的最小尺寸(min-content)還會小,甚至網格列寬會趨于 0 ,將會造成網格項目溢出網格列軌道:

img

Demo 地址: https://codepen.io/airen/full/BaxXydr

因此,在使用 minmax(MIN, MAX) 函數設置網格軌道時,不建議 MINMAX 都取 <percentage>%)值,更建議在 minmax(MIN, MAX) 中把 % 值和其他類型值結合起來使用,比如:

/* <inflexible-breadth>, <track-breadth> 值 */ 
minmax(400px, 50%)        /* ~> MIN = 400px;         MAX = 50% */
minmax(30%, 300px)        /* ~> MIN = 30%;           MAX = 300px *//* <fixed-breadth>, <track-breadth> 值 */ 
minmax(1fr, 50%)           /* ~> MIN = 1fr;          MAX = 50% */ 
minmax(400px, 50%)         /* ~> MIN = 400px;        MAX = 50% */
minmax(30%, 300px)         /* ~> MIN = 30%;          MAX = 300px */ 
minmax(50%, min-content)   /* ~> MIN = 50%;          MAX = min-content */ /* <inflexible-breadth>, <fixed-breadth> 值 */ 
minmax(400px, 50%)         /* ~> MIN = 400px;        MAX = 50% */ 
minmax(30%, 300px)         /* ~> MIN = 30%;          MAX = 300px */
minmax(min-content, 50%)   /* ~> MIN = min-content   MAX = 50% */

minmax(MIN, MAX) 函數中的參數值還可以是一個 <flex> 值(fr 單位值),如果該函數的有一個值是 fr 單位的值時,它會按 fr 計算來取值,而且和其他設置了 fr 單位值一起計算,分配網格容器可用空間。比如:

.container {grid-template-columns: minmax(100px, 1fr) 1fr 1fr;
}

minmax(100px, 1fr)MIN 值時,則返回的是 100px ;當它取 MAX 值時,則返回的是 1fr ,此時 grid-template-columns 的值相當于 1fr 1fr 1fr 。每個 fr 則等于網格容器可用空間的三分之一(因為總共有3fr ,即 1fr + 1fr + 1fr)。

img

Demo 地址: https://codepen.io/airen/full/VwxoYor

當你改變網格容器尺寸時,你會發現,如果網格容器有足夠空間,minmax(100px, 1fr) 則會取 1fr ,反之則會取 100px

img

不過需要注意的是,minmax(MIN, MAX) 函數取 fr 單位值時,不能同時給 MINMAX 都設置 fr 單位的值,因為兩個參數值都取 fr 單位值,瀏覽器會視該屬性值無效:

img

針對這一點,W3C 規范中有做過相應的描述:

img

也就是說, minmax(MIN, MAX) 函數中使用 fr 單位值時,只能用于 MAX 值中 。換句話說,minmax(MIN, MAX)MAXfr 單位值,可以和其他單位(除 fr之外)類型 MIN 值混合使用,比如示例中的 minmax(100px, 1fr)。即使是這樣,也有可能 1fr 計算出來的值會小于100px,要是出現這種現象,minmax(100px, 1fr)并不會無效,它最終會返回 MIN 的值(即 100px )。

在介紹 fr 的時候,我們聊到所有設置 1fr 值的列網格軌道,并不一定能讓所有網格列軌道寬度相等,但可以使用 minmax(0, 1fr) 來替代 1fr ,實現列相等(均分列)的布局效果:

.container {grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); /* 等同于 */grid-template-columns: repeat(3, minmax(0, 1fr));
}

img

Demo 地址: https://codepen.io/airen/full/xxjvwqQ

正如你所看到的,設置 minmax(0, 1fr) 的網格軌道的寬度是在 0 ~ 1fr 之間變化,最小為 0,最大不會超過 1fr

當然,你也可以將 MAX 設置為0 ,比如 minmax(100px, 0)minmax(30%, 0) 都是有效的,只不過最終會取 MIN 的值作為 minmax(MIN, MAX) 函數的返回值,這也符合前面的規則,minmax(MIN, MAX) 函數中的 MAX 值小于 MIN 值時,會返回 MIN

另外需要注意的是,示例中 minmax(0, 1fr) 是一個有效值,但 minmax(1fr, 0) 則是一個無效值。這是因為 minmax(MIN, MAX) 函數只能在 MAX 參數設置 fr 單位值,否則 minmax(MIN, MAX) 也將是一個無效值

minmax(MIN, MAX) 函數參數除了可以取長度值之外,還可以取一些描述長度的關鍵詞,比如 automin-contentmax-content 等。比如:

grid-template-columns: minmax(auto, auto) minmax(min-content, min-content) minmax(max-content, max-content);

依舊通過幾個簡單的示例向大家展示 minmax(MIN, MAX) 函數取關鍵詞作為值時,對網格軌道尺寸有何影響。先來看 auto 值:

.container {grid-template-columns: minmax(auto, auto)  1fr 1fr;
}

minmax(MIN, MAX) 函數中使用關鍵詞 auto 時:

  • auto 作為 MAX值(minmax(100px, auto)),auto值相當于 max-contentminmax(100px, max-content)),即 minmax(100px, auto) 等同于 minmax(100px, max-content)
  • auto 作為 MIN 值(minmax(auto, 1fr)),它的值由對應網格軌道中內容的最小尺寸指定,auto 有時相當于 min-contentminmax(min-content, 1fr)),即 minmax(auto, 1fr) 等同于 minmax(min-content, 1fr),但并非總是如此,因為有時候會受網格項目的 min-widthmin-inline-size)或 min-heightmin-block-size)值影響。如果顯式指定網格項目的min-widthmin-inline-size ,那么 min-content 等于 min-widthmin-inline-size

img

Demo 地址: https://codepen.io/airen/full/VwxovVY

minmax(MIN, MAX) 函數取 min-content 值時,它的大小由相應網格軌道中的內容來決定,在網格列軌道中,min-content 的值將等同于所在列網格軌道中網格項目的內容最小尺寸。

.container {grid-template-columns: minmax(min-content, min-content)  1fr 1fr;
}

示例中的第一列尺寸始終等于所有列的內容最小尺寸:

img

Demo 地址:https://codepen.io/airen/full/oNdKjKX

min-content 值可以只是 minmax(MIN, MAX) 函數當中的某一個參數值,它可以和其他值類型混合使用,但需要注意:

  • minmax(MIN, MAX) 中的 MAX 值為 min-content 時,如果min-content 計算出來的值小于 MINminmax(MIN, MAX) 函數返回的則是 MIN 值,反之則返回的是 MINmin-content 之間的一個范圍值。
  • minmax(MIN, MAX) 中的 MIN 值為 min-content 時,如果 min-content 計算出來的值大于 MAXminmax(MIN, MAX)函數返回的是 min-content,反之則返回的是 min-contentMAX 之間的一個范圍值。

img

Demo 地址:https://codepen.io/airen/full/Vwxoejj

minmax(MIN, MAX)max-content 值時有點類似于 min-content ,不同的是取最大長度,這個長度也稱為“理想大小”,它可以容納它包含的內容。比如網格項目是一個句子,那么理想長度就是這個句子長度,而且不用考慮長度,也不會換行:

.container {grid-template-columns: minmax(max-content, max-content)  1fr 1fr;
}

img

Demo 地址: https://codepen.io/airen/full/rNvXxvN

同樣的,max-contentminmax(MIN, MAX) 函數中與其他類型值混合使用,需要注意的是:

  • minmax(MIN, MAX) 函數中的 MAX 值為 max-content 時,如果 max-content 的計算值大于 MIN 值時,minmax(MIN, MAX) 函數返回的值是一個 MINmax-content 計算值之間的范圍值;反之會忽略 max-content ,函數返回的是 MIN 值。
  • minmax(MIN, MAX) 函數中的 MIN 值為 max-content 時,如果 max-content 的計算值小于 MAX 值時,minmax(MIN, MAX) 函數返回的值是一個 max-contentMAX 之間的范圍值;反之則會返回 max-content

img

Demo 地址:https://codepen.io/airen/full/poVMgxm

這樣一來,在 minmax(MIN, MAX) 函數中同時使用 min-contentmax-content 時,你可以得到一個響應式極強的布局效果,網格項目的內容永遠不會溢出所在網格軌道:

.container {grid-template-columns: minmax(min-content, max-content)  1fr 1fr;
}

img

Demo 地址:https://codepen.io/airen/full/zYjgrVq

我們來看一個真實的 Web 布局案例。使用 minmax(MIN, MAX) 函數來構建一個博客文章展示的頁面:

img

實現上圖這種帶有響應式布局效果,僅僅使用幾行 CSS 代碼即可:

<body><main><h2>現代 Web 布局</h2></main>
</body>
body {grid-template-columns: minmax(1rem, 1fr)  minmax(auto, 70ch)  minmax(1rem, 1fr);
}main {grid-column: 2 / 3;
}

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

Demo 地址: https://codepen.io/airen/full/BaxXKNv

示例中的 grid-template-columns 創建了一個三列網格布局,其中第一列和第三列的寬度是由 minmax(1rem, 1fr) 決定,當視窗足夠寬時,這兩列的寬度是 1fr ,當視窗沒有足夠寬的時候,這兩列的寬度是 1rem ,所以你會看到,在桌面端上,mian (主內容)兩側有很大的空白空間,實現了類似主內容水平居中的效果;在平板和手機端上時,兩側只有 1rem 的間距。而主內容(即第二列)列寬是 minmax(auto, 70ch) ,瀏覽器有足夠空間時,它的寬度是 70ch ,如果瀏覽器視窗空間不足時,則由 main 自己的內容來決定(即 auto )。

網格布局中,使用 repeat() 函數,minmax(MIN, MAX)auto-fitauto-fillRAM布局技術 )可以構建一個無媒體查詢的響應式布局。

.container {display: grid;grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));gap: 1.5rem;
}

雖然效果上看上去不錯,但它有一個缺陷存在,當瀏覽器視窗的寬度小于 minmax(MIN, MAX) 中的 MIN 值時,瀏覽器就會出現水平滾動條或溢出內容被裁剪:

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

Demo 地址: https://codepen.io/airen/full/mdLZMBp

其實,我們可以在 minmax(MIN, MAX) 函數中嵌套 CSS 的比較函數(min()max()clamp()),可以讓該布局更為完美。比如,你可以在 minmax(MIN, MAX) 函數中嵌套一個 min() 函數:

.container {display: grid;grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr));gap: 1.5rem;
}

minmax(MIN, MAX) 函數中嵌套了一個 min(100%, 250px) 函數。在我們這個示例中,min() 函數中的百分比也是相對于網格容器的內聯軸方向尺寸(即寬度)計算,min() 函數中的兩個參數會相互比較,并且取更小的值作為該函數的返回值,它有點類似于設置了一個 max-width 值,即 min(100%, 250px) 相當于 max-width: 250px

就該例而言,網格容器的寬度會隨著瀏覽器視窗寬度變小,也就是說,當瀏覽器視窗寬度小到一個臨界值時,min(100%, 250px) 返回的值就會小于 250px ,此時, min(100%, 250px) 函數返回的值就是 100% ,這樣一來,就可以避免瀏覽器出現水平滾動條(除非小到無法容納內容):

img

Demo 地址:https://codepen.io/airen/full/NWzKwwN

min() 、 max() 和 clamp() 函數

min()max() clamp() 統稱為 CSS 比較函數,可以給這些函數傳入一個列表值,并對這些值做相應的比較,最終返回一個最適合的值。它們也可以像 clac() 函數,支持使用加法 (+)、減法 (-)、乘法 (\*) 和除法 (/) 的數學表達式作為值

CSS 網格布局中,這些函數都可以用于設置網格軌道和網格溝槽的大小。比如:

.container{grid-template-columns: 1fr min(65ch, 100%) 1fr;gap: clamp(1.5rem, 6vmax, 3rem);
}

min()max()clamp() 函數用來設置網格軌道尺寸時和 minmax(MIN, MAX) 是有一定差異的:

  • minmax(MIN, MAX) 返回的是 MIN ~ MAX 之間的一個值,最小是 MIN,最大是 MAX
  • min() 返回的是函數列表參數中最小的值,比如 min(100px, 200px) 返回的是 100px
  • max() 返回的是函數列表參數中最大的值,比如 max(100px, 200px) 返回的是 200px
  • clamp(MIN, VAL, MAX) 更類似于 minmax(MIN, MAX),返回的是一個區間值。即 clamp(MIN, VAL, MAX),其中 MIN 表示最小值,VAL 表示首選值,MAX 表示最大值。如果 VALMINMAX 之間(MIN < VAL < MAX),則使用 VAL 作為函數的返回值;如果VAL 大于 MAXVAL > MAX),則使用 MAX 作為函數的返回值;如果 VAL 小于 MINVAL < MIN),則使用 MIN 作為函數的返回值。

我們來看一個 CSS 比較函數用于網格軌道尺寸設置的示例。

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

Demo 地址: https://codepen.io/airen/full/BaxXKNv

這個示例是前面介紹 minmax(MIN, MAX) 函數的示例:

body {display: grid;grid-template-columns: minmax(1rem, 1fr) minmax(auto, 70ch) minmax(1rem, 1fr);
}

使用 minmax(auto, 70ch) 設置了主內容列的尺寸,對于同等效果,我們還可以使用 min() 函數來替換:

body {display: grid;grid-template-columns: minmax(1rem, 1fr) min(100% - 2rem, 70ch) minmax(1rem, 1fr);
}

img

Demo 地址: https://codepen.io/airen/full/dyKbZLB

兩個方法構建出來的布局效果是等同的。這里使用 min(100% - 2rem, 70ch) 替代了 minmax(auto, 70ch) ,它所起的作用是:

  • 當瀏覽器視窗寬度足夠大時(寬屏),100% - 2rem 計算出值會大于 70ch ,因此 min(100% - 2rem, 70ch) 將返回 70ch
  • 當瀏覽器視窗寬度不夠大時(窄屏),100% - 2rem 計算出值就會小于 70ch ,因此 min(100% - 2rem, 70ch) 將返回 100% - 2rem

你可能會好奇,為什么會是 100% - 2rem 呢?這是因為示例中第一列和第三列,它設置值是 minmax(1rem, 1fr) ,輸出的最小值就是 1rem,而且只有在瀏覽器視窗寬度較小時才會出現。在這種現象下,如果 min() 函數設置 min(100%, 70ch), 就會造成瀏覽器出現水平滾動條或內容溢出。為了避免該現象,把 min() 函數中的 100% 替換成 100% - 2rem

你還可以使用 clamp() 函數來替代上面示例中的 min() 函數,讓布局在一個尺寸范圍具有一個更好的效果:

  • 設置一個最小屏尺寸,比如 320px - 2rem (瀏覽器視窗最小寬度是 320px);
  • 設置一個最大屏尺寸,比如 70c
  • 設置一個最佳值,比如 100vw - 2rem
body {display: grid;grid-template-columns:minmax(1rem, 1fr) clamp(320px - 2rem, 100vw - 2rem, 70ch) minmax(1rem, 1fr);
}

效果幾乎是一樣的,但瀏覽器視窗小于 320px 時,將會出現水平滾動條:

img

Demo 地址: https://codepen.io/airen/full/GRGKygZ

在實際使用的時候,更建議將 CSS 的比較函數與 minmax(MIN, MAX) 以及關鍵詞 min-contentmax-content 結合起來使用。這樣能更好地幫助你構建一個內在 Web 布局。

fit-content() 函數

img

上圖這樣的兩列布局是一種很常見的布局,即 側邊欄固定尺寸,主內容欄能隨瀏覽器視窗尺寸進動調整 。你可以像下面這樣使用 CSS Grid 來構建:

body {display: grid;gap: 1.5rem;grid-template-columns: 250px 1fr;grid-template-areas: "sidebar  main";
}

但是,如果瀏覽器的視窗尺寸較小,有可能因為缺少足夠的空間導致樣式出現問題。為了避免這種情況發生,通常會在 CSS Grid 布局中使用媒體查詢:

body { display: grid; gap: 1.5rem; grid-template-areas: "sidebar" "main"; 
} @media (min-width: 760px) { body { grid-template-columns: 250px 1fr; grid-template-areas: "sidebar main"; } 
}

img

Demo 地址:https://codepen.io/airen/full/PoaYEpp

示例中的側邊欄(網格第一列)是一個固定尺寸,即 250px 。不過,我們希望它的尺寸能更靈活些:

  • 當瀏覽器視窗足夠寬的時候,它的寬度能大一些,比如是 250px
  • 當瀏覽器視窗比較窄時,它的寬度能小一些,比如根據內容來決定。

你可能會想到使用 minmax(min-content, 250px) 來實現。在網格布局中除了使用 minmax(MIN, MAX) 函數之外,還可以使用 fit-content() 函數。你可以給 fit-content() 函數傳一個 <length-percentage> 值,比如上面的示例,可以將 250px 換成 fit-content(250px)

body {grid-template-columns: fit-content(250px) 1fr;
}

fig-12-37.png

Demo 地址: https://codepen.io/airen/full/jOKNZXO

示例中的 fit-content(250px) 其實相當于:

fit-content(250px) = min(min(max-content, available-size), max(min-content, 250px)) 

公式中的 available-size 指的是網格中的可用寬度

除此之外,規范中還提供了另一種公式來描述 fit-content():

fit-content(<length-percentage>) = max(minimum, min(limit, max-content))

其中:

  • ①:minimum 代表自動最小值(通常但不總是等于 min-content 最小值);
  • ②:limit 是作為參數傳給 fit-content() 參數,即 <length-percentage>,比如示例中的 250px
  • ③:min() 返回 limitmax-content 中更小的值,比如這個示例,min() 返回的是 250pxmax-content 更小的一個;
  • ④:max() 返回是 minimummin(limit, max-content) 兩個值中更大的一個。

如果上面的描述不易于理解的話,我們可以這樣來理解。比如示例中的 fit-content(250px),表示該列網格軌道寬度不會超過 250px,并且可以在內容很短的情況下縮小到 250px 以下。

另外,一般使用 fit-content() 函數時,傳遞給該函數的參數 <length-percentage> 一般都是小于元素的 max-content 值。比如 fit-content(250px),其中 250px 是小于元素 max-content 值。

在這種情況下,元素最終的渲染尺寸介于 min-content250px 之間。具體是多少,還要看當前的可用空間尺寸(available-size),如果可用空間充足,會使用最大的 250px,如果可用空間小,就會取 min-content250px 之間的某個值,如果可用空間不充足(比 min-content 還小),那就會使用最小值 min-content,不能再小。

當然,如果 fit-content() 函數中的值比元素的 max-content 還大,那么元素最終渲染尺寸介于 min-contentmax-content 之間。具體是多少還要看當前的可用空間大小,與上面類似。

總之,fit-content() 返回的最小值是 min-content,不能比 min-content 值更小。

需要注意的是,使用 fit-content() 函數設置網格軌道時,該函數只能接受一個 <length-percentage> (即 <length> 值,比如 250px;或 <percentage> 值,比如 25%)。其他值用于該函數將會被視為一個無效值,比如一個 <flex> 類型的值 1fr

小結

在這一節課程中,主要和大家一起探討了可用于網格軌道尺寸設置的 CSS 函數,其中 repeat()minmax()fit-content() 函數是 CSS 網格布局中獨有的,而 min()max()clamp() 函數(CSS 比較函數 )類似于 CSS 的 calc() 函數,除了可以用來設置網格軌道尺寸之外,還可以用于其他長度屬性上,比如 paddingmarginwidthfont-size 等。

除了 repeat() 函數之外,其他函數都可以用于 grid-template-columnsgrid-template-rowsgrid-auto-columnsgrid-auto-rows 屬性上。 repeat() 函數只用于 grid-template-columnsgrid-template-rows 屬性上設置顯式網格軌道尺寸。

在 CSS 網格布局中,我們應該盡可能避免使用像 <length><percentage> 這樣的長度值來設置網格軌道尺寸,盡可能地使用這些函數與關鍵詞 min-contentmax-contentauto<flex>fr)值來設置網格軌道大小,這樣做可能讓你的網格更靈活,不容易造成內容溢出打破 Web 布局!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88291.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88291.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88291.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pdf轉圖片(png,jpg)的python腳本

pdf轉圖片&#xff08;png&#xff0c;jpg&#xff09;的python腳本 PDF轉圖片工具 1.安裝庫 pip install pymupdf 2.如果需要pdf轉jpg的更改DEFAULT_FORMAT即可 3.一定注意要將腳本與待轉化的.pdf文件放在同一個目錄 4.運行腳本&#xff0c;將腳本所在目錄所有.pdf文件轉…

大模型本地部署,擁有屬于自己的ChatGpt

ChatGpt 以其強大的信息整合和對話能力驚艷了全球,在自然語言處理上面表現出了驚人的能力。不管用于文案撰寫還是程序輔助開發都大大提高了我們的工作效率,但是其使用有一定的門檻,讓我們大多數人都望而卻步,今天我們利用ollama實現本地大模型的步驟,讓我們輕松擁有自己的…

【mcu】-老舊小區門禁電話改造指南

老舊小區門禁電話改造指南(四線制DIY方案) 一、明確四根線的功能(關鍵第一步) 通常四線制門禁電話的線纜定義如下(需用萬用表驗證): 線色 常見功能 電壓/信號類型 檢測方法 紅線 電源正極(+12V) DC 12V(待機) 萬用表直流檔測對黑線電壓 黑線 電源負極(GND) 0V 與…

word中如何快速打出上標?

在 Microsoft Word 中快速輸入上標的方法有以下幾種&#xff0c;推薦掌握 鍵盤快捷鍵法&#xff08;最常用高效&#xff09;&#xff1a; ? 方法一&#xff1a;快捷鍵法&#xff08;強烈推薦&#xff0c;效率最高&#xff01;&#xff09; 輸入需要上標的文字/數字&#xff0…

如何優化HarmonyOS 5的分布式通信性能?

以下是針對HarmonyOS 5分布式通信性能優化的系統性方案&#xff0c;結合核心技術特性與實踐經驗&#xff1a; 一、傳輸層優化 數據壓縮與批處理 // 啟用ZLIB壓縮&#xff08;>1KB自動壓縮&#xff09; DistributedConfig config new DistributedConfig.Builder().setCom…

Matplotlib圖像處理三劍客:imshow(), imread(), imsave()

Matplotlib是Python中最著名的數據可視化庫之一&#xff0c;它不僅能夠繪制各種統計圖表&#xff0c;還提供了強大的圖像處理功能。本文將重點介紹Matplotlib中三個核心的圖像處理方法&#xff1a;imshow()、imread()和imsave()&#xff0c;通過示例代碼展示它們的使用方法。 …

[特殊字符]防止 MyBatis-Plus 中模糊查詢 `%` 查出全表:實現通配符轉義攔截器

目錄標題 ?為什么需要轉義 % 和 _&#x1f9ea; 使用案例&#xff1a;防止傳入 % 導致全表查詢&#x1f3af; 支持哪些場景&#xff1f;? 攔截器實現思路&#x1f9e9; 核心攔截器代碼實現&#x1f510; 可選忽略某些 SQL 的轉義 ?為什么需要轉義 % 和 _ 在使用 MyBatis-Pl…

linux grep的一些坑

grep -a "commit" a.log 可以獲取到所有的數據&#xff08;可以看到a.log所有的commit關鍵詞&#xff09; 但cat a.log|grep "commit" 無法全部獲取到&#xff08;只能看到a.log中部分的的commit&#xff09; 細分析和可能原因&#xff1a; 1. 二進制文件…

牛客 AI 面試 Ultra 版升級:開啟招聘新紀元

每到招聘季&#xff0c;HR 們便陷入繁忙與焦慮。海量簡歷篩選耗費大量人力&#xff0c;初步面試耗費數周時間&#xff0c;好不容易安排好面試官與候選人時間&#xff0c;又可能因各種意外狀況打亂節奏。而牛客 AI 面試 Ultra 版恰似一束光&#xff0c;照亮了招聘流程優化的道路…

OSS與NAS混合云存儲架構:非結構化數據統一管理實戰

AI訓練集管理面臨的核心挑戰&#xff1a;數據規模爆炸式增長與訪問模式多樣化的矛盾。ImageNet等典型數據集已達150TB規模&#xff0c;傳統單一存儲方案面臨三重困境&#xff1a; NAS在PB級場景下硬件成本呈指數增長OSS對象存儲無法滿足高頻隨機訪問需求跨存儲數據訪問導致訓練…

72、單元測試-常用測試注解

72、單元測試-常用測試注解 在單元測試中&#xff0c;常用的測試注解可以幫助組織和管理測試代碼&#xff0c;提高測試的可讀性和可維護性。以下是JUnit和TestNG框架中一些常用的測試注解及其功能&#xff1a; #### JUnit注解 1. **Test** - 標記一個方法為測試方法。 - 可以設…

強化學習在大型語言模型訓練中的最新進展:開源項目深度分析報告

強化學習在大型語言模型訓練中的最新進展&#xff1a;開源項目深度分析報告 引言 近年來&#xff0c;人工智能領域見證了大型語言模型(LLM)的迅速崛起&#xff0c;而強化學習作為機器學習的重要分支&#xff0c;在提升LLM推理能力方面展現出巨大潛力。隨著OpenAI發布o1等推理…

微服務:服務治理

簡單描述這個過程&#xff1a; 生產者與消費者之間的供需關系僅憑這兩者很難有效維持&#xff0c;比如某個消費者掛掉了&#xff0c;而生產者并不知道&#xff0c;就會依然給掛掉的消費者提供內容&#xff0c;那么此時的內容明顯就是未獲取到的&#xff0c;從而出現輸出問題。…

關于數據編碼、進制、位運算的詳細講解(從屬GESP三級)

本章內容 數據編碼基礎 進制轉換 位運算基礎 別讓符號位絆住你的步伐&#xff0c;掌握補碼&#xff0c;讓加減法都成為加法。 一、 數據編碼基礎 目標&#xff1a;掌握 原碼 / 反碼 / 補碼 的定義與互轉、常見進制&#xff08;2 / 8 / 10 / 16&#xff09;互化方法&#x…

實戰項目8(11)

任務場景一 按照下圖完成網絡拓撲搭建和配置 任務要求&#xff1a; 1、根據個人模擬器情況&#xff0c;將各交換機的MAC地址標注在拓撲圖中&#xff0c;并將結果進行截圖。 把每個交換機的這個復制粘貼出來【如上圖綠色標記的】 【SW1】配置 dis stp 【SW2】配置 dis stp 【…

儲能系統的離網,并網,構網,跟網 簡介

一、并網&#xff08;Grid-Connected&#xff09; ? 定義&#xff1a;PCS輸出與公共電網并聯運行&#xff0c;電網主導電壓和頻率&#xff0c;PCS按設定的有功/無功功率注入電網。 ? 特點&#xff1a; 電網存在、電壓頻率穩定 PCS僅作為電源“從機”&#xff0c;不能主導電壓…

Solr 初始環境搭建(Windows)

前言 Apache Solr 是一個開源的、基于 Java 的企業級搜索平臺&#xff0c;構建在 Apache Lucene 之上&#xff0c;提供了強大的全文檢索、分布式搜索、索引管理、高亮顯示、分面搜索等功能。它被廣泛應用于電子商務、內容管理系統&#xff08;CMS&#xff09;、數據分析和大規模…

系統架構設計的全方位視角:深入解析4+1視圖模型及其應用實踐

在當今復雜多變的軟件開發環境中&#xff0c;如何全面把握系統架構&#xff0c;滿足不同利益相關者的需求&#xff0c;是每位架構師面臨的重大挑戰。“41”視圖模型作為一種經典的架構描述框架&#xff0c;為解決這一難題提供了系統化的方法論。本文將深入剖析這一模型的理論基…

vue.js 3: markmap using typescript

在項目目錄文件下&#xff0c;通過cmd運行下述指令。 npm create vuelatest cd vue-projectnpm installnpm run format npm run dev或 npm init vuelatest cd vue-prjectnpm run build --打包項目創建項目沒有node_modules npm init -y npm install vue-routernpm install mark…

聚寬量化——股票時間序列函數

import matplotlib.pyplot as plt import pandas as pd from mpl_finance import candlestick2_ochl import mplfinance as mpf from unittest import TestCaseclass TestPandasKline(TestCase):#讀取股票數據&#xff0c;畫出K線圖def testKLineChart(self):file_name "…