前言
CSS是一门简单的语言,但是在如今CSS3的出现以及普及,似乎更多人开始觉得吃力,于是很多人都不愿意学习新的语法,但其实这些新的特性的出现都是有原因,其目的只会是解放生产力,让我们更加轻松解决某一类问题,在这里只做记录,记录一些实用的技巧,暂不讨论其背后的原理。
1.半透明边框
在浏览器早期的时候,如果我们要使用透明效果,可能需要加载shim脚本,甚至在IE中需要用到滤镜效果,如果要实现背景透明,可能我们会准备一张单像素的半透明图片,利用xy轴重复达到透明效果,但是到了2009年之后,我们就可以使用透明颜色了,比如常见rgba()
和hsla()
,前一个可能大家都知道,毕竟经常在用,第二个我在这里暂时解释一下吧:
H:Hue(色调)。0(或360)表示红色,120表示绿色,240表示蓝色,取值为:0 - 360
S:Saturation(饱和度)。取值为:0.0% - 100.0%
L:Lightness(亮度)。取值为:0.0% - 100.0%
A:Alpha透明度。取值0~1之间。
有了以上的知识之后,现在有一个需求,我们现在需要对某一个段文字设置一层淡红色背景和一道半透明红色边框,效果图类似于下面这种:
于是我们理所当然写出下面的这种代码:
div{
border: 10px solid hsla(0,0%,100%,.5);
background: white;
}
但是效果却是这样:
原因很简单,背景颜色和边框颜色重叠了,导致尽管边框颜色是透明色,但是背景色却不是,那怎么解决,只需要改变默认背景颜色作用的区域就好。
div{
border: 10px solid hsla(0,0%,100%,.5);
background: white;
background-clip: padding-box;
}
这里提醒一点,默认background-clip
的值是border-box
,只要修改就好,还没理解请私戳这个demo。
2.多重边框
想一想,如果我们想实现一个类似于以下的多重边框效果:
可能你会使用多个div模拟这种行为,但这种是不友好的,我们这里可以使用box-shadow
方案,可能许多人都用过,这不就是投影吗,但是我们换一种想法,如果我们设置xy轴偏移为0,模糊值设置为0,那就可以模拟边框效果,当然这不是重点,重点是它支持多个值的设置,下面我们看一下我们的具体实现:
div {
box-shadow: 0 0 0 10px #655,
0 0 0 15px deeppink,
0 2px 5px 15px rgba(0,0,0,.6);
}
这样我们就完美解决多边框的问题,但是有一个问题,投影的边框不会影响布局,并且也不会响应鼠标悬停或点击的事件,当然这个可以通过第六个参数指定inser
关键字解决,如果没理解可私戳这个demo
在某些时候,我们可能只需要两层边框,不需要这么多,那么我们可以使用outline
属性解决这个问题,这个的好处是可以产生虚线边框的效果,box-shadow
则只能产生实线边框,并且你可以通过outline-offset
指定描边的偏移值。
3.灵活的背景定位
如果我们想要实现背景图片右下角偏移,并且留下一点空隙,在CSS2.1中是很难实现的,可能我们会设置某个百分比值近似的达到想要的效果,下图为我们想要实线的效果:
但是CSS3中我们便可以更加精确控制背景图片偏移量了,比如:
div {
background: url(1.svg) o-repeat #58a;
background-position: right 20px bottom 10px;
}
当然我们还要设置一个回退方案,在不支持这样写法的浏览器中,图片默认位置则是左上角,所以我们还要在background
设置右下角定位。
div {
background: url(1.svg) o-repeat bottom right #58a;
background-position: right 20px bottom 10px;
}
除了这种解决方案,我们还可以使用background-origin
方案
有一种需求可能我们会遇到,就是偏移量和容器的内边距一致,如果采用以上的做法,我们的代码可能是这样的:
padding: 10px;
background: url(1.svg) o-repeat bottom right #58a;
background-position: right 10px bottom 10px;
但是这样的代码不够DRY,也就是当你修改padding
的值之后你还得修改background-position
的值,当然你可以通过CSS预处理器解决,但是我们可以使用一种更加合理简单的方法解决,我们都知道,background-position:top left
的top left
值默认是以CSS盒子模型中的padding-box
为基准,原因也很简单,如果以border-box
为准,那么边框将会遮住背景图片,所以我们就能想到background-origin
的默认值肯定是padding-box
,如果我们将这个值修改为content-box
,那就可以完美保持偏移量和容器的内边距一致了,具体代码为:
padding: 10px;
background: url(1.svg) o-repeat bottom right #58a;
background-origin: content-box;
这样就可以直接设置内边距而不用管背景定位的偏移值了。
另一种思路
我们可以使用较前沿的calc()
属性,我们的最终目的不过是希望在右下角希望有一个偏移值,所以我们可以这么设置,具体看代码:
background: url(1.svg) o-repeat bottom right #58a;
background-position: calc(100% - 20px ) calc(100% - 10px);
4.边框内圆角
想在我们想要实现这样一个效果:
可能我们首先想到就是一个父div
设置背景颜色,子div
设置圆角效果,这个解决方案没什么问题,但是需要两个div
元素,我们能不能用一个div
元素解决呢?
我们先看一下实现代码:
div {
border-radius: .8em;
box-shadow: 0 0 0 .4em #655;
outline: .6em solid #655;
}
我们来解读这一段代码,首先我们设置圆角属性,所以整个元素都有了圆角效果,紧接着我们设置了投影,这里投影会跟着圆角走,效果如下:
最后我们设置描边,而我们的描边是不会跟着圆角走的,所以它的四个角都是直角,所以就实现了我们想要的效果。
若还没理解,可以自己动手实现一遍。
5.条纹背景
在CSS2.1中我们想要实现渐变功能或者条纹功能,通常都是使用几像素的背景图片repeat-x
轴实现,又或许使用svg来实现,但总是不够方便,总是需要做很多无谓的工作量,那么在CSS3中我们就可以通过CSS来精准控制,这不得不说是一大好事,举一个例子:
background: linear-gradient(#fb3 #58a)
效果图:
颜色后面可以跟数值,比如:
background:linear-gradient(#fb3 20%,#58a 80%);
这里的意思是:
在容器的顶部20%的区域被填充为#fb3实色
在容器的底部20%的区域被填充为#58a实色
在容器20%~80%的区域将会从#fb3渐变为#58a实色
可能有点拗口,但是只要自己亲手动手试试,就能理解。
下面我们制作一个等宽的条纹背景,代码如下:
background:linear-gradient(red 50%,blue 50%);
这段代码可以解释为在顶部50%的区域渲染为红色,在底部50%的区域渲染为绿色,因此可以产生等宽条纹。
但是这里不够DRY,因为我们每次修改都要修改其中的两个数字,有没有什么简便的方法,在规范中有提到一段话:
如果每个色标的位置值比整个列表中在它之前的色标值都要小,则该色标值为它前面所有色标值的最大的哪一个。
举个例子:
background:linear-gradient(red 50%,blue 0);
在这段代码中,第二个色标值为0,也就是小于前面的色标值,那么解析的时候就会去前面的最大的那个,也就是50%这个数值,至于原由,很简单,这里就不在解释了。
linear-gradient
第一个还支持传入一个方向,使我们可以控制渐变的方向,比如,渲染一个垂直条纹:
background:linear-gradient(to right, red 50%,blue 0);
如果设置一个角度,能否得到一个斜向条纹:
background:linear-gradient(45deg, red 50%,blue 0);
background-size: 10% 30px;
似乎不可以,原由很简单,因为我们只是把单个贴片给旋转了,单个贴片类似下图:
而实际上斜向的单个贴片应该是这样的:
所以我们改写代码如下:
background:linear-gradient(45deg,red 25%,blue 0,blue 50%,red 0,red 75%,blue 0);
background-size: 30px 30px;
效果图:
当然,这里有一个问题,如果我们不是倾斜45度,而是60度,那么当我们设置的时候,会发现一团糟糕,但我们有一个更好的方法解决这个问题,一个鲜为人知的真相是linear-gradient()
和 radial-gradient
还各有一个循环式的增强版本:repeating-linear-gradient()
和 repeating-radial-gradient
,举个例子:
background: repeating-linear-gradient(45deg, red ,red 15px,blue 0, blue 30px)
背景图案我们经常都是使用颜色差不多的色调形成间隔条纹,那有没有简单一点的方法,这里我们可以把背景色设置为主色调,同时将半透明白色背景色应用在背景色之上,我们就可以得到一个相似的背景条纹:
background: #58a;
background-image: repeating-linear-gradient(30deg,
hsla(0,0%,100%,.1), hsla(0,0%,100%,.1) 15px,
transparent 0, transparent 30px);
height: 100vh;