根據子元素數量顯示不同樣式-純css解決方案

老沙322發表於2019-01-20

0. 知識儲備

css3元素選擇器

  • :only-child 匹配屬於其父元素的唯一子元素的每個元素。
  • :last-child 選擇屬於其父元素最後一個匹配子元素。
  • :first-child 選擇屬於其父元素最後一個匹配子元素。
  • :nth-child(n) 選擇屬於其父元素的第n個子元素。
  • :nth-last-child(n) 同上,從最後一個子元素開始計數。
  • :nth-last-child(an+b) 匹配文件樹中在其之後具有 an+b-1 個兄弟節點的元素,其中 n 為正值或零值。
  • ~ 是與所選元素同級,位於所選元素之後的所有兄弟元素。
  • 參考文件

1. 問題提出:

有一個展示最多4個元素的頁面(圖A),設計要求根據元素數量不同展示不同的樣式(圖B1、B2、B3)。

我的原則是能用css實現的就不用js實現,雖然各種框架可以很容易根據子元素數量去設定class,但是我想從css入手解決問題。

原始程式碼

<style>
    ul {
      border: 1px solid #ccc;
      box-sizing: border-box;
      padding: 0 10px 0 0;
      margin: 0 auto;
      width: 232px;
    }
    ul:after {
        content: '';
        display: table;
        clear:both;
    }
    ul>li {
        list-style: none;
        float: left;
        margin: 10px 0 10px 10px;
        padding: 0;
        height: 80px;
        width: 100px;
        background: #f00;
        font-size: 30px;
        font-weight: 700;
        color: #000;
        text-align: center;
        line-height: 80px;
    }
</style>
複製程式碼
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>
複製程式碼

圖A
圖A↑
圖B1
圖B1↑
圖B2
圖B2↑
圖B3
圖B3↑

2. 純css解決方案

得以純css解決的原因是無需考慮不相容css3的瀏覽器。

css3的元素選擇器中,:only-child 匹配屬於其父元素的唯一子元素的每個元素,圖B1的問題就可以馬上解決。**:only-child實質上等同於:first-cihld:last-child。**按照這個思路,圖B2的第一個元素可以用li:first-child:nth-last-child(2)表示、第二個元素可以用li:nth-child(2):nth-last-child(1)表示。同理可以處理圖B3。

程式碼如下

<style>
    ul {
      border: 1px solid #ccc;
      box-sizing: border-box;
      padding: 0 10px 0 0;
      margin: 0 auto;
      width: 232px;
    }
    ul:after {
        content: '';
        display: table;
        clear:both;
    }
    ul>li {
        list-style: none;
        float: left;
        padding: 0;
        height: 80px;
        background: #f00;
        font-size: 30px;
        font-weight: 700;
        color: #000;
        text-align: center;
        line-height: 80px;
    }
    
    /* 只有一個li元素 */
    ul>li:only-child {
        width: 180px;
        margin: 10px 25px;
    }

    /* 有兩個li元素 */
    ul>li:first-child:nth-last-child(2),
    ul>li:first-child:nth-last-child(2) ~ li {
        width: 100px;
        margin: 10px 0 10px 10px;
    }

    /* 有三個li元素的第1個元素 */
    ul>li:first-child:nth-last-child(3) {
        width: 180px;
        margin: 10px 25px;
    }

    /* 有三個li元素的第2個及以後元素 */
    ul>li:nth-child(2):nth-last-child(2),
    ul>li:nth-child(2):nth-last-child(2) ~ li {
        width: 100px;
        margin: 10px 0 10px 10px;
    }

    /* 有四個及四個以上的li元素 */
    ul>li:first-child:nth-last-child(n+4),
    ul>li:first-child:nth-last-child(n+4) ~ li {
        width: 100px;
        margin: 10px 0 10px 10px;
    }
</style>
複製程式碼
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>
複製程式碼

3. 問題擴充

目前頁面只有4個元素,如果再追加元素,大於等於4個時想繼續按照圖A往下排列(圖B4),可以這樣寫:

li:first-child:nth-last-child(n+4),
li:first-child:nth-last-child(n+4) ~ li {
......
}
複製程式碼

圖B4
圖B4↑

運用到實際專案中也可以根據情況選擇css前處理器實現以上思路的程式碼使程式碼更簡潔,從而達到用純css實現根據子元素數量顯示不同樣式。

相關文章