半透明边框
background-clip
难题
假设我们想给一个容器设置一层白色背景和一道半透明白色边框,它的背景会从它的半透明边框透上来
1 | border:10px solid hsla(0,0%,100%,.5); |
解决方案
原因 :默认情况下,背景会延伸到边框所在的区域下层。
解决方法 :通过background-clip
属性来调整。这个属性的初始值是border-box
,更改为padding-box
1 | border: 10px solid hsla(0,0%,100%,.5); |
多重边框
box-shadow
难题
虽然网页开发者可以使用border-image
来达到多重边框的效果,但是我们通常希望在 CSS 代码层面以更灵活的方式来调整边框样式。
box-shadow方案
一个正值的扩张半径加上两个为零的偏移量以及为零的模糊值,得到的“投影”其实就像一道实线
边框
1 | background: yellowgreen; |
更重要的是,它支持逗号分隔语法,并且是层层叠加的,我们可以创建任意数量的投影
1 | background: yellowgreen; |
注意 :
- 投影的行为跟边框不完全一致,因为它不会影响布局,而且也不会受到 box-sizing 属性的影响。
- 上述方法所创建出的假“边框”出现在元素的外圈。它们并不会响应鼠标事件,可以通过加上insert来改变
outline方案
优点:灵活,可以使用虚线,可以控制于元素边缘的距离
缺点:只适用两层边框,不贴合边框圆角
灵活的背景定位
background-position,background-origin,calc()
难题
很多时候,我们想针对容器某个角对背景图片做偏移定位并留出一点的空隙,
对于具有固定尺寸的容器来说,使用 CSS 2.1 +复杂的计算可以做到这一点;
当容器元素的尺寸不固定时,这就不可能做到了。
background-position 的扩展语法方案
CSS3中,background-position
属性,它允许我们指定背景图片距离任意角的偏移量,只要我们在偏移量前面指定关键字。
1 | background: url(code-pirate.svg) |
background-origin 方案
默认情况下,background-position
是以padding box
为准的,这样边框才不会遮住背景图片。因此,top
left
默认指的是padding box
的左上角。background-origin
,可以用它来改变这种行为。
1 | padding:10px; |
calc()方案
如果我们仍然以左上角偏移的思路来考虑,其实就是希望它有一个100% - 20px 的水平偏移量,以及100% - 10px 的垂直偏移量。
1 | background:url("code-pirate.svg") no-repeat; |
边框内圆角
border-radius,outline,box-shadow
难题
用两个元素可以解决
1 | <div class="something-meaningful"><div> |
如何用一个元素解决呢?
解决方案
outline
并不会跟着元素的圆角走(因而显示出直角),但box-shadow
却是会的。因此,如果我们把这两者叠加到一起,box-shadow
会刚好填补描边和容器圆角之间的空隙。
1 | background:tan; |
条纹背景
CSS线性渐变,background-size
难题
要想在网页中实现条纹图案。通常,我们的方法是创建一个单独的位图文件,然后每次需要做些调整时,都用图像编辑器来修改它。或者使用SVG来取代位图。
解决方案
“如果多个色标具有相同的位置,它们会产生一个无限小的过渡区域,
过渡的起止色分别是第一个和最后一个指定值。从效果上看,颜色会在那
个位置突然变化,而不是一个平滑的渐变过程。 ”
1 | background:linear-gradient(#fb3 50%,#58a 50%); |
图像如下:
如果要创建超过两种颜色的条纹,也是很容易的。举例来说,下面的代
码可以生成三种颜色的水平条纹。
1 | background:linear-gradient(#fb3 33.3%,#58a 0,#58a 66.6%,yellowgren 0); //注意颜色排列和百分数 |
垂直条纹
垂直条纹的代码跟水平条纹几乎是一样的,差别主要在于:
我们需要在开头加上一个额外的参数来指定渐变的方向。
1 | background:linear-gradient(to right,#fb3 50%,#58a 0); |
斜向条纹
如果我们改变 background-size 的值和渐变的方向,是不是就可以得到斜向(比如
45°)的条纹图案呢?
不行!
原因在于我们只是把每个“贴片”(表示平铺图案中的每个基本单)内部的渐变旋转了 45°,而不是把整个重复的背景都旋转了。
正确做法是:单个贴片包含了四条条纹,而不是两条,只有这样才有可能做到无缝拼接。
1 | background:linear-gradient(45deg,#fb3 25%,#58a 0,#58a 50%,#fb3 0,#fb3 75%,#58a 0); |
更好的斜向条纹
在前面的段落中展示的方法还不够灵活,不能变换其他角度。linear-gradient()
和radial-gradient()
还各有一个循环式的加强版:repeating-linear-gradient()
和repeating-radial-gradient()
。
它们的工作方式跟前两者类似,只有一点不同:
色标是无限循环重复的,直到填满整个背景。
- 优点
- 减少了重复:我们要改动任何颜色时只需要修改两处,而不是原来的三处
- 是在渐变的色标中指定长度,而不是原来的
background-size
。 - 可以随心所欲地改变渐变的角度
倾斜角为60度的代码如下:
1 | background:repeating-linear-gradient(60deg,#fb3,#fb3 15px,#58a 0,#58a 30px); |
我们最好用前面的方法来实现水平或垂直的条纹,而用这种方法来实现斜向条纹。
注意 :需要指定高度或宽度。
灵活的同色系条纹
在大多数情况下,我们想要的条纹图案并不是由差异极大的几种颜色组成的,这些颜色往往属于同一色系,只是在明度方面有着轻微的差异。
下面是老方法,在修改时需要修改4个色标
1 | background:repeating-linear-gradient(30deg,#79b,#79b 15px,#58a 0,#58a 30px); |
下面是新方法,最深的颜色指定为背景色,同时把半透明白色的条纹叠加在背景色之上来
得到浅色条纹
1 | background:#58a; |
现在在只需要修改一个地方就可以改变所有颜色了。同时,对于那些不支持CSS 渐变的浏览器来说,这里的背景色还起到了回退的作用。
复杂的背景图案
CSS渐变,“条纹背景”
难题
除了创建各种条纹图案,有时还需要创建网格、波点、棋盘图案
网格
主要思想:多个渐变图案组合起来
我们可以把水平和垂直的条纹叠加起来,从而得到各种样式的网格。
1 | //网格条纹不固定 |
1 | //网格条纹固定 |
1 | //把两幅不同线宽、不同颜色的网格图案叠加起来 |
波点
径向渐变允许我们创建圆形、椭圆,或是它们的一部分,能够创建的最简单的图案是圆点的阵列。
1 | background:#58a; |
我们可以生成两层圆点阵列图案,并把它们的背景定位错开,这样就可以得到真正的波点图案
1 | background:#58a; |
伪随机背景
CSS渐变、条纹背景、复杂的背景图案
难题
自然界中的事物都不是以无限平铺的方式存在的。即使重复,也往往伴随着多样
性和随机性。
重现大自然的随机性是一个挑战,因为 CSS 本身没有提供任何随机功
能。
解决方案
把这组条纹从一个平面拆散为多个图层:
一种颜色作为底色,另三种颜色作为条纹,然后再让条纹以不同的间隔进行重复平铺。
1 | background:hsla(20,40%,90%); |
我们应该把平铺间距最大的贴片安排在最顶层(在我们的例子中是橙色条
纹)。
这个组合图案中第一个贴片的终点,就是各层背景图像以不同间距重复数次后再次统一对齐的
点。贴片的尺寸实际上就是所有background-size 的最小公倍数。
为了让最小公倍数最大化,这些数字最好是“相对质数”(一种关系,指相互没有公约数)。尽量选择质数,因为质数跟其他任意数字都是相对质数。
连续的图像边框
CSS 渐变,基本的 border-image,“条纹背景”,基本的 CSS 动画
难题
一个元素有一圈装饰性的边框,基本上就是一张图片被裁剪进了边框所在的方环区域。同时,我们还希望这个元素的尺寸在扩大或缩小时,这幅图片都可以自动延伸并覆盖完整的边框区域。border-image
的九宫格伸缩法不适用此难题。
最简单的办法是使用两个 HTML 元素,但不够理想。
解决方案
主要的思路就是在石雕背景图片之上,再叠加一层纯白的实色背景。为了让下层的图片背景透过边框区域显示出来,我们需要给两层背景指定不同的background-clip
值。
我们只能在多重背景的最底层设置背景色(上层覆盖下层),因此需要用一道从白色过渡到白色的 CSS 渐变来模拟出纯白实色背景的效果。
1 | padding:1em; |
边框的图片有一种怪异的拼接效果。原因是background-origin
的默认值是padding-box
,因此,图片的显示尺寸不仅取决于padding box的尺寸,而且被放置在了padding box的原点(左上角)。我们看到的实际上就是背景图片以平铺的方式蔓延到border box区域的效果。为了修正这个问题,只需把background-origin
也设置为border-box
就可以了
1 | padding:1em; |
这个技巧还可以用在渐变图案上。举个例子,下面这段代码可以生成一种老式信封样式的边框:
1 | padding:1em; |
这个技巧的另一个用武之地是生成好玩的蚂蚁行军边框!
我们将会用到“老式信封”技巧的一个变种。我们将把条纹转变为黑白两色,并把边框的宽度减少至 1px,然后再把background-size
改为某个合适的值。最后,我们把background-position
以动画的方式改变为 100%,就可以让它滚动起来了:
1 | @keyframes ants {to {background-position:100%}}; |
这个技巧不仅在实现蚂蚁行军时很有用,还可以创建出各种特殊样式的虚线框:不管是为虚
线线段指定不同的颜色,还是自定义线段的长度和间隙的长度。
当然,border-image
也有它强大的地方,尤其是在搭配渐变图案时更是威力倍增。 举个例子,假设我们需要一个顶部边框被裁切的效果,border-image
属性再加上一条由渐
变生成的垂直条纹,并把要裁切的长度在渐变中写好。边框线的粗细交给border-width
来控制。
1 | border-top:.2em solid transparent; |