文章目录
- 条纹背景
- 条纹背景
- 背景知识
- 难题
- 解决方案
- 垂直条纹linear-gradient()
- 斜向条纹
- 更好的斜向条纹repeating-linear-gradient() 和 repeating-radial-gradient()
- 灵活的同色系条纹
- 总结
我以为世间最可宝贵的就是“今”,最易丧失的也是“今”。因为它最容易丧失,所以更觉得它宝贵。
CSS 线性渐变,background-size
css渐变https://www.w3.org/TR/css-images-3/#funcdef-repeating-linear-gradient
不了解css渐变的可以阅读 带你了解css渐变
不论是在网页设计中,还是在其他传统媒介中(比如杂志和墙纸等),各种尺寸、颜色、角度的条纹图案在视觉设计中无处不在。
要想在网页中实现条纹图案
,其过程还远远不够理想。通常,我们的方法是创建一个单独的位图文件,然后每次需要做些调整时,都用图像编辑器来修改它。可能有人试过用 SVG 来取代位图
,但这样还是会有一个独立的文件,而且它的语法也远远不够友好。如果可以直接在 CSS 中创建条纹图案
,那该有多棒啊!你可能会惊讶地发现,我们居然真的可以。
background: linear-gradient(#fb3, #58a);
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 30px;
border-radius: 20px;
color: rgb(15, 204, 46);
background: linear-gradient(#fb3, #58a);
}
style>
head>
<body>
<div id="app">
渐变色
div>
body>
html>
现在,让我们试着把这两个色标拉近一点(参见图 2-21):
background: linear-gradient(#fb3 20%, #58a 80%);
现在容器顶部的 20% 区域被填充为 #fb3实色 ,而底部 20% 区域被填充为 #58a实色 。真正的渐变只出现在容器 60% 的高度区域。如果我们把两个色标继续拉近(
分别改为 40% 和 60%
,参见图 2-22),
background: linear-gradient(#fb3 40%, #58a 60%);
那真正的渐变区域就变得更窄了。你是不是开始好奇,如果我们把两个色标重合在一起,
会发生什么?
background: linear-gradient(#fb3 50%, #58a 50%);
“如果多个色标具有相同的位置,它们会产生一个无限小的过渡区域,过渡的起止色分别是第一个和最后一个指定值。从效果上看,颜色会在那个位置突然变化,而不是一个平滑的渐变过程。”
——CSS 图像(第三版)(http://w3.org/TR/css3-images)
你在图 2-23 中可以看到,已经没有任何渐变效果了,只有两块实色,
各占据了background-image
一半的面积。本质上,我们已经创建了两条巨
大的水平条纹。
因为
渐变是一种由代码生成的图像
,我们能像对待其他任何背景图像那
样对待它,而且还可以通过background-size
来调整其尺寸
:
background: linear-gradient(#fb3 50%, #58a 50%);
background-size: 100% 30px;
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 30px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: linear-gradient(#fb3 50%, #58a 50%) no-repeat;
background-size: 100% 30px;
}
style>
head>
<body>
<div id="app">
渐变色
div>
body>
html>
background: linear-gradient(#fb3 50%, #58a 50%);
background-size: 100% 30px;
为了避免每次改动条纹宽度时都要修改两个数字,我们可以再次从规范 那里找到捷径。
*** “如果某个色标的位置值比整个列表中在它之前的色标的位置值都要
小,则该色标的位置值会被设置为它前面所有色标位置值的最大值。” ***
——CSS 图像(第三版)(http://w3.org/TR/css3-images)
这意味着,如果我们把第二个色标的位置值设置为 0,那它的位置就总是会被浏览器调整为前一个色标的位置值,这个结果正是我们想要的。因此,下面的代码会产生跟图 2-26 完全一样的条纹背景,但代码会更加DRY:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 30px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: linear-gradient(#fb3 30%, #58a 0);
background-size: 100% 30px;
}
style>
head>
<body>
<div id="app">
渐变色
div>
body>
html>
background: linear-gradient(#fb3 33.3%,
#58a 0, #58a 66.6%, yellowgreen 0);
background-size: 100% 45px;
等价于
background: linear-gradient(#fb3 33.3%,
#58a 33.3%, #58a 66.6%, yellowgreen 66.6%);
background-size: 100% 45px;
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 30px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: linear-gradient(#fb3 33.3%, #58a 0, #58a 66.6%, yellowgreen 0);
background-size: 100% 45px;
}
style>
head>
<body>
<div id="app">
渐变色
div>
body>
html>
水平条纹是最容易用代码写出来的,但我们在网页上看到的条纹图案并不都是水平的。有些条纹是垂直的(参见图 2-28),而且某些形态的斜条纹或许更受欢迎,或者看起来更加有趣。幸运的是,CSS 渐变同样也能帮助我们创建出这些效果,只是难度稍有不同。
垂直条纹的代码跟水平条纹几乎是一样的,差别主要在于:我们需要在开头加上一个额外的参数来指定渐变的方向
。在水平条纹的代码中,我们其实也可以加上这个参数,只不过它的默认值to bottom
本来就跟我们的意图一致,于是就省略了。最后,我们还需要把background-size
的值颠倒
一下,原因应该不用多说了吧:
background: linear-gradient(to right, /* 或 90deg */
#fb3 50%, #58a 0);
background-size: 30px 100%;
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 30px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: linear-gradient(to right, /* 或 90deg */
#fb3 50%, #58a 0);
background-size: 30px 100%;
}
style>
head>
<body>
<div id="app">
垂直纹路
div>
body>
html>
在完成了水平和垂直条纹之后,我们可能会顺着往下想:如果我们再次改变
background-size 的值
和渐变的方向
,是不是就可以得到斜向(比如45°
)的条纹图案呢?比如这样(结果如图 2-29 所示):
background: linear-gradient(45deg, #fb3 50%, #58a 0);
background-size: 30px 30px;
可以发现,这个办法行不通。原因在于我们只是把每个“贴片”1①内部的渐变旋转了 45°,而不是把整个重复的背景都旋转了
。试着回忆一下我们以前用位图来生成斜向条纹时是怎么做的吧,做法类似图 2-30。单个贴片包含了四条条纹,而不是两条,只有这样才有可能做到无缝拼接。它正是我们需要在 CSS 代码中重新实现的贴片,因此我们需要增加一些色标:
background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 30px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;
}
style>
head>
<body>
<div id="app">
斜向纹路
div>
body>
html>
background: linear-gradient(45deg,
#fb3 25%, #58a 0, #58a 50%,
#fb3 0, #fb3 75%, #58a 0);
background-size: 42.426406871px 42.426406871px;
你可以在图 2-33 中看到最终效果。但是,除非有人拿枪顶着你的脑袋威胁你必须把斜向条纹的宽度设置为完全精确的 15 像素,我会强烈推荐你把这一长串数字取整,写成 42.4px,或者甚至是 42px。(当然,在上述情形之下,你还是会被干掉。因为 2 不是整数,我们最终得到的条纹宽度永远都只能是一个近似值——尽管它已经相当精确了。)
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 30px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 42.426406871px 42.426406871px;
}
style>
head>
<body>
<div id="app">
45°斜向纹路
div>
body>
html>
在前面的段落中展示的方法还不够灵活。假设我们想让条纹不是
45°
而是60°
怎么办?或者是 30°?又或者是 3.141 592 653 5°?如果我们只是把渐变的角度改一下,那么结果看起来会相当糟糕。(比如在图 2-34 中,我们尝试实现 60°条纹,但以失败告终。)
background: linear-gradient(60deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 42.426406871px 42.426406871px;
幸运的是,我们还有更好的方法来创建
斜向条纹
。一个鲜为人知的真相是linear-gradient() 和 radial-gradient()
还各有一个循环式的加强版:repeating-linear-gradient() 和 repeating-radial-gradient()。
它们的工作方式跟前两者类似,只有一点不同:色标是无限循环重复的,直到填满整个背景。下面是一个重复渐变的例子(效果参见图 2-35):
它相当于下面这个简单的线性渐变:
background: linear-gradient(45deg,
#fb3, #58a 30px,
#fb3 30px, #58a 60px,
#fb3 60px, #58a 90px,
#fb3 90px, #58a 120px,
#fb3 120px, #58a 150px, ...);
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 24px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: repeating-linear-gradient(45deg, #fb3, #58a 30px);
}
style>
head>
<body>
<div id="app">
45°斜向纹路
div>
body>
html>
重复线性渐变完美适用于——你已经猜到了吧——条纹效果!这得益于
它们可以无限循环的天赋,一个渐变图案就可自动重复并铺满整个背景。因 此,我们再也不需要去操心如何创建出可以无缝拼接的贴片了。
作个对比,我们在图 2-33 中创建的效果也可以由这个重复渐变来生成
background: repeating-linear-gradient(45deg,
#fb3, #fb3 15px, #58a 0, #58a 30px);
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 24px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: repeating-linear-gradient(45deg, #fb3, #fb3 15px, #58a 0, #58a 30px);
}
style>
head>
<body>
<div id="app">
45°斜向纹路
div>
body>
html>
第一个明显的好处就是减少了重复:
我们要改动任何颜色时只需要修改两处,而不是原来的三处。另外一点也很重要,我们现在是在渐变的色标中指定长度,而不是原来的 background-size
。这里的background-size
是初始值,对渐变来说就是以整个元素的范围进行填充。这意味着代码中的长度值更加直观,因为这些长度是直接在渐变轴上进行度量的,直接代表了条纹自身的宽度
。我们再也不需要计算什么 根号 2 了!
不过这还不是最大的好处。最大的好处在于,现在我们可以
随心所欲地改变渐变的角度
了,指哪儿打哪儿,再也不需要苦苦思索如何生成一个无缝贴片。举例来说,我们苦苦追寻的 60°条纹只需这样写即可(参见图
2-36):
background: repeating-linear-gradient(60deg,
#fb3, #fb3 15px, #58a 0, #58a 30px);
这简单到只需要改改角度就可以了!请注意,在这个方法中,不论条纹的角度如何,我们在创建双色条纹时都需要用到四个色标。这意味着,我们最好用前面的方法来实现水平或垂直的条纹,而用这种方法来实现斜向条纹。另外,
在处理 45°条纹时,我们甚至可以把这两种方法结合起来,本质上是通过重复线性渐变来简化贴片的代码
:
background: repeating-linear-gradient(45deg,
#fb3 0, #fb3 25%, #58a 0, #58a 50%);
background-size: 42.426406871px 42.426406871px;
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 24px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: repeating-linear-gradient(45deg, #fb3 0, #fb3 25%, #58a 0, #58a 50%);
background-size: 42.426406871px 42.426406871px;
}
style>
head>
<body>
<div id="app">
45°斜向纹路
div>
body>
html>
在大多数情况下,我们想要的条纹图案
并不是由差异极大的几种颜色组成的
,这些颜色往往属于同一色系,只是在明度方面有着轻微的差异。举个例子,我们来看看这个条纹图案:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 24px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: repeating-linear-gradient(45deg, #79b, #79b 15px, #58a 0, #58a 30px);
}
style>
head>
<body>
<div id="app">
45°斜向纹路
div>
body>
html>
在图 2-37 中可以看到,条纹是由一个主色调( #58a)和它的浅色
变体所组成的。但是,这两种颜色之间的关系在代码中并没有体现出来。此 外,如果我们想要改变这个条纹的主色调,甚至需要修改四处!
幸运的是,还有一种更好的方法:
不再为每种条纹单独指定颜色,而是 把最深的颜色指定为背景色,同时把半透明白色的条纹叠加在背景色之上来 得到浅色条纹:
background: #58a;
background-image: repeating-linear-gradient(30deg, hsla(0, 0%, 100%, .1), hsla(0, 0%, 100%, .1) 15px, transparent 0, transparent 30px);
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body,
html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
#app {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 24px;
border-radius: 20px;
border: red solid 1px;
color: rgb(15, 204, 46);
background: #58a;
background-image: repeating-linear-gradient(30deg, hsla(0, 0%, 100%, .1), hsla(0, 0%, 100%, .1) 15px, transparent 0, transparent 30px);
}
style>
head>
<body>
<div id="app">
45°斜向纹路
div>
body>
html>
结果看起来跟图 2-37 是一模一样的,
但我们现在只需要修改一个地方就可以改变所有颜色了。我们还得到了一个额外的好处,对于那些不支持CSS 渐变的浏览器来说,这里的背景色还起到了回退的作用。不仅如此,在下一篇攻略中我们还将看到,通过叠加的手法,具有透明区域的多个渐变图案可以构造出非常复杂的图案。
相关规范
- CSS 图像
http://w3.org/TR/css-images- CSS 背景与边框
http://w3.org/TR/css-backgrounds- CSS 图像(第四版)
http://w3.org/TR/css4-images