自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何正確使用:Has和:Nth-Last-Child

開發(fā) 項目管理
根據(jù)項目的數(shù)量來改變樣式可能不是一次性的用法,它可以被提取到不同的用例中。通過使用樣式查詢,我們可以只寫一次,并在任何地方重用它們。

我們可以用CSS檢查,以了解一組元素的數(shù)量是否小于或等于一個數(shù)字。例如,一個擁有三個或更多子項的grid。你可能會想,為什么需要這樣做呢?在某些情況下,一個組件或一個布局可能會根據(jù)子元素的數(shù)量而改變。

這在CSS中已經(jīng)存在很多年了,但現(xiàn)在通過CSS :has,它變得更加強(qiáng)大。我們可以把nth-last-child選擇器和:has結(jié)合起來,以達(dá)到神奇的效果!你沒聽錯。

在這篇文章中,我將強(qiáng)調(diào)幾個例子,說明我們可以將一個CSS選擇器和:has結(jié)合起來,形成一個有條件的組件/布局狀態(tài)。

總覽

  • 介紹:nth-last-child
  • CSS中的數(shù)量查詢限制
  • 不可能根據(jù)元素的數(shù)量來設(shè)計父元素的樣式
  • 讓它們在不同的視口尺寸上奏效
  • 為了控制間距要付出更多
  • 使用案例 使用案例
  • 基于子項數(shù)量而變化的Grid
  • 動態(tài)標(biāo)題布局
  • 動態(tài)新聞部分
  • 模態(tài)框操作
  • 用戶頭像
  • 時間軸
  • logo網(wǎng)格
  • 總結(jié)

介紹:nth-last-child

這篇文章的主要要素之一是:nth-last-child偽類。我們可以使用該選擇器來模擬計算子元素。

來看看它是如何工作的。我將盡可能用直白的話來解釋。

請看下圖:

圖片圖片

我們有一個五個卡片的列表。我們將用這個例子來證明我們可以用:nth-last-child做什么。

在下列CSS中,n + 3意味著:

li:nth-last-child(n + 3) {
    /* styles */
}

從末端選擇前三項,從第三項開始計算。

讓我們仔細(xì)看看。首先,我們需要從末端計算三個項。這樣一來,第三項實際上就是我們從末端開始計算的第一項。

圖片圖片

我們從第三項算起直到最后,這里是被選中的項:

圖片圖片

CSS中的數(shù)量查詢限制

我們可以使用:nth-last-child作為CSS的數(shù)量查詢。

請看下圖:

圖片圖片

我們有一個信息清單,當(dāng)我們有5個或更多的項時,它的顯示方式會不同。

<ul>
   <li></li>
   <li></li>
   <li></li>
   <!-- more items -->
</ul>
li {
    /* default styles */
}

/* If the list has 5 or more items */
li:nth-last-child(n + 5),
li:nth-last-child(n + 5) ~ li {
  width: 50%;
  display: inline-block;
  border-bottom: 0;
}

雖然這很有效,但在某些方面仍然有點局限性。

不可能根據(jù)元素的數(shù)量來設(shè)計父元素的樣式

想象一下,當(dāng)有5個或更多的項時,我們需要為每個<li>添加display: flex。我們不能用 :nth-last-child 偽類選擇器來做這個。

原因是,添加display: flex將迫使每個項留在自己的行中,這與要實現(xiàn)的設(shè)計不一致。

li:nth-last-child(n + 5),
li:nth-last-child(n + 5) ~ li {
  width: 50%;
  display: flex;
  flex-direciton: column;
}

圖片圖片

我們可以用display: inline-flex來解決這個問題,但對我來說,這仍然不是最佳解決方案。原因是,瀏覽器會考慮到HTML元素之間的間距,它們應(yīng)該是這樣的:

<ul>
   <li></li><li></li><li></li>
   <!-- more items -->
</ul>

如果我們不這樣做,display: inline-flex的效果將與display: flex相同。解決這個問題的一個方法是將寬度減少1%。

li:nth-last-child(n + 5),
li:nth-last-child(n + 5) ~ li {
  width: 49%;
  display: flex;
  flex-direciton: column;
}

讓它們在不同的視口尺寸上奏效

如果沒有對父類進(jìn)行控制的能力,就不能那么直接地對列表的布局進(jìn)行設(shè)計。例如,當(dāng)容器或視口寬度較小時,我們需要每行顯示1個項。

為了控制間距要付出更多

當(dāng)有3個或更少的項時,間距是水平的,而當(dāng)有5個或更多時,間距是垂直的。我們可以通過將頁邊距從水平方向翻轉(zhuǎn)到垂直方向,或者通過使用CSS gap與Flexbox來手動管理。但是,在這種情況下,我們又不得不使用inline-flex。

CSS :nth-last-child偽類是構(gòu)建條件性布局的關(guān)鍵。通過將它與CSS :has選擇器相結(jié)合,我們可以檢查一個父元素是否至少有特定數(shù)量的項,并對其進(jìn)行相應(yīng)的樣式設(shè)計。這種可能性是無窮無盡的!

使用案例

基于子項數(shù)量而變化的Grid

圖片圖片

當(dāng)我們需要基于子項數(shù)量而更改gird布局時,這在目前的CSS中是不可能的。在CSS的grid中,我們可以使用minmax()基于可用空間來動態(tài)改變grid。

下面是我對CSS網(wǎng)格minmax()的看法:

.list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1rem;
}

結(jié)果看起來是這樣:

圖片圖片

這一點都不完美。我們沒有太多的控制,因為我們需要調(diào)整minmax()中的150px的值。當(dāng)有4個或更少的項時,它可以很好地工作,而當(dāng)有5個或更多的項時就會出現(xiàn)問題。

解決辦法是什么?我們可以用CSS :has檢查是否有超過5個項目或更多,并在此基礎(chǔ)上改變minmax()的值。

/* default grid */
.list {
    --item-size: 200px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(var(--item-size), 1fr));
    gap: 1rem;
}

/* If the grid has 5+ items, change the --item-size width to 150px */
.list:has(li:nth-last-child(n + 5)) {
    --item-size: 150px;
}

我只是改變了--item-size變量,使代碼更容易閱讀,并避免重復(fù)。

動態(tài)標(biāo)題布局

在下圖中,我們有一個標(biāo)題,當(dāng)導(dǎo)航項有4個或更多時,應(yīng)該改變其布局。通過CSS :has和:nth-last-child,我們可以檢測并改變布局。

圖片圖片

.site-header:has(li:nth-last-child(n + 4)) {
    .site-header__wrapper > * {
        flex: initial;
    }

    .site-header__start {
        order: 2;
    }

    .site-header__middle {
        order: -1;
        text-align: start;
    }

    .site-header__end {
        margin-left: auto;
    }
}

以上是Sass的代碼。如果用CSS寫,可能看起來有點多。

.site-header:has(li:nth-last-child(n + 4)) .site-header__wrapper > * {
    flex: initial;
}

.site-header:has(li:nth-last-child(n + 4)) .site-header__start {
    order: 2;
}

.site-header:has(li:nth-last-child(n + 4)) .site-header__middle {
    order: -1;
    text-align: start;
}

.site-header:has(li:nth-last-child(n + 4)) .site-header__end {
    margin-left: auto;
}

我們能做得更好嗎?可以。但這還沒有得到很好的支持(目前來說)。我們可以添加一個布爾CSS變量,當(dāng)標(biāo)題有4個或更多的項目時,它將被切換,然后使用樣式查詢來改變標(biāo)題。

.site-header:has(li:nth-last-child(n + 4)) {
    --layout-2: true;
}

有了這個,當(dāng)導(dǎo)航項有4個或更多時,我們設(shè)置變量--layout-2。

/* This will only works if the --layout-2 CSS variable is set */
@container style(--layout-2: true) {
  .site-header__wrapper {
    > * {
      flex: initial;
    }
  }

  .site-header__start {
    order: 2;
  }

  .site-header__middle {
    order: -1;
    text-align: start;
  }

  .site-header__end {
    margin-left: auto;
  }
}

動態(tài)新聞部分

下面是一個新聞部分的設(shè)計,當(dāng)項目數(shù)為3或更多時,它應(yīng)該改變其布局。

圖片圖片

通過組合CSS的:has和:nth-last-child,我們可以創(chuàng)建一個切換的CSS變量,它將被一個樣式查詢所檢查。

首先,我將假設(shè)默認(rèn)的卡片樣式是水平的。

<div class="layout">
    <article class="card"></article>
    <article class="card"></article>
    <article class="card"></article>
</div>
.layout {
  display: grid;
  grid-gap: 1rem;
}

.card {
  display: flex;
  gap: 1rem;
  align-items: center;
}

然后,我需要檢查.card元素的數(shù)量。

.layout:has(.card:nth-last-child(n + 4)) {
  --layout-4: true;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

現(xiàn)在,我們有一個CSS變量--layout-4,只有當(dāng)我們有4個或更多的項時才會被切換。我們可以用一個樣式查詢來檢查,并相應(yīng)地更新.card的樣式。

@container style(--layout-4: true) {
    .card {
        flex-direction: column;
    }

    .card__thumb {
        flex: 1;
        width: 100%;
        aspect-ratio: 4 / 3;
    }
}

模態(tài)框操作

在一個設(shè)計系統(tǒng)中,我們可能需要根據(jù)我們有多少個操作來動態(tài)地控制模態(tài)操作的排列。

請看下圖:

圖片圖片

比如說,如果只有一個操作,它應(yīng)該居中。否則,向右對齊它們。

下面是CSS:

.modal__footer {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
}

/* If there are 2 buttons or more */
.modal__footer:has(a:nth-last-child(n + 2)) {
    justify-content: flex-end;
}

很簡單,對不對。

用戶頭像

在編輯網(wǎng)站上,一篇文章可能由多個作者撰寫。一個常見的模式是,當(dāng)我們有多個作者時,用負(fù)間距堆疊作者的圖像。

圖片圖片

僅僅通過使用數(shù)量查詢,我們就可以最低限度的實現(xiàn),也就是:

  • 添加負(fù)間距(互相堆疊頭像)。
  • 當(dāng)有多個頭像時,縮小頭像的尺寸。
img:nth-last-child(n+2) ~ img {
    border: 2px solid #fff;
    margin-left: -0.25rem;
    width: 30px;
    height: 30px;
}

上面的方法可行,但它有局限性。如果我們想對容器本身進(jìn)行樣式設(shè)計呢?那么,這就是CSS :has變得強(qiáng)大的地方。

首先,我們需要檢查并切換CSS變量:

.post-author:has(img:nth-last-child(n + 2)) {
    --multiple-avatars: true;
}

如果CSS變量為true,就為多個頭像應(yīng)用下面的樣式:

@container style(--multiple-avatars: true) {
    .avatars-list {
        display: flex;
        background-color: #efefef;
        padding: 8px 12px;
        border-radius: 50px;
    }

    img:not(:first-child) {
        border: solid 2px #fff;
        margin-left: -0.25rem;
    }
}

時間線

另一個有趣的例子是時間線組件,它的CSS效果很好。

圖片圖片

在這個例子中,我想讓時間線在有4個或更多項時,從垂直列表切換到交替式。

首先,使用:nth-last-child和:has:

.timeline-wrapper:has(.timeline__item:nth-last-child(n + 4)) {
    --alternating: true;
}

如果符合上述條件,將采用以下CSS:

@container style(--alternating: true) {
    /* Alternating timeline styles. */
}

在這里使用樣式查詢的有用之處在于,我們可以在另一個頁面上重復(fù)使用這些樣式。它不一定非得是一個有條件的CSS。

我可能會做這樣的事情:

.timeline-wrapper--page-10 {
    --alternating: true;
}

請不要介意.timeline-wrapper--page-10,這是個故意的隨機(jī)類名。這個CSS變量可以被分配到我們想要的任何地方,而且這個CSS開箱即用。

只要寫一次,就能在很多情況下發(fā)揮作用。

logo網(wǎng)格

在CSS中,要處理的一個棘手問題是對齊多個標(biāo)識,并確保它們都看起來不錯。通過條件性CSS,我們可以檢測logo的數(shù)量,并將其尺寸縮小一些。

圖片圖片

ul:has(li:nth-last-child(n + 8)) img {
    max-width: 160px;
    height: 35px;
}

總結(jié)

這是我所做的有趣的文章之一。結(jié)合現(xiàn)代的CSS功能可以讓我們以令人興奮的新方式來構(gòu)建布局,這篇文章的例子也不例外。

根據(jù)項目的數(shù)量來改變樣式可能不是一次性的用法,它可以被提取到不同的用例中。通過使用樣式查詢,我們可以只寫一次,并在任何地方重用它們。

  • 本文譯自:https://ishadeed.com/article/conditional-css-has-nth-last-child[1]

參考資料

[1]https://ishadeed.com/article/conditional-css-has-nth-last-child:https://ishadeed.com/article/conditional-css-has-nth-last-child

責(zé)任編輯:武曉燕 來源: 前端F2E
相關(guān)推薦

2023-12-26 11:56:14

Go通道編程

2023-04-10 09:18:42

CSS前端

2022-09-07 08:58:58

Node.js框架

2018-12-05 09:00:00

RedisRedis Strea數(shù)據(jù)庫

2015-08-05 09:33:21

Javawaitnotify

2010-01-18 17:23:55

函數(shù)

2022-11-23 08:00:00

開發(fā)Regulator調(diào)試

2011-04-27 16:38:31

投影機(jī)

2019-11-14 16:23:07

MySQL索引數(shù)據(jù)庫

2010-01-18 17:23:55

函數(shù)

2010-02-03 15:40:37

Python函數(shù)

2021-03-15 12:23:24

Pythonyield代碼

2015-03-31 14:15:12

JavaJava事件通知

2010-05-18 15:58:39

MySQL觸發(fā)器

2010-02-25 10:10:29

WCF使用Header

2017-08-30 17:47:35

MySql索引

2020-08-19 08:39:05

中間件前端設(shè)計模式

2010-08-26 10:36:44

2020-12-29 05:34:48

Scrapy網(wǎng)頁源代碼

2023-10-19 08:01:04

FirstLastTake
點贊
收藏

51CTO技術(shù)棧公眾號