CSS编码技巧
尽量减少代码重复
多种尺寸的按钮
使用em、rem作为边距的单位,可以让按钮尺寸随着于字号进行缩放,只需要改变字号,就可以创造出等比例放大和缩小的按钮
html
css
button {
padding: 0.3em 0.8em;
border: 1px solid #446d88;
background: #58a linear-gradient(#77a0bb, #58a);
border-radius: 0.2em;
box-shadow: 0 0.05em 0.25em gray;
color: white;
text-shadow: 0 -0.05em 0.05em #335166;
font-size: 125%;
line-height: 1.5;
}
button.big {
font-size: 150%;
}
- padding使用em、rem作为单位,em参考自身或者父元素的font-size,rem参考html的font-size
- font-size 使用%、em、rem等单位
- line-height:1.5 设置行高时字号的1.5倍
多种颜色按钮
button {
padding: 0.3em 0.8em;
border: 1px solid rgba(0, 0, 0, 0.1);
background: #58a linear-gradient(hsla(0, 0%, 100%, 0.2), transparent);
border-radius: 0.2em;
box-shadow: 0 0.05em 0.25em rgba(0, 0, 0, 0.5);
color: white;
text-shadow: 0 -0.05em 0.05em rgba(0, 0, 0, 0.5);
font-size: 125%;
line-height: 1.5;
}
button.cancel {
background-color: #c00;
}
button.ok {
background-color: #6b0;
}
- background: #58a linear-gradient(hsla(0, 0%, 100%, 0.2), transparent) 是 background-color 和 background-image 的简写,两者位置可任意对换
- 只要把半透明的黑色或白色(background-image)叠加在主色调(background-color)上,即可产生主色调的亮色和暗色变体
代码易维护vs代码量少
- 有时两者不可兼得
下面的代码片断,我们要为一个元素添加10px宽的边框,但左侧不加边框。
之前代码
.box {
border-width: 10px 10px 10px 0;
}
这样似乎很简洁了,但如果以后要改变边框的宽度,可能需要同时改三个地方
更改之后
.box {
/* 修改宽度只需该这一处即可 */
border-width: 10px;
border-left-width: 0;
}
currentColor
currentColor 是一个特殊的颜色关键字,它没有绑定到固定的颜色值,而是从文本获取颜色
html
This is header 1
This is some text
css
hr {
color: #0984e3;
height: 0.5em;
background: currentColor;
}
- currentColor 是很多CSS颜色属性的初始值,比如 border-color 和 outline-color,以及 text-shadow 和 box-shadow 的颜色值,等等。
继承
- inherit 可以用在任何CSS属性中,而且它总是绑定到父元素的计算值(对伪元素来说,则会取生成该伪元素的宿主元素)
举例来说,要把表单元素的字体设定为与页面的其他部分相同,你并不需要重复指定字体属性,只需利用 inherit 的特性即可:
html
表单
css
input,
select,
button {
font: inherit;
}
类似,把超链接的颜色设定为与页面中其他文本相同,还是要用 inherit
a {
color: inherit;
}
inherti 对于背景色同样非常有用,例如在创建提示框的时候,你可能希望它的小箭头能够自动继承背景和边框的样式
html
这是一段提示文字
css
.callout {
line-height: 1.5;
width: 200px;
background: #74b9ff;
position: relative;
border: 3px solid #fdcb6e;
}
.callout::before {
content: "";
position: absolute;
top: -0.4em;
left: 1em;
padding: 0.35em;
/* 边框和背景颜色继承至父类 */
background: inherit;
border: inherit;
border-right: 0;
border-bottom: 0;
transform: rotate(45deg);
z-index: -1;
}
视觉的偏差
人的眼睛并不是一台完美的输入设备。有时候精准的尺度看起来并不精准,而我们的设计需要顺应这种偏差。
- 几何上完美居中物体在视觉上不居中,我们应该把这个物体从几何学的中心点再稍微向上挪一点,才能取得理想的视觉效果。
- 在给文本容器设置内边距,如果我们希望四边的内边距看起来是基本一致的,就需要减少顶部和底部的内边距。
响应式网页设计
媒体查询是实现响应式布局重要工具,媒体查询的断点不应该由具体的设备来决定,而应该根据设计自身来决定。
- 使用百分比长度来取代固定长度。如果实在做不到这一点,也应该尝试使用与视口相关的单位(vw、vh、vmin 和 vmax),它们的值解析为视口宽度或高度的百分比。
- 当你需要在较大分辨率下得到固定宽度时,使用 max-width 而不是 width,因为它可以适应较小的分辨率,而无需使用媒体查询。
- 不要忘记为替换元素(比如 img、object、video、iframe 等)设置一个 max-width,值为 100%。
- 假如背景图片需要完整地铺满一个容器,不管容器的尺寸如何变化, background-size: cover 这个属性都可以做到。但是,我们也要时刻牢记——带宽并不是无限的,因此在移动网页中通过 CSS 把一张大图缩小显示往往是不太明智的。
- 当图片(或其他元素)以行列式进行布局时,让视口的宽度来决定列的数量。弹性盒布局(flex-wrap: wrap;)或者 display: inline-block 加上常规的文本折行行为,都可以实现这一点。
- 在使用多列文本时,指定column-width(列宽)而不是指定 column-count(列数),这样它就可以在较小的屏幕上自动显示为单列布局。
html
当我年轻的时候,我梦想改变这个世界;当我成熟以后,我发现我不能够改变这个世界,我将目光缩短了些,决定只改变我的国家;当我进入暮年以后,我发现我不能够改变我们的国家,我的最后愿望仅仅是改变一下我的家庭,但是,这也不可能。当我现在躺在床上,行将就木时,我突然意识到:如果一开始我仅仅去改变我自己,然后,我可能改变我的家庭;在家人的帮助和鼓励下,我可能为国家做一些事情;然后,谁知道呢?我甚至可能改变这个世界。
css
.newspaper {
column-width: 100px;
-moz-column-width: 100px; /* Firefox */
-webkit-column-width: 100px; /* Safari and Chrome */
}
合理使用简写
- 展开式写法并不会帮助你清空所有相关的其他属性。如下面的例子,背景图覆盖背景颜色。如果将
background-color
改为background
,背景图的设置就被清空了
.container > div {
height: 200px;
width: 200px;
background-image: url("http://img0.imgtn.bdimg.com/it/u=1940080850,543989800&fm=26&gp=0.jpg");
background-size: 100px;
background-repeat: repeat-y;
background-color: #6c5ce7;
}
- 如果只为某个属性提供一个值,那它就会扩散并应用到列表中的每一项。
改进前代码
div {
background: url(tr.png) no-repeat top right / 2em 2em,
url(br.png) no-repeat bottom right / 2em 2em,
url(bl.png) no-repeat bottom left / 2em 2em;
}
background-size 和 background-repeat 的值被重复了三遍, 尽管每层背景的这两个值确实是相同的。
改进后代码
div {
background: url(tr.png) top right, url(br.png) bottom right,
url(bl.png) bottom left;
background-size: 2em 2em;
background-repeat: no-repeat;
}
现在,我们只需要在一处修改,就可以改变所有的 background-size 和 background-repeat 了。
怪异的简写
- background 简写属性中指定 background-size 时,需要同时提供一个 background-position 值,而且还要使用一个斜杠(/)作为分隔(必须position在前,size在后)。这是为了消除歧义,因为假如只有
50% 50%
,解析器便分不清是 background-size 还是 background-position - 简写属性通常可以任意顺序,注意上面的特例
预处理器
像Stylus、Sass、Less等CSS预处理器,如果使用得当,它们在大型项目中可以让代码更加灵活,但是它有以下缺点
- CSS 的文件体积和复杂度可能会失控。
- 调试难度会增加(SourceMap可以解决这个问题,它会告诉浏览器哪些编译生成的 CSS 代码对应哪些预处理器 CSS 代码,精确到行号)
- 预处理器在开发过程中引入了一定程度的延时。
- 学习成本
- 抽象泄漏法则
原生CSS中的特性
- CSS 自定义属性暨层叠式变量 http://w3.org/TR/css-variables-1
- calc 函数
- CSS 颜色,引入的 color() 函数会提供颜色运算方法 http://dev.w3.org/csswg/css-color
- 嵌套(草案)
这些原生特性通常比预处理器提供的版本要强大得多,因为它们是动态的,可以看下面例子
ul {
--accent-color: purple;
}
ol {
--accent-color: rebeccapurple;
}
li {
background: var(--accent-color);
}
在有序列表中,列表项的背景色将是 rebeccapurple;但在无序列表中,列表项的背景色将是 purple。这在预处理器中实现起来比较复杂。总之,但问题庞大到只有预处理器才能解决时,才使用预处理器,否则使用原生CSS。
背景与边框
半透明边框
- 默认情况下,背景颜色会延伸到边框下方。就像下面例子一样
css
.box {
width: 200px;
height: 200px;
border: 10px solid hsla(0, 0%, 100%, 0.5);
background: #74b9ff;
}
- background-clip
css
.box {
width: 200px;
height: 200px;
border: 10px solid hsla(0, 0%, 100%, 0.5);
background: #74b9ff;
background-clip: padding-box;
}
background-clip 属性的初始值是 border-box,意味着背景会被元素的 border box(边框的外沿框)裁切掉。如果不希望背景侵入边框所在的范围,将其设为 padding-box,这样浏览器就会用内边距的外沿来把背景裁切掉。
多重边框
border属性不支持设置多重边框,可以使用box-shadow实现类似效果
box-shadow 方案
- box-shadow 有第四个参数,称为
扩展半径
,通过指定正值或负值,可以让投影面积加大或者减小
.box {
width: 200px;
height: 200px;
background: yellowgreen;
box-shadow: 0 0 0 10px #655;
}
- box-shadow 支持逗号分隔语法,可以创建任意数量的投影。需要注意的是 box-shadow 是层层叠加的,第一层投影位于最顶层,依次类推,因此需要有规律的增加扩展半径
.box {
width: 200px;
height: 200px;
background: yellowgreen;
box-shadow: 0 0 0 10px #655, 0 0 0 15px deeppink;
}
- 可以在这些特殊
边框
加常规投影
.box {
width: 200px;
height: 200px;
background: yellowgreen;
box-shadow: 0 0 0 10px #655, 0 0 0 15px deeppink,
0 2px 5px 15px rgba(0, 0, 0, 0.6);
}
投影和边框区别
投影不会影响布局,而且也不会受到 box-sizing 属性的影响,可以通过增加内边距或外边距(这取决于投影是内嵌和还是外扩的)来模拟投影所占空间
上述方法所创建出的“边框”出现在元素的外圈。它们并不会响应鼠标事件,比如悬停或点击。如果这一点非常重要,你可以给 box-shadow属性加上inset关键字,来使投影绘制在元素的内圈。请注意,此时你需要增加额外的内边距来腾出足够的空隙,否则内容可能被阴影遮挡住。
.box {
width: 200px;
height: 200px;
/* 留足阴影的空间 */
padding: 15px;
background: yellowgreen;
box-shadow: 0 0 0 10px #655 inset;
}
outline 方案
- 和border配合只能实现两层边框
- outline-offset 属性来控制描边跟元素边缘之间的间距,这个属性甚至可以接受负值,实现类似裁缝线效果
.box {
width: 200px;
height: 200px;
background: #655;
outline: 1px dashed white;
outline-offset: -10px;
}
- 描边不一定会贴合 border-radius 属性产生的圆角
.box {
width: 200px;
height: 200px;
background: yellowgreen;
border: 10px solid #655;
outline: 5px solid deeppink;
border-radius: 1rem;
}
背景定位
设置背景图片距离任意角有一定偏移。
和背景颜色不同,背景图片不会默认跑到边框下方。
background-position 的扩展语法方案
默认情况下,background-position 是以 padding box 为准的,下面讲的background-origin
可以改变这一行为
.box {
background: url(http://csssecrets.io/images/code-pirate.svg) no-repeat #58a;
background-position: right 20px bottom 10px;
/* Styling */
max-width: 10em;
min-height: 5em;
padding: 10px;
color: white;
/* 100%/1 是 font-size 和 line-height 的简写 */
font: 100%/1 sans-serif;
}
回退方案(兼容不支持的浏览器)
.box {
background: url(http://csssecrets.io/images/code-pirate.svg) no-repeat bottom
right #58a;
background-position: right 20px bottom 10px;
/* Styling */
max-width: 10em;
min-height: 5em;
padding: 10px;
color: white;
/* 100%/1 是 font-size 和 line-height 的简写 */
font: 100%/1 sans-serif;
}
回退方案是在加上不带偏移的 background-position
background-origin 方案
在给背景图片设置距离某个角的偏移量时,有一种情况极其常见:偏移量与容器的内边距一致。如果继续用上面的方案,一旦更改了padding,background-position 也要进行修改。background-origin: content-box; 可以让 background-position 相对于内容偏移
.box {
background: url(http://csssecrets.io/images/code-pirate.svg) no-repeat bottom
right #58a; /* 或 100% 100% */
/* 将background-position 更改为相对于content-box */
background-origin: content-box;
/* Styling */
max-width: 10em;
min-height: 5em;
padding: 10px;
color: white;
/* 100%/1 是 font-size 和 line-height 的简写 */
font: 100%/1 sans-serif;
}
在必要时可以把这两种技巧组合起来!如果你想让偏移量与内边距稍稍有些不同(比如稍微收敛或超出),那么可以在使用 background-origin: content-box 的同时,再通过 background-position 的扩展语法来设置这些额外的偏移量。
calc() 方案
把背景图片定位到距离底边 10px 且距离右边 20px 的位置,也可以通过calc来实现
.box {
background: url(http://csssecrets.io/images/code-pirate.svg) no-repeat #58a;
background-position: calc(100% - 20px) calc(100% - 10px);
/* Styling */
max-width: 10em;
min-height: 5em;
padding: 10px;
color: white;
/* 100%/1 是 font-size 和 line-height 的简写 */
font: 100%/1 sans-serif;
}
注意:background-position 中的100% 100%指的是元素的padding-box 边缘
边框内圆角
有时我们需要一个容器,只在内侧有圆角,而边框或描边的四个角在外部仍然保持直角的形状。
使用两个div
html
I have a nice subtle inner rounding, don't I look pretty?
css
.something-meaningful {
background: #655;
padding: 0.8em;
}
.something-meaningful > div {
background: tan;
border-radius: 0.8em;
padding: 1em;
}
使用box-shadow + outline
html
I have a nice subtle inner rounding, don't I look pretty?
css
.container > div {
background: tan;
border-radius: 0.8em;
padding: 1em;
box-shadow: 0 0 0 0.4em #655;
outline: 0.6em solid #655;
}
- 这个方法有些hack的味道,因为它利用了描边不会跟着圆角走,而阴影会
- box-shadow 属性指定的扩张值大小实际和border-radius有关,如下图所示
- 为了避免计算,取 border-radius 的一半即可
条纹背景
水平条纹
色标
的概念
渐变中可以指定位置做色标标明特别的颜色。第一个颜色默认位置是0,最后一个默认位置是100%。第一个色标位置到第二个色标位置之间颜色进行渐变,依次类推。笔者发现,如果第一个颜色不是从0开始,比如是
linear-gradient(#fb3 20%, #58a 50%)
,那么从实现效果来看,它等同于linear-gradient(#fb3 0%, #fb3 20%, #58a 50%)
,缺少位置为100%的色块可以做类似推断。
渐变角度
以物体几何中心为原点,顺时针方向计算,正上方为0deg。换句话说,0deg 将创建一个从下到上的渐变(箭头指向),90deg 将创建一个从左到右的渐变,180deg从上往下渐变(默认值)
简单例子
html
linear-gradient
css
.multicolor-linear {
padding: 0.5rem 0.8em;
background: linear-gradient(#fb3 20%, #58a 80%);
}
省略了方位名词后,渐变是从上往下开始的。在中间20%-80%的区域是渐变区域,如果将其缩小,变成下面这样
.multicolor-linear {
padding: 0.5rem 0.8em;
background: linear-gradient(#fb3 50%, #58a 50%);
}
当两个色标
重合在一起时候,渐变区域就变得无限小,最终看上去就是两个条纹
背景大小
因为渐变是一种由代码生成的图像,我们能像对待其他任何背景图像那样对待它,而且还可以通过 background-size 来调整其尺寸
.multicolor-linear {
height: 90px;
width: 150px;
background: linear-gradient(#fb3 50%, #58a 50%);
background-size: 100% 30px;
}
不等宽的条纹
.multicolor-linear {
height: 90px;
width: 150px;
background: linear-gradient(#fb3 30%, #58a 30%);
background-size: 100% 30px;
}
关于色标位置的trick
如果某个色标的位置值比整个列表中在它之前的色标的位置值都要小,则该色标的位置值会被设置为它前面所有色标位置值的最大值
利用上面这个trick,可以写出下面代码
.multicolor-linear {
height: 90px;
width: 150px;
background: linear-gradient(#fb3 33.3%, #58a 0, #58a 66.6%, yellowgreen 0);
background-size: 100% 45px;
}
#58a 0
等价于#58a 33.3%
,yellowgreen 0
等价于ellowgreen 66.6%
垂直条纹
垂直条纹和水平条纹原理类似,不过需要更改渐变方向和背景位置
.multicolor-linear {
height: 90px;
width: 150px;
background: linear-gradient(
to right,
#fb3 33.3%,
#58a 0,
#58a 66.6%,
yellowgreen 0
);
background-size: 50px 100%;
}
斜向条纹
如果使用和上面类似的方法实现斜向条纹,代码可能像下面这样
.multicolor-linear {
height: 90px;
width: 150px;
background: linear-gradient(
45deg,
#fb3 25%,
#58a 0,
#58a 50%,
#fb3 0,
#fb3 75%,
#58a 0
);
background-size: 42.426406871px 42.426406871px;
}
上面的不论从可读性还是易用性都不是很好,特别是backgroud-size的计算
更好的斜向条纹
linear-gradient() 和 radial-gradient() 各有一个循环式的加强 版:repeating-linear-gradient() 和 repeating-radial-gradient()。它们的工作方式跟前两者类似,只有一点不同:色标是无限循环重复的,直到填满整个背景。下面是一个重复渐变的例子
.multicolor-linear {
height: 90px;
width: 150px;
background: repeating-linear-gradient(
45deg,
#fb3,
#fb3 15px,
#58a 0,
#58a 30px
);
}
区别
- repeating-linear-gradient在渐变的色标中指定长度,而linear-gradient在background-size中指定
- repeating-linear-gradient 的长度是直接在渐变轴上进行度量的,更加直观
- repeating-linear-gradient 可以任意调整角度
- 在创建双色条纹时都需要用到四个色标(不可省略初始和结束)
同色系条纹
在大多数情况下,我们想要的条纹图案并不是由差异极大的几种颜色组 成的,这些颜色往往属于同一色系,只是在明度方面有着轻微的差异。举个例子,我们来看看这个条纹图案:
.multicolor-linear {
height: 90px;
width: 150px;
background: repeating-linear-gradient(
30deg,
#79b,
#79b 15px,
#58a 0,
#58a 30px
);
}
它使用用两个相同色系的条纹组成,如果要修改主色调,甚至需要修改四处,还有一种更好的方法:不再为每种条纹单独指定颜色,而是把最深的颜色指定为背景色,同时把半透明白色的条纹叠加在背景色之上来得到浅色条纹:
.multicolor-linear {
height: 90px;
width: 150px;
background: #58a;
background-image: repeating-linear-gradient(
30deg,
hsla(0, 0%, 100%, 0.1),
hsla(0, 0%, 100%, 0.1) 15px,
transparent 0,
transparent 30px
);
}
复杂的背景图案
网格
水平和垂直的条纹叠加起来,从而得到各种样式的网格
.multicolor-linear {
height: 90px;
width: 150px;
background: white;
background-image: linear-gradient(
90deg,
rgba(200, 0, 0, 0.5) 50%,
transparent 0
),
linear-gradient(rgba(200, 0, 0, 0.5) 50%, transparent 0);
background-size: 30px 30px;
}
另一种写法
.multicolor-linear {
height: 90px;
width: 150px;
background-image: repeating-linear-gradient(
90deg,
rgba(200, 0, 0, 0.5),
rgba(200, 0, 0, 0.5) 15px,
transparent 0,
transparent 30px
),
repeating-linear-gradient(
rgba(200, 0, 0, 0.5),
rgba(200, 0, 0, 0.5) 15px,
transparent 0,
transparent 30px
);
}
网格线
背景色 + 水平、垂直线
.multicolor-linear {
height: 90px;
width: 150px;
background: #58a;
background-image: linear-gradient(white 1px, transparent 0),
linear-gradient(90deg, white 1px, transparent 0);
background-size: 30px 30px;
}
另一个网格例子
.multicolor-linear {
height: 150px;
width: 150px;
background: #58a;
background-image: linear-gradient(hsla(0, 0%, 100%, 0.3) 1px, transparent 0),
linear-gradient(90deg, hsla(0, 0%, 100%, 0.3) 1px, transparent 0),
linear-gradient(white 2px, transparent 0),
linear-gradient(90deg, white 2px, transparent 0);
background-size: 15px 15px, 15px 15px, 75px 75px, 75px 75px;
}
波点
径向渐变允许我们创建圆形、椭圆,或是它们的一部分。
圆点阵列
.box {
height: 150px;
width: 150px;
background: #655;
background-image: radial-gradient(tan 30%, transparent 0);
background-size: 30px 30px;
}
波点图
.box {
height: 150px;
width: 150px;
background: #655;
background-image: radial-gradient(tan 30%, transparent 0),
radial-gradient(tan 30%, transparent 0);
background-size: 30px 30px;
background-position: 0 0, 15px 15px;
}
为了提高代码复用性,可以用sass来写
@mixin polka($size, $dot, $base, $accent) {
background: $base;
background-image: radial-gradient($accent $dot, transparent 0),
radial-gradient($accent $dot, transparent 0);
background-size: $size $size;
background-position: 0 0, $size/2 $size/2;
}
调用方法
@include polka(30px, 30%, #655, tan);
棋盘
构造棋盘图案本质上是用两个三角形来拼合出我们想要的方块。
div {
height: 150px;
width: 150px;
background: #eee;
background-image: linear-gradient(45deg, #bbb 25%, transparent 0),
linear-gradient(45deg, transparent 75%, #bbb 0);
background-size: 30px 30px;
}
上面代码使用了两层渐变,各自构成一个三角形图案,但这样的效果不是我们想要的。我们只需要把第二层渐变在水平和垂直方向均移动贴片长度的一半,就可以把它们拼合成一个完整的方块:
div {
height: 150px;
width: 150px;
background: #eee;
background-image: linear-gradient(45deg, #bbb 25%, transparent 0),
linear-gradient(45deg, transparent 75%, #999 0);
background-size: 30px 30px;
/* 要调整背景的位置,使用 background-position */
/* 多个位置用逗号隔开 */
background-position: 0 0, 15px 15px;
}
靠下位置的虚线标志的是第二个渐变层平移后的位置
以上只得到棋盘的一半,完整棋盘还需要将现有的棋盘复制一份
div {
height: 150px;
width: 150px;
background: #eee;
background-image: linear-gradient(45deg, #bbb 25%, transparent 0),
linear-gradient(45deg, transparent 75%, #bbb 0),
linear-gradient(45deg, #bbb 25%, transparent 0),
linear-gradient(45deg, transparent 75%, #bbb 0);
background-size: 30px 30px;
background-position: 0 0, 15px 15px, 15px 15px, 30px 30px;
}
上面的代码还可以优化,比如将四层渐变合并为两层渐变(每层渐变绘制两个三角),使用半透明渐变色,可以实现棋盘颜色随着主色调变化
div {
height: 150px;
width: 150px;
background: #3498db;
background-image: linear-gradient(
45deg,
rgba(0, 0, 0, 0.25) 25%,
transparent 0,
transparent 75%,
rgba(0, 0, 0, 0.25) 0
),
linear-gradient(
45deg,
rgba(0, 0, 0, 0.25) 25%,
transparent 0,
transparent 75%,
rgba(0, 0, 0, 0.25) 0
);
background-size: 30px 30px;
background-position: 0 0, 15px 15px;
}
scss的写法
@mixin checkerboard($size, $base, $accent: rgba(0, 0, 0, 0.25)) {
background: $base;
background-image: linear-gradient(
45deg,
$accent 25%,
transparent 0,
transparent 75%,
$accent 0
),
linear-gradient(
45deg,
$accent 25%,
transparent 0,
transparent 75%,
$accent 0
);
background-position: 0 0, $size $size;
background-size: 2 * $size 2 * $size;
}
/* 调用时是这样的...... */
@include checkerboard(15px, #58a, tan);
使用svg的棋盘
div {
height: 150px;
width: 150px;
background: #eee
url('data:image/svg+xml,');
background-size: 30px 30px;
}
饼图
绘制饼图使用到了conic-gradient
,下面是它和radial-gradient
的对比图
div {
height: 150px;
width: 150px;
background: conic-gradient(red 36deg, orange 36deg 170deg, yellow 170deg);
border-radius: 50%;
}
其他用法参考https://developer.mozilla.org/en-US/docs/Web/CSS/conic-gradient
伪随机背景
CSS本身没有提供随机功能,伪随机背景是将背景大小设置成质数,来构造重复规律不明显的背景图案
div {
height: 150px;
background: hsl(20, 40%, 90%);
background-image: linear-gradient(90deg, #fb3 11px, transparent 0),
linear-gradient(90deg, #ab4 23px, transparent 0),
linear-gradient(90deg, #655 41px, transparent 0);
/* 背景大小设置成质数 每隔 41*61*83 才会出现重复 */
background-size: 41px 100%, 61px 100%, 83px 100%;
}
一些使用质数
的例子
- 在照片图库中,为每幅图片应用伪随机旋转效果时,可以使用多个 :nth-child(a) 选择符,且让 a 是质数。
- �如果要生成一个动画,而且想让它看起来不是按照明显的规律在循环时,我们可以应用多个时长为质数的动画。[例子](play. csssecrets.io/cicanimation)
连续的图像边框
实现边框是一个图案的效果,最先想到的是用两个div标签
html
I have a nice border
css
.something-meaningful {
background: url("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2841247860,2911841437&fm=26&gp=0.jpg");
background-size: cover;
padding: 1em;
}
.something-meaningful > div {
background: white;
padding: 1em;
}
[图片上传失败...(image-658045-1594393251551)]
实现上面的效果至少需要两个元素,那么,只用一个元素能否实现相同效果呢?
怪异的现象
现在来考虑只用一个元素的情况
html
css
.something-meaningful {
padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white),
url("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2841247860,2911841437&fm=26&gp=0.jpg");
background-size: cover;
background-clip: padding-box, border-box;
}
如果同时设置背景图(url)和渐变背景(*-gradient),必须设置
background-clip
背景图片(background-image)先设置的离用户近(在层叠上下文中越靠前)
background-clip
设置background-image
的裁剪方式,默认情况下为border-box
,更改为padding-box
后,背景被裁剪到内边距框。但图片平铺的起点是padding-box的左上角,所以会出现上面怪异
结果background-origin
设置background-position
的相对位置,默认情况下background-position
的起点是padding-box
的左上角,可以通过设置background-origin:border-box
将background-position
的起点设置为border-box
的左上角。
.something-meaningful {
padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white),
url("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2841247860,2911841437&fm=26&gp=0.jpg");
background-size: cover;
background-clip: padding-box, border-box;
/* 更改 background-position 的相对位置 */
background-origin: border-box;
}
简写方式
.something-meaningful {
padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white) padding-box,
url("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2841247860,2911841437&fm=26&gp=0.jpg")
border-box 0 0 / cover;
}
0 0 / cover
的含义是
- background-position:0 0; 默认是center center
- backrgound-size:cover
信封图案
.something-meaningful {
padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white) padding-box,
repeating-linear-gradient(
-45deg,
red 0,
red 12.5%,
transparent 0,
transparent 25%,
#58a 0,
#58a 37.5%,
transparent 0,
transparent 50%
)
0 / 5em 5em;
}
注意:上面使用了双色标
border-image
实现上面的信封效果也可以是用border-image
来实现
.something-meaningful {
padding: 1em;
border: 16px solid transparent;
border-image: 16
repeating-linear-gradient(
-45deg,
red 0,
red 1em,
transparent 0,
transparent 2em,
#58a 0,
#58a 3em,
transparent 0,
transparent 4em
);
}
border-image 有以下参数
border-image-source 图片位置(url、linear-gradient)
border-image-slice 图片边界向内偏移
border-image-width 图片边界宽度(单位px,不能用em)
border-image-outset 指定在边框外绘制(outset)
border-image-repeat 图像是否重复 (重复repeat、拉伸stretch、铺满round)
蚂蚁行军效果
.marching-ants {
padding: 1em;
border: 1px solid transparent;
background: linear-gradient(white, white) padding-box,
repeating-linear-gradient(-45deg, black 0, black 25%, white 0, white 50%) 0 /
0.6em 0.6em;
animation: ants 12s linear infinite;
}
脚注
div {
height: 150px;
width: 150px;
border-top: 0.2em solid transparent;
border-image: 100% 0 0 linear-gradient(90deg, currentColor 4em, transparent 0);
padding-top: 1em;
}
上面代码含义是
border-image-source: linear-gradient(90deg, currentcolor 4em, transparent 0px);
border-image-slice: 100% 0 0;
border-image-width: 1;
border-image-outset: 0;
border-image-repeat: stretch;