此次隨筆記錄,講述在同時有邊框、背景顏色,且顏色都帶透明度時相互的影響。
問題的思考源於想要用圓角邊框和背景,制作圖片輪播的圓形按鈕。
由於按鈕需要在圖片上方顯示,所以為了減輕對圖片的遮擋,改善視覺效果,需要給邊框和背景加上透明度,於是我是這么寫的
1 li{ 2 width: 18px; 3 height: 18px; 4 margin-left: 10px; 5 display: inline-block; 6 border-radius: 50%; 7 border:2px solid; 8 border-color: rgba(0,0,0,0.5); 9 background-color: rgba(0,0,0,0.5); 10 } 11 li:first-of-type{ 12 background-color: rgba(255,255,255,0.5); 13 }
然后發現這樣不行
經前輩提醒,發現是有透明度時邊框和背景顏色會重疊顯示!仔細思考,想明白的原因。
首先要明白一個知識點,盒模型是有3D層次划分的,由上到下分別是border,content+padding,background-image,background-color,margin。為了展示清楚,借用網上的一張圖片
看到着,就能明白邊框和背景重合疊加的原因了,由於有透明度,邊框首先顯示了一遍顏色,透過它,背景顏色又顯示了一遍顏色。所以邊框顏色變深。
那怎么解決呢?由於按鈕要隨着圖片變動顏色,所以我首先想到的是方法1,但我們先來看方法2。
方法2:利用css3新屬性background-clip,此屬性規定背景的繪制區域,有取值border-box、padding-box、content-box,默認為border-box。它有什么用呢?
簡單的理解,就是哪些范圍下面能有背景,取border-box就是content+padding+border下都有,取padding-box就是border下沒有背景, content-box就只有content下有背景。
本案例中無padding,所以background-clip設置為padding-box/content-box均可。既然border下沒有背景,當然也就不會存在疊加重合了。
此處給出建議:在不使用圓角屬性,又希望邊框背景都有透明度時,background-clip屬性很好用。
但是使用圓角時,會產生一個新問題,此問題在不使用圓角屬性時不會發生,如果圓角弧度較小的話也不明顯。
1 li{ 2 width: 18px; 3 height: 18px; 4 margin-left: 10px; 5 display: inline-block; 6 border-radius: 50%; 7 border:2px solid; 8 border-color: rgba(0,0,0,0.5); 9 background-color: rgba(0,0,0,0.5); 10 background-clip: padding-box; 11 } 12 li:first-of-type{ 13 background-color: rgba(255,255,255,0.5); 14 }
為了看到更清楚,把透明度取消
眼睛不錯的應該能看出問題了,沒錯,在邊框和背景中間多了一層更淡的圓圈。如果在瀏覽器中用取色光標查看放大的情況,更清楚。
如果沒有強迫症,不對顯示效果有追求的話還好。但是我就是看着別扭。
在取色的放大圖里,看到它的像素排列,想通了原因。那就是css3圓角屬性的實現應當是通過像素點色值漸變實現的。這很像純css+div實現圓角矩形的方法,只是有色值漸變,更加圓滑。對css+div實現圓角矩形感興趣可以搜索圓角邊框實現,這里不做說明。
像素點色值變化就是形成淡顏色環的原因,由於要實現圓弧,邊框內部一部分像素點遞減顯示,這部分像素點屬於border范圍,而background-clip為padding-box使得背景顏色不在border下顯示,同時背景顏色外圍一部分像素點遞減顯示。兩部分像素點加起來就形成了一圈淡環。
由於這是像素排列的問題,所以無法解決。最后我選擇了一開始使用的方法一
方法一:
做法很簡單,為了避免邊框和背景重疊顯示,一開始把邊框顏色設置為transparent,需要轉換內部顏色時,在js里同時控制邊框和背景顏色變化
1 li{ 2 width: 18px; 3 height: 18px; 4 margin-left: 10px; 5 display: inline-block; 6 border-radius: 50%; 7 border:2px solid; 8 border-color: transparent; 9 background-color: rgba(0,0,0,0.5); 10 /*background-clip: padding-box;*/ 11 } 12 li:first-of-type{ 13 border-color: rgba(0,0,0,0.5); 14 background-color: rgba(255,255,255,0.5); 15 }
1 for (var i = 0; i < obj.length; i++) { 2 3 obj[i].style.display="none"; 4 nav[i].style.backgroundColor="rgba(0,0,0,.5)"; 5 nav[i].style.borderColor="transparent"; 6 console.log(nav[i]); 7 } 8 obj[objplay.index].style.display="block"; 9 nav[objplay.index].style.backgroundColor="rgba(255,255,255,.5)"; 10 nav[objplay.index].style.borderColor="rgba(0,0,0,.5)"; 11 //obj為包含需要輪播的圖片的元素,nav為圓點按鈕,封裝與一個對象objplay內,objplay.index為控制顯示元素的索引
現在顯示的圓圈按鈕效果就比較理想了