CSS實現鏤空遮罩

前一陣子面試被問題到這個問題,忽然懵逼了,腦子一片空白,之前知道這種效果,好比什麼值得買的改版引導頁面:面試

當時再緊張也應該打出一種實現方法,就是什麼值得買這種使用圖片實現canvas

它首先加了一個半透明的黑色蒙層(background-color: rgba(0,0,0,.8))而後添加提早製做好的圖片做爲子元素,而後經過決定定位,讓圖片與被遮蓋的部分的定位相同,製造出一種假的鏤空的效果瀏覽器

雖然這種方式處理定位有一些麻煩,而且不適合頁面有滾動的狀況,滾動的時候可能出現錯位。svg

可是當時怎麼也應該答出這種方式,可是確實一面試就緊張,腦子不轉了,就想着添加一個僞元素,可是不知道怎麼穿透。佈局

回來查了一些資料,找到了幾種實現的方法post

首先準備好要被遮罩的DOM結構:ui

<div class="outer">
  <div class="content">
    <p>這是要露出來的字</p>
    <p>這是要露出來的字</p>
    <p>這是要露出來的字</p>
  </div>
  <div class="inner"></div>
</div>
複製代碼

以及樣式:url

.outer {
  position: relative;
  margin: 20px 0;
  height: 500px;
  background: darksalmon;
  overflow: hidden;
}

.content {
  width: 200px;
  height: 80px;
  color: #FFF;
  line-height: 1.5;
  background: #5b8b7b;
  margin: 100px 0 0 100px;
}
複製代碼

此時的效果:spa

要實現的效果:.net

透明邊框

中間的鏤空部分爲實際的widthheight,爲徹底透明的背景,而四周半透明的遮罩使用rgbaborder來實現

.inner {
  position: absolute;
  left: 0;
  top: 0;
  box-sizing: content-box;
  width: 200px;
  height: 80px;
  border-color: rgba(0, 0, 0, 0.5);
  border-style: solid;
  border-width: 100px 1500px 1500px 100px;
  background: transparent;
}
複製代碼

透明輪廓

使用邊框的地方,大多數時候均可以使用輪廓outline來替代,實際上沒有什麼不一樣,只是要注意,outline是不佔據文檔流空間的,因此定位方式與使用border時不一樣

.inner2 {
  position: absolute;
  left: 100px;
  top: 100px;
  box-sizing: content-box;
  width: 200px;
  height: 80px;
  outline: rgba(0, 0, 0, 0.5) 1500px solid;
  background: transparent;
}
複製代碼

透明陰影

還能夠使用透明陰影實現,主要利用了陰影的第四個擴展半徑這個參數

.inner3 {
  position: absolute;
  left: 100px;
  top: 100px;
  box-sizing: content-box;
  width: 200px;
  height: 80px;
  box-shadow: rgba(0, 0, 0, 0.5) 0 0 0 1500px;
  background: transparent;
}
複製代碼

使用Canvas實現

能夠使用強大的Canvas實現,固然使用Cavnas就須要使用腳原本編寫了,雖然有些複雜,可是使用靈活,可以適應各類不一樣的要求,好比同時鏤空多個等等。

使用Canvas也有兩種方式來實現,第一種方式是使用clearRect方法,比較簡單:

const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';

ctx.fillRect(0, 0, 1500, 1500);
ctx.clearRect(100, 100, 200, 80);
複製代碼

另外一種方式是本身經過path直接畫出這樣的一個形狀,這裏就須要介紹一下非零環繞規則

因此在畫外圍的半透明矩形時順時針,那麼裏面鏤空的矩形就須要逆時針:

const canvas = document.querySelector('#canvas2');
const ctx = canvas.getContext('2d');

// 外圍
ctx.moveTo(0, 0);
ctx.lineTo(1500, 0);
ctx.lineTo(1500, 1500);
ctx.lineTo(0, 1500);
ctx.closePath();

// 內層
ctx.moveTo(300, 100);
ctx.lineTo(100, 100);
ctx.lineTo(100, 180);
ctx.lineTo(300, 180);
ctx.closePath();

ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
ctx.fill();
複製代碼

使用SVG實現

我對SVG基本上是不瞭解的,直接複製修改了一段代碼

<svg class="svg" width="1500" height="500">
  <defs>
    <mask id="myMask">
      <rect x="0" y="0" width="100%" height="100%" style="stroke:none; fill: #ccc"></rect>
      <rect width="200" height="80" x="100" y="100" style="fill: #000"></rect>
    </mask>
  </defs>
  <rect x="0" y="0" width="100%" height="100%" style="stroke: none; fill: rgba(0, 0, 0, 0.6); mask: url(#myMask)"></rect>
</svg>
複製代碼

也不是很複雜。

總結

  • 若是頁面佈局尺寸都是固定的,能夠使用CSS的三種方法實現
  • 若是實現效果比較複雜,能夠使用Canvas或者SVG實現
  • 若是要偷懶,可讓UI出一張圖片實現

參考

相關文章
相關標籤/搜索