Clamp()、Max() 和 Min() CSS 函數(shù)的用例
點擊上方 前端Q,關注公眾號
回復加群,加入前端Q技術交流群
英文 | https://ishadeed.com/article/use-cases-css-comparison-functions/
2020 年 4 月開始支持 CSS 比較函數(shù),當時我寫了一篇介紹關于它們的文章。我喜歡使用所有這些,但我最喜歡的一個是clamp(),它是我最常用的一個。

.section-image {width: clamp(70px, 80px + 15%, 180px);}

通過設置最小、首選和最大寬度,圖像將根據(jù)其容器寬度縮小或增長,這是由于使用了固定值和百分比 80px + 15% 的混合。
演示地址:https://codepen.io/shadeed/pen/qBYPdOq?editors=1100
裝飾元素
如果你需要在部分項目中添加裝飾元素,大多數(shù)時候,元素需要響應,并且可能需要根據(jù)視口大小進行不同的定位,你會怎么做?
如下示例效果:

兩側有兩個裝飾元素。在移動設備上,它們會占用太多空間,因此我們只想展示其中的一小部分。

為了解決這個問題,我們可以在移動設備上使用媒體查詢來控制它們。
CSS:
.decorative--1 {left: 0;}.decorative--2 {right: 0;}@media (max-width: 600px) {.decorative--1 {left: -8rem;}.decorative--2 {right: -8rem;}}
雖然這可行,但我們可以使用帶有 CSS clamp() 函數(shù)的無媒體查詢解決方案。
CSS:
@media (max-width: 600px) {.decorative--1 {left: clamp(-8rem, -10.909rem + 14.55vw, 0rem);}.decorative--2 {right: clamp(-8rem, -10.909rem + 14.55vw, 0rem);}}
讓我剖析一下上面的 CSS,讓你更容易理解:
我們想要的是設置最小左偏移為-8rem,最大值為0rem。
有了這個,我們把它留給 CSS clamp() 來決定首選值并尊重我們設置的最小值和最大值。
我用這個計算器(https://min-max-calculator.9elements.com/)得到了上面的 clamp() 數(shù)字。
演示地址:https://codepen.io/shadeed/pen/LYmzVZW?editors=1100
流體英雄高度
與前面的示例相關,英雄部分的高度可以根據(jù)視口大小而不同。因此,我們傾向于通過媒體查詢或使用視口單元來改變它。
CSS:
.hero {min-height: 250px;}@media (min-width: 800px) {.hero {min-height: 500px;}}
我們可以混合使用固定值和視口單位,但我們需要注意不要在較大的視口上設置很大的高度,然后,我們需要設置一個最大高度。
CSS:
.hero {min-height: calc(350px + 20vh);}@media (min-width: 2000px) {.hero {min-height: 600px;}}
使用 CSS clamp(),我們可以只用一個 CSS 聲明來設置最小、首選和最大高度。
.hero {min-height: clamp(250px, 50vmax, 500px);}
調(diào)整屏幕大小時,你會注意到高度會根據(jù)視口寬度逐漸變化。在上面的示例中,50vmax 表示“視口最大尺寸的 50%。

演示地址:https://codepen.io/shadeed/pen/LYmzVZW?editors=1100
加載條
這個例子的靈感來自 Andy Bell 的一條推文,我真的很喜歡在這個用例中使用 CSS clamp()!

條形按鈕應該從左到右進行動畫處理,反之亦然。在 CSS 中,按鈕可以絕對定位在左側。
CSS:
.loading-thumb {left: 0%;}
要將按鈕放在最右邊,我們可以使用 left: 100% 但這會帶來一個問題,按鈕將從裝載桿容器中吹出。

CSS:
.loading-thumb {left: 100%;}
這是意料之中的,因為在這種情況下 100% 從拇指末端開始,因此將其推出。
我們可以使用 CSS calc() 減去按鈕寬度,它會起作用,但這不是 100% 靈活的。
CSS:
.loading-thumb {/* 40px represents the thumb width. */left: calc(100% - 40px);}
讓我們探索如何使用 CSS 變量和比較函數(shù)來改進 CSS。
CSS:
.loading-thumb {--loading: 0%;--loading-thumb-width: 40px;position: absolute;top: 4px;left: clamp(0%,var(--loading),var(--loading) - var(--loading-thumb-width));width: var(--loading-thumb-width);height: 16px;}
以下是上述 CSS 的工作原理:
首先,我們將最小值設置為 0%。
首選值是 --loading CSS 變量的當前值。
最大值表示當前加載減去按鈕寬度。
CSS clamp() 在這里為我們提供了這個組件的三個不同的統(tǒng)計信息,我個人喜歡這個解決方案!

不僅如此,我們還可以為不同的設計擴展相同的概念。考慮下圖:

當前進度值在它上面有一個小句柄,當值為 100% 時,我們需要寬度來尊重它。
如下圖所示,圓圈必須在最右側結束,如果我們不注意這一點,它最終會吹出手柄寬度的一半(參見帶有紅色標志的第二行)。

在這種情況下,我們可以使用 CSS clamp() 函數(shù)。
CSS:
.loading-progress {width: clamp(10px, var(--loading), var(--loading) - 10px);}
最小值等于半圓寬度,優(yōu)選值是當前加載百分比,最大值是半圓減去當前百分比的結果。

演示地址:https://codepen.io/shadeed/pen/rNvGVOa?editors=0100
動態(tài)線分隔符
今年早些時候,我寫了一篇關于我正在開發(fā)的 UI 的有趣 CSS 解決方案的文章。
考慮下圖,我們在兩個部分之間有一個行分隔符。

在移動設備上,該分隔符應變?yōu)樗?,如下所示?/span>

我的解決方案是使用邊框和彈性框,這個方法是帶有邊框的偽元素可以擴展以填充垂直和水平狀態(tài)的可用空間。
CSS:
.section {display: flex;flex-direction: column;gap: 1rem;}.section:before {content: "";border: 1px solid #d3d3d3;align-self: stretch;}@media (min-width: 700px) {.section {align-items: center;flex-direction: row;}}
我們甚至可以通過使用 CSS clamp 來實現(xiàn),Temani Afif 提出了一個根本不需要媒體查詢的解決方案。
CSS:
.section {--breakpoint: 400px;display: flex;flex-wrap: wrap;}.section:before {content: "";border: 2px solid lightgrey;width: clamp(0px, (var(--breakpoint) - 100%) * 999, 100%);}
讓我們剖析一下上面的 CSS:
0px:最小值,用于垂直分隔符。它為零,因為我們使用的是 CSS 邊框。
(var(--breakpoint) - 100%) * 999 根據(jù)視口寬度在 0px 或 100% 之間切換。
條件邊界半徑
大約一年前,我在 Facebook 提要 CSS 中發(fā)現(xiàn)了一個巧妙的 CSS 技巧。它是關于使用 CSS max() 比較函數(shù)根據(jù)視口寬度將卡片的半徑從 0px 切換到 8px。
CSS:
.card {border-radius: max(0px,min(8px, calc((100vw - 4px - 100%) * 9999)));}
讓我們詳細了解一下上面的 CSS。
現(xiàn)在我們來剖析一下上面的 CSS:
我們有一個 max() 函數(shù),用于比較 0px 和 min() 的計算值,它將選擇較大的值。
min() 函數(shù)在 8px 和 calc((100vw - 4px - 100%) * 9999) 的計算值之間進行比較,這將導致非常大的正數(shù)或負數(shù)。
9999 是一個很大的數(shù)字,強制該值為 0px 或 8px。
有了上面的內(nèi)容,當卡片占據(jù)整個視口寬度時,它的半徑為零,或者在更大的屏幕上為 8px。
CSS 文章標題

在構建CSS 文章標題時,我需要一種方法來為內(nèi)容添加動態(tài)填充,同時,在較小的視口上保持最小值。
這個想法是文章標題不包含在包裝元素中,因此我們需要一種方法來模擬內(nèi)容實際上被包裝并與下面的內(nèi)容對齊。

為此,我們需要一種在 CSS 中使用以下公式的方法:
動態(tài)填充 = (視口寬度 - 包裝寬度) / 2感謝 CSS max() 函數(shù),我們可以添加最小填充,以及在需要時切換到動態(tài)填充的方法。
CSS:
:root {--wrapper-width: 1100px;--wrapper-padding: 16px;--space: max(1rem,calc((100vw - calc(var(--wrapper-width) - var(--wrapper-padding) *2)) / 2));}.article-header {padding-left: var(--space);}
這個想法是我們需要最小填充為 1rem,然后,它將根據(jù)視口寬度動態(tài)變化。
間距
有時,我們可能需要根據(jù)視口寬度更改組件或網(wǎng)格的間距。不帶 CSS 比較功能!我們只需要設置一次。
.wrapper {display: grid;grid-template-columns: repeat(3, 1fr);grid-gap: min(2vmax, 32px);}
關于間距的知識,我們后面將會詳細介紹,今天的內(nèi)容就先分享到這里,感謝你的閱讀。

往期推薦



最后
歡迎加我微信,拉你進技術群,長期交流學習...
歡迎關注「前端Q」,認真學前端,做個專業(yè)的技術人...


