[譯文] 小提示:僞元素是子元素,吧。

小提示:僞元素是子元素,吧。

請看下列代碼,一個有若干子元素的容器:javascript

<div class="container">
  <div>item</div>
  <div>item</div>
  <div>item</div>
</div>
複製代碼

若是我這樣寫:css

.container::before {
  content: "x"
}
複製代碼

實質上等效於:html

<div class="container">
  [[[ 在此插入 ::before 僞元素 ]]]
  <div>item</div>
  <div>item</div>
  <div>item</div>
</div>
複製代碼

該僞元素大致上像是一個子元素。棘手的是,除了 ::before 這個創造了該僞元素的選擇器(或者一個相似的在相同位置以一個 ::before 或者 ::after 結尾的選擇器),再無其餘選擇器可以選中它。前端

舉例來講,假設我將容器設置爲一個 2×3 的網格,並將每一個子元素都設置成藥片格子風格:java

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: 0.5rem;
}

.container > * {
  background: darkgray;
  border-radius: 4px;
  padding: 0.5rem;
}
複製代碼

不使用僞元素時,效果以下:android

六個子元素兩兩排列,造成整齊網格

若是我把上述僞元素選擇器加上,將會獲得以下效果:ios

六個子元素兩兩排列,但開頭多出了一個子元素,把總體子元素向後擠開了一格

這合情合理,但也可能會是一個坑。僞元素經常做爲裝飾元素出現(它們差很少也應該用做裝飾),所以,把它們規劃到網格佈局之中就會顯得很怪異。git

注意,選擇器 .container > * 並未選中僞元素,未能使其背景色變爲 darkgray,由於用這把槍射不中僞元素。這是僞元素的另外一個小圈套。github

在平常開發中,我發現僞元素的用途一般是經過絕對定位來實現某些裝飾效果 —— 所以,若是你寫過這樣的代碼:後端

.container::before {
  content: "";
  position: absolute;
  /* 一些裝飾效果 */
}
複製代碼

你甚至可能不會注意到你添加了一個元素。技術上來說,僞元素歸根究竟是一個子元素,因此它會盡到一個子元素應盡的義務,但參與網格佈局可不在其義務以內。並非只有 CSS 網格佈局如此。例如,你會發如今應用 Flex 佈局時,僞元素就會成爲 Flex 佈局中的子項。你也能夠對僞元素任意設置浮動,或其餘形式的佈局。

在調試工具中能夠很清楚地看到,僞元素在 DOM 中的表現恰如一個子元素:

在調試工具中選中一個 ::before 元素

還有更多的機關暗道呢!

其中之一就是 :nth-child()。你會以爲既然僞元素是實實在在的子元素,那麼它們就應該會被 :nth-child() 計算到,實際上並不是如此。也就是說像這樣的操做:

.container > :nth-child(2) {
  background: red;
}
複製代碼

將會選中同一個元素,不管是否存在僞元素 ::before。對 ::after:nth-last-child 亦是同理。這就是我在文字標題中加了「吧」的緣由。若是僞元素是貨真價實的子元素,那麼它們理應可以干預選擇器的命中。

還有一個機巧之處,在 JavaScript 中,你沒法像選中常規子元素那樣選中僞元素。document.querySelector(".container::before"); 將會返回 null。若是你想用 JavaScript 獲取到僞元素是由於想獲取其樣式,你可使用一點 CSSOM 魔法來實現:

const styles = window.getComputedStyle(
  document.querySelector('.container'),
  '::before'
);
console.log(styles.content); // "x"
console.log(styles.color); // rgb(255, 0, 0)
console.log(styles.getPropertyValue('color'); // rgb(255, 0, 0)
複製代碼

你是否中過僞元素的那些小圈套?

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索