在某些場景下,我們需要根據兄弟元素的總數來為它們設置樣式。最常見的場景就是,當一個列表不斷延長時,通過隱藏控件或壓縮控件等方式來節省屏幕空間,以此提升用戶體驗。
- 為保證一屏內容能展示更多的內容,需要將多余的列表項隱藏。
- 二級導航菜單:當菜單項為 1 項時,寬度為 100%;當菜單項為 2 項時,每項寬度為 50%;當菜單項為 3 項時,每項寬度為 33.33333333%;當菜單項為 4 項及以上時,寬度不定,根據內容寬度調整,超出屏幕后滑動菜單查看隱藏的菜單。
不過,對 CSS 選擇符來說,基於兄弟元素的總數來匹配元素並不簡單。
一、設想一個列表,假設僅當列表項的總數大於 3 時就隱藏項目數 4 及之后的項。我們可以用 li:nth-of-type(4)
來選中列表的第四個列表項,再使用 ~ 選擇符選擇后續的兄弟元素。
首頁的產品中心僅展示四項,想要查看更多就需要點擊“更多產品+”跳轉到產品頁,假如循環出的列表總數超過 4 項就隱藏
li { &:nth-of-type(4) ~ li { display: none; } }
二、設想一個二級菜單,當列表項總數小於 5 時,菜單的寬度按照屏幕的寬度比例平均分配,當列表項大於等於 5 時,按照自身內容寬度自適應。
以第一個只有兩項的列表為例,我們需要選擇每一項,並且把其寬度設置為50%。要怎么選擇兩項中的每一項呢,似乎沒有辦法只能使用腳本來判斷。不過 li:nth-of-type 表示父元素只有一個同一類型的子元素,它等同於 li:first-of-type:last-of-type 的集合,既是第一項又是最后一項,那我們就選中了只有一個項目時的這一項。用同樣的思路,li:first-of-type:nth-last-of-type(2) 集合,表示既是第一項又是倒數第二項,那我們就選中了有兩個項目時的第一項了,那么 li:first-of-type:nth-last-of-type(2) , li:first-of-type:nth-last-of-type(2) ~ li 就選中了有兩個項目時的每一項:
li { &:first-of-type:nth-last-of-type(2), &:first-of-type:nth-last-of-type(2) ~ li { width: 50%; } }
如果一個列表有 3 項,把其寬度設置為 33.33333333%。
li { &:first-of-type:nth-last-of-type(3), &:first-of-type:nth-last-of-type(3) ~ li { width: calc(100% / 3); } }
可以使用 SCSS 預編譯器來處理
@mixin n-items($n) { &:first-of-type:nth-last-of-type(#{$n}), &:first-of-type:nth-last-of-type(#{$n}) ~ &{ width: calc(100% / #{$n}); } } .sub-nav-item { @include n-items(1); @include n-items(2); @include n-items(3); @include n-items(4); &:first-of-type:nth-last-of-type(n + 5), &:first-of-type:nth-last-of-type(n + 5) ~ & { padding-right: .15rem; padding-left: .15rem; } }
擴展
上面調用中我們的目的是選擇有 1 - 4 項的列表。如果能夠調用一次就省心了。
需求:
當項目列表為 1 - 4 項時,將字體加粗
受啟發 first-of-type:nth-last-of-type(n + 5) 限定了最小項目數為 5,那可不可以限定最大項目數呢,n 為負數可以實現限定最大數,但是 n 不可能為負數,不過可以給 n 取反。
first-of-type:nth-last-of-type(n + 5):nth-last-of-type(-n + 10) 集合中,當 n 取 0 時,-n + 10 最大,為 10,這時它表示范圍為 5 - 10 的項目個數。
因此我們實現需求:
.sub-nav-item { &:first-of-type:nth-last-of-type(n + 1):nth-last-of-type(-n + 4), &:first-of-type:nth-last-of-type(n + 1):nth-last-of-type(-n + 4) ~ & { font-weight: 500; } }
這時我們實現了根據兄弟元素的個數范圍來設置樣式
未加粗,此時有 6 項。
加粗,此時有 4 項。
加粗,此時有 3 項。