CSS3 的一對孿生兄弟之 background & mask

AJie發表於2019-04-05

前言

很多人在做前端開發的時候基本都用過 background 屬性,但是 mask 屬性卻很少使用,甚至有些許陌生。但是實際上 mask 與 background 一樣簡單方便,甚至在某些地方比 background 更有優勢!今天我們就來深度學習一下 background & mask!


再談盒模型

CSS3 的一對孿生兄弟之 background & mask

可能有人會問為啥這裡又提起盒模型的概念?實際上很多老師在講述盒模型的時候,重心都放在了 margin、padding 和 border 上。而我們今天再談的盒模型與這些無關。

既然叫盒模型,任何盒子都應該有一個地面和一個蓋子,就如上圖所示一樣。我們 div 中的內容放在盒子裡面,自然也就在盒子底面的上面,而這裡的底面就是我們今天要說的 background,背景。說到這裡我想大家也應該意識到,這裡的蓋子就是我們要說的 mask,遮罩。

常用的幾個基本屬性

影像是由 rgb 三個通道以及第四個通道——alpha 通道,來繪製的。

mask 的功能就是使用透明的圖片或漸變遮罩元素的背景。於是,mask 與背景 background 非常類似。這就是為什麼說 background 和 mask 是一對孿生兄弟!

值得一提:mask-mode 僅 Firefox 瀏覽器支援,Chrome 瀏覽器是基於 alpha 遮罩。遮罩元素的alpha值為0的時候會完全覆蓋下面的元素,為1的時候會完全顯示下面的內容。這裡我們以 Chrome 瀏覽器作為我們的開發環境,所以 mask 在這裡僅使用 alpha 遮罩。在這裡我也不會討論 mask-mode 屬性,如有需求請自行查閱資料!

共性

先舉個例子:

現在有結構如下:

<div class="wrapper">
  <div class="container">
    我愛你!我愛你!我愛你!我愛你!我愛你!我愛你!我愛你!我愛你!我愛你!
  </div>
</div>
複製程式碼

樣式如下:

.container {
  width: 250px;
  height: 250px;
  font-size: 2rem;
  overflow: hidden;
}
複製程式碼

CSS3 的一對孿生兄弟之 background & mask

  1. background-image & mask-image

    • none(預設值)

      啥都沒有

    • gradient

      新增漸變色!

      我們給之前的結構加個漸變背景色:

      background-image: -webkit-gradient(
        linear,
        left top,
        right bottom,
        from(rgb(255, 192, 159)),
        to(rgb(255, 238, 147))
      );
      複製程式碼

      CSS3 的一對孿生兄弟之 background & mask

      我們再加一個遮罩 maks,這裡我們用了一張 png 圖片,如下:

      CSS3 的一對孿生兄弟之 background & mask

      -webkit-mask-image: url(../images/example.png);
      複製程式碼

      CSS3 的一對孿生兄弟之 background & mask

      這裡我們不用漸變色是有原因的,因為 Chrome 瀏覽器所支援的 mask-mood 只基於 alpha 通道,所以漸變本身的顏色並不會作用於樣式上,只有 rgba 中的第四通道值是有效的。而且顯示出來的只有不同透明程度的白色樣式,具體如下:

      -webkit-mask-image: -webkit-gradient(
        linear,
        left bottom,
        right top,
        from(rgba(221, 80, 67, 1)),
        to(rgba(0, 0, 0, 0))
      );
      複製程式碼

      CSS3 的一對孿生兄弟之 background & mask

      遮罩元素的 alpha 值為 0 的時候會完全覆蓋下面的元素,為 1 的時候會完全顯示下面的內容。這也是為啥我們選擇 png 圖片的原因。

  2. background-size & mask-size

    設定背景或者遮罩圖片的大小。

    這裡我們先將背景換為一張圖片:

    CSS3 的一對孿生兄弟之 background & mask

    解析度 3937×5906

    .container {
      width: 250px;
      height: 250px;
      font-size: 2rem;
      overflow: hidden;
      background-image: url(../images/man.jpg);
    }
    複製程式碼

    這時候的樣式如下:

    CSS3 的一對孿生兄弟之 background & mask

    背景圖片之所以只顯示了左上角的一小部分是因為背景圖片的解析度太大了,而我們的盒子只是 250px×250px 的大小,預設背景圖片的左上角與盒子的左上角是一致的,所以只顯示了左上角一小部分。

    這裡我們就可以運用 background-size 屬性來進行調整了:

    background-size: length|percentage(以父元素的百分比來設定背景影像的寬度和高度)|cover|contain;
    複製程式碼

    這裡著重討論 cover|contain 這兩個值:

    屬性值 描述
    cover 把背景影像擴充套件至足夠大,以使背景影像完全覆蓋背景區域。背景影像的某些部分也許無法顯示在背景定位區域中。
    contain 把影像影像擴充套件至最大尺寸,以使其寬度和高度完全適應內容區域。

    我們這裡為了讓背景圖片完全顯示,所以旋轉 contain。

    background-size: contain;
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    我們也為 mask 新增 mask-size,這裡我們使用 cover。

    -webkit-mask-size: cover;
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    由於我們 mask 的圖片長寬比與盒子長寬比一樣,所以我們只能看到一個遮罩圖片。

  3. background-repeat & mask-repeat

    這個字面意思就是:背景圖片或者遮罩是否重複出現。

    對於這一屬性只有兩個值:repeat(重複(預設值))/no-repeat(不重複(僅顯示一次))

    這裡我們新增如下兩個屬性:

    background-repeat: no-repeat;
    -webkit-mask-repeat: no-repeat;
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    可以看到背景只顯示了一次而並未重複出現。由於我們的遮罩本身就只能看到一次,所以在這裡設定 no-repeat 並沒有什麼實際效果。

  4. background-position & mask-position

    設定背景圖片或者遮罩圖片的位置。

    描述
    x y
    x,y=top|left|right|bottom|center
    如果您僅規定了一個關鍵詞,那麼第二個值將是"center"。預設值:0% 0%。
    可以接偏移量,如:background-position: right 40px bottom 20px;
    x% y% 第一個值是水平位置,第二個值是垂直位置。左上角是 0% 0%。右下角是 100% 100%。如果您僅規定了一個值,另一個值將是 50%。
    xpos ypos 第一個值是水平位置,第二個值是垂直位置。左上角是 0 0。單位是畫素 (0px 0px) 或任何其他的 CSS 單位。如果您僅規定了一個值,另一個值將是 50%。您可以混合使用 % 和 position 值。

    這裡有一點需要注意:

    <position>值對應的容器座標位置實際上有一個公式的:

    positionX = (容器的寬度-圖片的寬度) * percentX;
    positionY = (容器的高度-圖片的高度) * percentY;
    複製程式碼

    background-position:100% 100%時候,實際定位值就是容器尺寸和圖片尺寸的差異,於是就有了右下角定位效果。

    瞭解更多CSS 值簡介理解 background 百分比定位

    這裡我們讓背景圖片居中,且改變 mask 的大小為容器寬度的一半,讓其也居中顯示。

    background-position: center;
    -webkit-mask-size: 50%;
    -webkit-mask-position: center;
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    可以看到背景和縮小後的遮罩都已經居中顯示了。

  5. background-origin & mask-origin

    規定 background-position 和 mask-position 屬性相對於什麼位置來定位。

    background-origin: padding-box(預設值)|border-box|content-box;
    -webkit-mask-origin: padding-box|border-box(預設值)|content-box|margin-box;
    複製程式碼
    描述
    padding-box 背景影像相對於內邊距框來定位。
    border-box 背景影像相對於邊框盒來定位。
    content-box 背景影像相對於內容框來定位。
    margin-box 背景影像相對於邊距框來定位。

    我們重新寫一下盒子樣式:

    .container {
      width: 250px;
      height: 250px;
      font-size: 2rem;
      overflow: hidden;
      border: 10px solid rgba(255, 0, 0, 0.5);
      background-image: url(../images/man.jpg);
      background-repeat: no-repeat;
      background-size: 100px;
    }
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    關於上述樣式就不再說明了,這時候我新增如下樣式:

    background-origin: border-box;
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    可以看到背景圖片起點由 padding-box 的左上角變為了 border-box 的左上角。

    現在加上 mask:

    -webkit-mask-image: url(../images/example.png);
    -webkit-mask-size: 50px;
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    可以看出 mask 的預設值是 border-box。

    我們將其改為 padding-box:

    -webkit-mask-origin: padding-box;
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    可以看到遮罩是由 padding-box 的左上角為原點開始平鋪的。

  6. background-clip & mask-clip

    設定元素的背景或遮罩背景的繪製區域。

    background-clip: border-box(預設值)|padding-box|content-box|text;
    -webkit-mask-clip: border-box(預設值)|padding-box|content-box|margin-box;
    複製程式碼

    同樣我們重寫一下樣式:

    .container {
      width: 250px;
      height: 250px;
      font-size: 2rem;
      overflow: hidden;
      border: 10px solid rgba(255, 0, 0, 0.3);
      background-image: url(../images/man.jpg);
      background-size: 100px;
      background-origin: border-box;
      background-position: 0 0;
    }
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    可以看到,在預設情況下,背景圖片在 border 範圍之內都進行了平鋪。

    當我們設定:

    background-clip: padding-box;
    複製程式碼

    CSS3 的一對孿生兄弟之 background & mask

    可以看到平鋪範圍被限定在了 padding 範圍之內了。

    值得一提:background-clip:text

    <div class="container">Love You!</div>
    複製程式碼
    .container {
      font-size: 5rem;
      font-weight: bolder;
      color: transparent;
      background-image: url(../images/scene.jpg);
      background-size: cover;
      background-position: center;
      -webkit-background-clip: text;
    }
    複製程式碼

    這裡用的背景:

    CSS3 的一對孿生兄弟之 background & mask
    ages/scene.jpg)

    Love You! + scene.jpg = 如下:

    CSS3 的一對孿生兄弟之 background & mask

  7. background-attachment & mask-attachment

    設定背景影像或者遮罩影像的位置是固定在 viewport 內,還是與其容器一起滾動。

    background-attachment: scroll(預設值)|fixed|local;
    mask-attachment: scroll(預設值)|fixed|local;
    複製程式碼
    描述
    scroll 相對於元素本身固定, 而不是隨著它的內容滾動。
    local 相對於元素的內容固定。如果一個元素擁有滾動機制,背景/遮罩將會隨著元素的內容滾動, 並且背景/遮罩的繪製區域和定位區域是相對於可滾動的區域而不是包含他們的邊框。
    fixed 相對於視口固定。即使一個元素擁有滾動機制,背景/遮罩也不會隨著元素的內容滾動。

    這裡我們著重介紹 background-attachment。

    background-attachment 是 CSS3 視差特效最棒的實現方法。這裡推薦一下一位作者的文章寫得非常棒!滾動視差?CSS 不在話下

    這裡我們也來實現一個炫技:

    想看成品:

    CSS3 的一對孿生兄弟之 background & mask

    <div class="wrapper">
      <div class="container">
        <div class="div text">Love You!</div>
        <div class="div"></div>
        <div class="div text">Love Me!</div>
        <div class="div"></div>
        <div class="div text">Love life!</div>
      </div>
    </div>
    複製程式碼
    ::-webkit-scrollbar {
      display: none;
    }
    .container {
      width: 30rem;
      height: 8rem;
      overflow: scroll;
      border: 1px solid red;
    }
    .container > div {
      width: 30rem;
      height: 8rem;
      background-color: #ffffff;
      font-size: 5rem;
      font-weight: bolder;
      color: transparent;
      text-align: center;
      background-size: cover;
      background-position: center;
      background-attachment: fixed;
    }
    .container :nth-child(1) {
      -webkit-background-clip: text;
      background-image: url(../images/scene-1.jpg);
    }
    .container :nth-child(2) {
      background-image: url(../images/scene-0.jpg);
    }
    .container :nth-child(3) {
      -webkit-background-clip: text;
      background-image: url(../images/scene-2.jpg);
    }
    .container :nth-child(4) {
      background-image: url(../images/scene-4.jpg);
    }
    .container :nth-child(5) {
      -webkit-background-clip: text;
      background-image: url(../images/scene-3.jpg);
    }
    複製程式碼

    這裡我們通過設定 background-attachment: fixed;讓背景圖片相對於視窗固定,而不會讓背景圖片隨內容的滾動而滾動。

特性

background

  1. background-color

    給背景設定顏色。它的層級比背景圖片還靠後,是盒模型的最底部!

    開發人員應當在給元素設定背景圖的同時給元素指定背景色,當背景圖不可用時背景色替代。

mask
  1. mask-composite(不做詳細介紹)

    表示當同時使用多個圖片進行遮罩時候的混合方式。

    這裡只簡單的介紹其中幾個值:

    描述
    source-over 遮罩累加。
    source-in 重疊的位置是遮罩,不重疊的位置表現為透明。
    source-out 重疊的位置是不遮罩,表現為透明。

筆者專門在 github 上建立了一個倉庫,用於記錄平時學習全棧開發中的技巧、難點、易錯點,歡迎大家點選下方連結瀏覽。如果覺得還不錯,就請給個小星星吧!?


2019/04/05

AJie

相關文章