天天看點

一個進階 CSS 面試題:在 CSS 中實作 if-else

一個進階 CSS 面試題:在 CSS 中實作 if-else

英文 | https://medium.com/frontend-canteen/an-advanced-css-interview-question-implement-if-else-in-css-bb681d786d76

翻譯 | 楊小愛

我的一個朋友在最近的一次面試中遇到了一個有趣的 CSS 面試問題。當我第一次看到這個問題時,我認為這是一個常見的CSS問題。然而,經過仔細研究,我發現了這個問題的有趣部分。

面試題:請用CSS實作如下效果:

一個進階 CSS 面試題:在 CSS 中實作 if-else

頁面上有一些數字顯示文章閱讀的數量。如果數字小于 100,則數字的顔色為灰色。如果數字大于或等于 100,則數字為棕色,而且這種顔色可以動态調整,而不是提前預設。

一個進階 CSS 面試題:在 CSS 中實作 if-else

最後面試官要求用純CSS來解決這個問題,你知道如何達到這個效果嗎?

題目分析

這個問題的本質是什麼?

這個問題的本質很簡單,也就是說,這實際上是一個 if-else 問題。

如果我們用僞代碼描述這個問題,它應該是這樣的:

let color;
if (reads < 100){
  color = 'gray'
} else {
  color = 'brown'
}      

是以現在問題變成了:我們如何在 CSS 中實作這個 if-else 邏輯?請記住,CSS 中沒有 if-else 關鍵字之類的東西。

在 CSS 中實作 if-else

在 CSS 中實作 if-else 的邏輯是本題考查的核心技能。讓我們在下面完成這個邏輯。如果你學會了這個技巧,你可以用它來實作許多強大的 CSS 效果。

首先,讓我們了解一個叫做clamp的函數。

clamp() CSS 函數将一個值限制在上限和下限之間。clamp() 允許在定義的最小值和最大值之間的值範圍内選擇中間值。

基本文法格式:

clamp(min, var, max)      

我們可以将clamp函數了解為這樣的僞代碼:

funciton clamp(min, var, max){
  if(var <= min){
    return min
  }


  if(var >= max){
    return max
  }


  if(var > min && var < max){
    return var
  }
}      

是以:

clamp(10, 13, 20) → 13

clamp(10, 2, 20) → 10

clamp(10, 30, 20) → 20

用法示例:

一個進階 CSS 面試題:在 CSS 中實作 if-else

font-size 的值不會超過 20px,也不會低于 10px。

這是clamp的基本用法。

如果您對clamp仍有疑問,可以參考 MDN 文檔。

接下來,我們在 CSS 中實作這個功能。

result的值根據 var 的值而變化:

當 var 的值小于 100 時,結果的值為 10;

當 var 的值大于等于 100 時,結果變為 20。

如果我們用僞代碼描述這個問題,它應該是這樣的:

let result;
if(var < 100){
  result = 10
} else {
  result = 20
}      

這個要求和clamp函數類似,但又不一樣。clamp可以将 var 的值限制在一個範圍内,但我們現在希望結果的值是 10 或 20。

那我們怎麼做?

有一個特殊的技巧:我們可以放大 var 的變化,使其值要麼達到區間的上限,要麼達到區間的下限。

于是:

let result = clamp(10, (var-99) * 20, 20)      

這會産生一個效果:

  • 如果 var 的值為 99,則表達式變為:clamp(10, 0, 20), takes 10.
  • 如果 var 的值為 100,則變為:clamp(10, 20, 20), takes 20.

用一張圖解釋:

一個進階 CSS 面試題:在 CSS 中實作 if-else

同樣,如果我們希望:

當 var 的值小于 50 時,result的值為 5。

當 var 的值大于等于 50 時,result的值為 15。

我們隻需要這樣寫:

let result = clamp(5, (var-49) * 15, 15)      

你有沒有注意到:這實際上是 if-else 的效果,我們做到了。

一個進階 CSS 面試題:在 CSS 中實作 if-else

在 CSS 中切換顔色

回到最初的面試問題。

為了讓我們後面可以使用 CSS 進行變量計算,我們需要将值放在一個 CSS 變量中,是以 HTML 可以這樣寫:

<num style="--num:1">1<span>reads</span></num>
<num style="--num:99">99<span>reads</span></num>
<num style="--num:102">102<span>reads</span></num>      

如果我們不需要考慮 HTML 語義或 SEO 因素,這裡的“數字”和“讀取”都可以由僞元素生成:

<head>
  <style>
    num::before {
      counter-reset: num var(--num);
      content: counter(num);
    }


    num::after {
      content: 'reads';
    }
</style>
</head>


<body>
  <div>
    <num style="--num:1"></num>
    <num style="--num:99"></num>
    <num style="--num:102"></num>
  </div>
</body>      

如果對 content 和 counter-reset 不熟悉,可以檢視 MDN 文檔。

  • content :https://developer.mozilla.org/en-US/docs/Web/CSS/content
  • counter-reset:https://developer.mozilla.org/en-US/docs/Web/CSS/counter-reset

具體的示範效果,可以通過以下位址檢視:https://codepen.io/bytefishmedium/pen/VwQrGEb

棕色為#aa540e,用HSL顔色表示為hsl(27, 50%, 36%),如下:

一個進階 CSS 面試題:在 CSS 中實作 if-else

它的飽和度控制顔色的鮮豔程度。飽和度越高,顔色越鮮豔,飽和度越低,顔色越暗。當飽和度降低到0時,就變成了完全的灰色,如下:

一個進階 CSS 面試題:在 CSS 中實作 if-else

在灰色和棕色之間切換顔色,即在 hsl(27, 85%, 36%) 和 hsl(27, 85%, 36%) 之間切換。

于是就有如下代碼:

num{
  --s: clamp(0%,(var(--num) - 99) * 99%,85%);/* >100 */
  color: hsl(27 var(--s) 36%);
}      

最終的示範:https://codepen.io/bytefishmedium/pen/WNMXabm

總結

我們通過clamp函數在CSS中實作if-else效果,最後讓顔色根據變量的值進行切換。

其實原面試題還有另外一部分,簡單來說就是:讓顔色在多個值之間切換。僅使用 if-else 不足以滿足此要求,有興趣的話,可以留言交流學習。