一文學會使用 CSS 中的 min(), max(), clamp() 以及它們的使用場景

做者:Ahmad shaded
譯者:前端小智
來源:sitepoint
點贊再看,微信搜索 【大遷世界】關注這個沒有大廠背景,但有着一股向上積極心態人。本文 GitHub https://github.com/qq44924588... 上已經收錄,文章的已分類,也整理了不少個人文檔,和教程資料。

2020年4月8日Firefox瀏覽器支持了 CSS 比較函數min()max()clamp()),這意味着如今全部主流瀏覽器都支持它們。 這些CSS函數最大的做用就是能夠爲咱們提供動態佈局和更靈活設計組件方法。 css

簡單的這些元素主要用來設置元素尺寸,如容器大小,字體大小,內距,外距等等 。在這篇文章中,我將用一些示例和你們一塊兒來探討這幾個函數在實際中的使用,但願能更好的幫助你們理解它們。前端

兼容性

minmax 的支持狀況:git

clipboard.png

clamp()的支持狀況:github

圖片描述

CSS 比較函數

根據CSS規範,比較函數是關於比較多個值並取其一的操做,咱們來研究一下函數。瀏覽器

Min() 函數

min() 函數支持一個或多個表達式,每一個表達式之間使用逗號分隔,而後以最小的表達式的值做爲返回值,咱們可使用min()爲元素設置最大值。微信

考慮下面的例子,咱們但願元素的最大寬度爲500pxapp

.element {
    width: min(50%, 500px);
}

clipboard.png

瀏覽器須要在(50%,500px) 取一個最小值,由於有個百分比,因此最終結果取決於視口寬度。若是50%的計算值大於500px,那麼就取 500pxide

不然,若是50%計算值小於500px,則50%將用做寬度的值,假設視口的寬度是 900px, 最終元素的寬度爲 900px x 50% = 450px函數

clipboard.png

下面是一個交互的動畫爲了讓你們更好的理解:工具

圖片描述

事例源碼:https://codepen.io/shadeed/debug/f5e338c8a1c7cd29e382c72a5eb37e48/auth

Max() 函數

max()函數和min()函數語法相似,區別在於max()函數返回的是最大值,min()函數返回的是最小值。一樣,咱們可使用man()爲元素設置最小值。

考慮下面的例子,咱們但願元素的最小寬度爲500px

.element {
    width: max(50%, 500px);
}

瀏覽器須要在(50%,500px) 取一個最大值,由於有個百分比,因此最終結果取決於視口寬度。若是50%的計算值小於500px,那麼就取 500px

不然,若是50%計算值大於500px,則50%將用做寬度的值,假設視口的寬度是 1150px, 最終元素的寬度爲 1150px x 50% = 575px

clipboard.png

事例源碼:https://cdpn.io/shadeed/debug/cca927df45964fbe1a8342ad3ace6d71

Clamp() 函數

clamp()函數做用是返回一個區間範圍的值。語法以下:

clamp(MIN, VAL, MAX)

其中MIN表示最小值,VAL表示首選值,MAX表示最大值。意思是,若是VALMINMAX範圍之間,則使用VAL做爲函數返回值;若是VAL大於MAX,則使用MAX做爲返回值;若是VAL小於MIN,則使用MIN做爲返回值。

clamp(MIN, VAL, MAX)實際上等同於max(MIN, min(VAL, MAX))

考慮下面的例子

.element {
    width: clamp(200px, 50%, 1000px);
}

假設咱們有一個元素,其最小寬度爲200px,首選值爲50%,最大值爲1000px,以下所示:

clipboard.png

上面的計算過程是這樣的:

  • 寬度永遠不會低於200px
  • 內容中間首選值是50%,只有在視口寬度大於400px小於2000px時纔有效
  • 寬度不會超過 1000px

事例源碼:https://codepen.io/shadeed/pen/924419f15bfdcf0cd0103b0587524b0b?editors=0010

上下文很重要

計算值取決於上下文。 多是%emremvw/vh。 甚至百分比值也能夠基於視口寬度(若是元素直接位於<body>中),也能夠基於其父元素。

數學表達式

值得一提的是, clamp() 函數也能夠用於數學表達式,而沒必要藉助於 calc(),以下代碼所示:

.type {
  /* 強制字體大小保持在 12px 到 100px 之間 */
  font-size: clamp(12px, 10 * (1vw + 1vh) / 2, 100px);
}

用例

側邊欄和主界面

clipboard.png

一般,頁面的側邊欄是固定的,主界面度是靈活的。 若是視口足夠大,咱們能夠根據視口的大小動態增長側邊欄寬度,這裏咱們可使用max()函數爲其設置最小寬度。

考慮下面的示例:

.wrapper {
    display: flex;
}

aside {
  flex-basis: max(30vw, 150px);
}

main {
  flex-grow: 1;
}

若是視口大於 500px,則側邊欄的最小寬度爲150px(500 * 30% = 150)。

事例源碼: https://codepen.io/shadeed/pen/7f9558f31fdf60bc08c827817c10bf3a?editors=1100

標題字體大小

clipboard.png

clamp()的一個很好的用例是用於標題。假設咱們但願標題的最小大小爲16px,最大大小爲50pxclamp()函數將爲咱們提供一個介於二者之間的值。

.title {
    font-size: clamp(16px, 5vw, 50px);
}

在這裏使用clamp()是很是適合的,由於它確保了所使用的字體大小是可訪問的和易於閱讀的。若是換作min(),那麼就不能在小的視圖中控制字體了。

.title {
    font-size: min(3vw, 24px); /* Not recommended, bad for accessibility */
}

clipboard.png

在移動端,字體大小很小。所以,不要對字體大小使用min()函數。固然,咱們也能夠經過媒體查詢來適配,可是這樣就錯過了一次使用 CSS 比較函數實戰。

如前所述,能夠在max()函數中嵌套min()來實現clamp() 效果,該函數將模仿clamp()函數,以下所示:

.title {
    font-size: max(16px, min(10vw, 50px));
}

事例源碼:https://codepen.io/shadeed/pen/db76480260c104df00c65991df90a203?editors=1100

裝飾性標題

clipboard.png

注意看上圖標題下面有一個大的半透明的標題,這是一個裝飾性的文本,根據視窗的大小來縮放。咱們可使用max()函數和CSS viewport單元來設置它的最小值。

.section-title:before {
  content: attr(data-test);
  font-size: max(13vw, 50px);
}

源碼: https://codepen.io/shadeed/pen/e0128b73de7c84cb9b98cf733a3835c4?editors=1100

平滑漸變

當在CSS中使用漸變時,你可能須要對它進行一些調整,使顏色之間的過渡更加平滑。咱們先看看下面的漸變:

.element {
    background: linear-gradient(135deg, #2c3e50, #2c3e50 60%, #3498db);
}

clipboard.png

注意移動的過渡是有一條比較明顯的線分開,這是很差的。咱們能夠經過使用媒體查詢來解決這個問題:

@media (max-width: 700px) {
    .element {
        background: linear-gradient(135deg, #2c3e50, #2c3e50 25%, #3498db)
    }
}

有一種更加簡潔的方法就是使用 min() 函數,以下 所示:

.element {
    background: linear-gradient(135deg, #2c3e50, #2c3e50 min(20vw, 60%), #3498db);
}

clipboard.png

事例源碼:https://codepen.io/shadeed/pen/2c4bf2ded32f66390fdef13409be4a10?editors=1100

透明漸變

當須要在圖片上放置文本時,咱們應該在圖片上加層漸變讓文本更加可讀。與上一個示例相似,漸變大小應該在小視圖和大視圖之間有所不一樣。見下圖:

clipboard.png

.element {
    background: linear-gradient(to top, #000 0, transparent max(20%, 20vw));
}

事例源碼:https://codepen.io/shadeed/pen/babf1bfd4c85eeb1b6f9f549dd0fe602?editors=1100

容器寬度

clipboard.png

若是有一個容器,它的寬度應該是它父容器的80%,但不能超過780px,你會用什麼?一般,你應該會用max-width,以下所示:

.container {
    max-width: 780px;
    width: 80%;
}

這裏使用 min() 函數也能夠爲元素設置最大值:

.container {
    max-width: min(80%, 780px);
}

事例源碼:https://codepen.io/shadeed/pen/3d8b44709b04efdd7336fe91363e3d76?editors=1100

邊界與陰影

圖片描述

在一些設計案例中,若是元素邊框的寬度和弧度比較大時,在移動時應儘可能減少。經過使用clamp(),咱們能夠根據視窗寬度使其動態。

.element {
    box-shadow: 0 3px 10px 0 red;
    border: min(1vw, 10px) solid #468eef;
    border-radius: clamp(7px, 2vw, 20px);
    box-shadow: 0 3px clamp(5px, 4vw, 50px) 0 rgba(0, 0, 0, 0.2);
}

事例源碼:https://codepen.io/shadeed/pen/7b5c7979e09573ca32150ebfc7f74a66?editors=1100

Grid Gap

clipboard.png

在一個使用風格佈局的界面上,若是咱們想根據視口大小來調整網格之間的間距,使用 clamp() 是很容易作到的:

.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-gap: clamp(1rem, 2vw, 24px);
}

事例源碼:https://codepen.io/shadeed/pen/a14c7d9fcbbae84340a4f83833294f5b?editors=1100

若是在不兼容瀏覽器使用這些方法

與任何新的 CSS 函數同樣,提供後退方案是很重要的。 要實現這一點,咱們可使用如下方法之一:

1.手動添加回退方案

咱們能夠在使用比較函數以前加一個默認的方式,以下所示:

.hero {
    padding: 4rem 1rem;
    padding: clamp(2rem, 10vmax, 10rem) 1rem;
}

支持的瀏覽器將忽略第一個,不支持的將使用第一個padding

使用 CSS @supports

咱們可使用@supports檢測瀏覽器是否支持 CSS 比較函數,以下所示:

.hero {
    /* 默認值,用於不支持的瀏覽器 */
    padding: 4rem 1rem;
}

@supports (width: min(10px, 5vw)) {
   /* 用於支持的瀏覽器  */
  .hero {
    padding: clamp(2rem, 10vmax, 10rem) 1rem;
  }
}

代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

原文:https://heydesigner.com/every...

交流

文章每週持續更新,能夠微信搜索【大遷世界 】第一時間閱讀,回覆【福利】有多份前端視頻等着你,本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,歡迎Star。

相關文章
相關標籤/搜索