此次随笔记录,讲述在同时有边框、背景颜色,且颜色都带透明度时相互的影响。
问题的思考源于想要用圆角边框和背景,制作图片轮播的圆形按钮。
由于按钮需要在图片上方显示,所以为了减轻对图片的遮挡,改善视觉效果,需要给边框和背景加上透明度,于是我是这么写的
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为控制显示元素的索引
现在显示的圆圈按钮效果就比较理想了