很多時候稍途,我們需要通過一層半透明的遮罩層來把后面的一切整體調(diào)暗轩性,以便凸顯某個特定的UI元素赏廓,引導(dǎo)用戶關(guān)注巴刻,比如彈出層或者交互指南愚铡。
這個效果的傳統(tǒng)方法就是增加一個額外的HTML元素用于遮擋背景添加如下樣式:
.overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,.8);
}
.lightbox { /*需要引起用戶注意的元素*/
position: absolute;
z-index: 1;
}
.overlay 遮罩層負責(zé)把這個元素背后所有的東西調(diào)暗。.lightbox
需要指定一個更高的z-index
胡陪,一邊繪制在遮罩層的上層沥寥。這個方法的優(yōu)點:穩(wěn)定可靠,缺點:需要增加額外的HTML柠座。那怎么由CSS單獨實現(xiàn)呢邑雅?
box-shadow方案
我們可以用偽元素消除額外的HTML元素,比如:
body.dimmed::before {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
background: rgba(0,0,0,.8);
}
缺點: 移植性不好妈经, <body>
元素上可能有其他需求已經(jīng)占用了 ::before
元素淮野,而且使用這個效果需要JS 給<body>添加dimmed
這個類,如果把遮罩層交給元素自己的::bofore
偽元素來實現(xiàn)吹泡,就可以彌補不足骤星。給偽元素設(shè)置z-index:-1;
就可以讓它出現(xiàn)在元素的背后。盡管這解決了可移植的問題爆哑,但無法對遮罩層Z軸層次進行細粒度的控制洞难,它可能出現(xiàn)在這個元素之后(期望的),但也可能出現(xiàn)在這個元素的父元素活著祖先元素之后泪漂。這個方法還有一個問題廊营,偽元素?zé)o法綁定獨立的JS事件處理函數(shù)歪泳。
box-shadow方案
具體做法就是生成一個巨大的投影,不偏移不模糊露筒,簡單拙劣的模擬遮罩層效果:
box-shadow: 0 0 0 999px rgba(0,0,0,.8);
為了確保遮罩層總是可以覆蓋視口呐伞,我們換用視口單位來解決它。因為我們無法分開制定的水平和垂直方向的直徑慎式,所以這里最合適的視口單位為vmax
伶氢。1vmax
相當(dāng)于1vw
和1vh
兩者中較大值,因此滿足我們需求的最小值就是50vmax瘪吏。由于投影是同時向四個方向擴展的癣防,這個遮罩層的最終尺寸將是100vmax加上元素本身的尺寸。
position: fixed;
top: 50%; left: 50%;
margin: -200px;
box-shadow: 0 0 0 50vmax rgba(0,0,0,.8);
缺點: 如果頁面很長而為此擴大投影的擴張半徑就不太明智掌眠。
優(yōu)點:可以有限度的使用該技巧蕾盯,比如配合固定定位來使用,或者當(dāng)頁面沒有滾動條時再用蓝丙。
backdrop 方案
如果你想引導(dǎo)用戶關(guān)住的元素就是一個模擬的<dialog>
元素级遭,(<dialog>
元素可以由它的showModal()
方法顯示出來),那么根據(jù)瀏覽器的默認樣式渺尘,它會自帶一個遮罩層挫鸽。借助::backdrop
偽元素,這個原生的遮罩層可以設(shè)置樣式的鸥跟,比如可以把它變的更暗一些:
<button onclick="document.querySelector('#modal').showModal()">Click me</button>
<dialog id="modal">O HAI!
<button onclick="this.parentNode.close()">Close</button>
</dialog>
dialog::backdrop { background: rgba(0,0,0,.8)}
缺點:瀏覽器對其支持比較有限丢郊,再次使用之前,確認一下兼容性的問題医咨。
優(yōu)點:盡管瀏覽器還不支持枫匾,對話框沒有遮罩層也不會導(dǎo)致任何功能的缺失,因為它只是用戶體驗的增強手段而已拟淮。