你不知道的CSS(三)

Smohan發表於2017-09-18

本文首發於我的部落格

在前面兩篇文章《你不知道的CSS(一)》和《你不知道的CSS(二)》中大致介紹了一些CSS方面比較隱晦的但又很實用的技巧。相信這些技巧會為大家在專案實踐中帶來一定的幫助,本文作為《你不知道的CSS》系列的第三篇文章,將繼續在CSS技巧方面進行探討,不同於前兩篇的是,本文將著重介紹CSS中偽類和偽元素在專案中的應用場景。偽類相信大家最熟悉也是用的最多的莫過於:hover, :active, :focus之類的,因為這些在平常的專案中太常用了(然而我目前依然見過還有用js去新增.hover類來變化背景色的同學?)。而偽元素如:before, :after相信大家也用的爛熟了。 當然對於比較常見的偽類(元素)不在本文的討論範圍類,本文主要介紹一些生僻的但是又非常實用的偽類(元素)。

CSS的世界已經變天了,拋開過去,擁抱變化吧~

偽類和偽元素的區別

偽類和偽元素是一個比較容易混淆的概念,這不僅僅是從名稱上,而且在寫法上也是相似的(目前因為相容性的問題,它們的寫法是一致的)。這就更容易混淆了?。但還是希望大家在書寫的過程中養成習慣,至於相容性交給postcss等轉換工具去實現。

規範

css3 明確規定了偽類用一個冒號:來表示,而偽元素則用兩個冒號::來表示。

區別

  • 偽類更多的定義的是狀態,如:hover,或者說是一個可以使用CSS進行修飾的特定的特殊元素,如:first-child
  • 偽類使用一個冒號:
  • 常見偽類:
    • :hover
    • :active
    • :focus
    • :visited
    • :link
    • :lang
    • :first-child
    • :last-child
    • :not
  • 偽元素簡單來說就是不存在於DOM文件樹中的虛擬的元素,它們和HTML元素一樣,但是你又無法使用JavaScript去獲取,如:before
  • 偽元素使用兩個冒號::
  • 常見偽元素:
    • ::before
    • ::after
    • ::first-letter
    • ::first-line

:valid:invalid來做表單即時校驗

html5豐富了表單元素,提供了類似required,email,tel等表單元素屬性。同樣的,我們可以利用:valid:invalid來做針對html5表單屬性的校驗。

  • :required 偽類指定具有required 屬性的表單元素
  • :valid 偽類指定一個通過匹配正確的所要求的表單元素
  • :invalid 偽類指定一個不匹配指定要求的表單元素
    css實現表單校驗
    css實現表單校驗

有沒有最開始學angular的感覺?,快點直戳demo感受下吧

.valid {
  border-color: #429032;
  box-shadow: inset 5px 0 0 #429032;
}
.invalid {
  border-color: #D61D1D;
  box-shadow: inset 5px 0 0 #D61D1D;
}
.required {
  border-color: #056B9B;
  box-shadow: inset 5px 0 0 #056B9B;
}
input,
textarea {
  &:valid {
    @extend .valid;
  }
  &:invalid {
    @extend .invalid;
  } 
  &:required {
    @extend .required;
  }
}複製程式碼

:target來實現摺疊皮膚

:target是文件的內部連結,即 URL 後面跟有錨名稱 #,指向文件內某個具體的元素。

利用 :target 的特性可以實現以前只能使用JavaScript實現的顯示隱藏或者Collapse 摺疊皮膚。

.collapse {
  >.collapse-body {
    display: none;
    &:target {
      display: block;
    }
  }
}複製程式碼

target實現摺疊皮膚
target實現摺疊皮膚

預覽CSS實現Collapse摺疊皮膚demo

:not來排除其他選擇器

:not表示的是一個非/不是的概念。我在專案mo-css上用到過很多次,尤其是在表單類中,我用它來設定表單元素在readonlydisabled狀態之外的hover等狀態,以便於當元素在readonlydisabled時,元素不具有hover狀態。

@mixin buttonStyle ($border, $background, $color, $hoverBorder, $hoverBackground, $hoverColor) {
    color: $color;
    border-color: $border;
    background-color: $background;
    &:not(.readonly):not([readonly]):not(.disabled):not([disabled]) {
        &:hover,
        &:active {
            color: $hoverColor;
            border-color: $hoverBorder;
            background-color: $hoverBackground;
        }
    }
}複製程式碼

:nth-child(even/odd)來實現隔行變色

:nth-child等偽類的引數大多是一個數值或者數學表示式2n+1,而even作為引數用來表示偶數odd作為引數用來表示奇數的類似於別罵的特性往往被忽略。

ul {
  &.odd {
    >li:nth-child(odd) {
      background: red;
    }
  }
  &.even {
    >li:nth-child(even) {
      background: green;
    }
  }
}複製程式碼

odd/even在隔行變色中的應用
odd/even在隔行變色中的應用

::selection來美化選中文字

就像你用滑鼠選中這段話看到的那樣,::selection用來設定選中文字的樣式,從而改變瀏覽器一成不變的文字選中色(藍色)。

::selection{
 color: #fff;
 background-color: #6bc30d;
}複製程式碼

selection設定選中文字樣式
selection設定選中文字樣式

::placeholder來美化佔位符

::placeholder用來修飾input/textarea等表單元素placeholder屬性的樣式。

<input type="text" placeholder="我是自定義的placeholder" />複製程式碼

自定義placeholder
自定義placeholder

@mixin placeholder {
  &::-webkit-input-placeholder {
    @content
  }
  &::-moz-placeholder {
    @content
  }
  &:-ms-input-placeholder {
    @content
  }
}
input, textarea {
   @include placeholder {
      color: #f00;
   }
}
//css
input::-webkit-input-placeholder{
    color: #f00;
}
input::-moz-placeholder{
     color: #f00;
}
input:-ms-input-placeholder{
     color: #f00;
}複製程式碼

::first-letter來實現段落首字下沉

首字下沉 : 設定段落的第一行第一字字型變大,並且向下一定的距離,與後面的段落對齊,段落的其它部分保持原樣

首字下沉效果
首字下沉效果

就像圖中展示的那樣,之前實現類似效果,我們需要多加一個標籤,如:

<p>
   <b></b>
    ...
</p>複製程式碼

然而,現在只需要一個CSS偽元素就可以實現。

first-letter 偽元素用於向文字的首字母設定特殊樣式

p::first-letter{
  font-size: 6em;
  line-height: 1;
  float: left;
}複製程式碼

::first-line來特殊標記段落第一行

就如它的名字一樣,這個偽元素代表了段落的第一行,你可以使用任意樣式來控制它。

first-line標記段落第一行
first-line標記段落第一行

p::first-line{
  color: red
}複製程式碼

小結

CSS的偽類和偽元素還有很多,因為或相容性或其他原因,文章中介紹的幾種偽類/元素用的比較少,這不得不說是一種遺憾。但,為了保證專案的健康和可持續化,一定要注意偽類和偽元素的區別,儘可能的在寫偽類的時候使用一個冒號:,而在寫偽元素的時候用兩個冒號::,就像使用autoprefixer來生成瀏覽器字首一樣,將:::的轉換交給postcss等工具去做。

系列文章

本文首發於我的部落格

相關文章