一道有意思的 CSS 面試題,FizzBu​​zz ~

chokcoco發表於2022-03-28

FizzBu​​zz 是一道很有意思的題目。我們來看看題目:

如果遇見了 3 的倍數要說 Fizz,5 的倍數就說 Buzz,如果既是 3 的倍數又是 5 的倍數就說 FizzBuzz

如果是在一些程式語言中,這是一道比較初級的題目,當然,稍微轉換一下,我們就可以把它轉換成一道有關 CSS 選擇器的題目。

假設我們有如下結構:

<ul>
    <li></li>
    <li></li>
    <li></li>
    // ... 很多個 li
    <li></li>
    <li></li>
</ul>

通過 CSS 選擇器,實現當 li 的序號為 3 的倍數時,li 輸出 Fizz,5 的倍數就說 Buzz,如果既是 3 的倍數又是 5 的倍數就輸出 FizzBuzz。當然,如果不滿足上述 3 個條件,需要輸出當前的序號。

要求的效果如下:

簡單分析題目

這裡題目看似考察 CSS 選擇器,其實還有幾個隱藏的考點:

  1. <li></li> 本身內部是空值,如何賦予內容?

這裡的第一個考點就是CSS 偽元素,CSS 中可以通過偽元素的 content 屬性,填充文字內容。

  1. 如何填充 li 當前的序號?

第二個考點就是如何填充當前 li 的 index 序號?通過選擇器找到對應的 3、5、15 的倍數相對簡單,那面對剩下的不滿足規則的 li,它的序號應該如何填充呢?

這裡需要運用到 CSS 計數器,也就是如下兩個屬性:

  • counter-increment
  • counter

屬性用於將 CSS Counters 的值增加給定值。利用它可以實現 CSS 內部的一個計數器。

解題

簡單分析之後,解題就比較簡單了,直接上程式碼:

li {
    list-style-type: unset;
    counter-increment: fizzbuzz;
}
li::before {
    content: counter(fizzbuzz);
}
li:nth-child(3n)::before {
    content: "fizz";
}
li:nth-child(5n)::before {
    content: "buzz";
}
li:nth-child(15n)::before {
    content: "fizzbuzz";
}

如果不滿足 fizzbuzz 規則的,使用 CSS 計數器填充 content 內容 content: counter(fizzbuzz),滿足規則的則使用對應的字串填充 content。

結果如下:

CodePen Demo -- CSS FizzBuzz 1

延伸一下

當然,這個 FizzBuzz 還可以用於建立一些有意思的佈局。我們利用 FizzBuzz 的佈局,構建一幅有意思的網格圖片:

li {
    width: 40px;
    height: 40px;
    background: lightskyblue;
}
li:nth-child(3n) {
  background-color: azure;
}
li:nth-child(5n) {
  background-color: peachpuff;
}
li:nth-child(15n) {
  background-color: dodgerblue;
}

它可以用於生成一些有意思的背景網格圖:

放大了看,甚至帶有一些視覺上的錯位的感覺。當然,改變盒子的寬度,效果也是不停地在變化:

CodePen Demo -- CSS FizzBuzz Grid

最後

好了,本文到此結束,希望對你有幫助 :)

如果還有什麼疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。

本文參與了 SegmentFault 思否徵文「如何“反殺”面試官?」,歡迎正在閱讀的你也加入。

相關文章