《CSS揭秘》阅读笔记
工具函数——$$()。
作用:可以让我们更容易地获取和遍历所有匹配特定 CSS 选择符的 DOM 元素。
函数的定义如下:
function $$(selector, context) {
context = context || document;
var elements = context.querySelectorAll(selector);
return Array.prototype.slice.call(elements);
}
conic-gradient
浏览器前缀
Firefox 的 -moz-、IE 的 -ms-、Opera 的 -o- 以及 Safari 和 Chrome 的 -webkit-
一、CSS编码技巧
1、尽量减少代码重复
-
currentColor
使用后,自动获取使用当前元素文本颜色
-
inherit
继承父级元素的属性
2、合理使用简写
相较于这种写法
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: url(tr.png) top right,
url(br.png) bottom right,
url(bl.png) bottom left;
background-size: 2em 2em;
background-repeat: no-repeat;
3、应该使用预处理器吗?
预处理器缺点:
-
CSS 的文件体积和复杂度可能会失控。
-
调试难度会增加,因为你在开发工具中看到的 CSS 代码并不是你写 的源代码。不过这个问题已经大大好转了,因为已经有越来越多的 调试工具开始支持 SourceMap。SourceMap 是一种非常酷的新技术, 正是为了解决这个痛点而生的,它会告诉浏览器哪些编译生成的 CSS 代码对应哪些预处理器 CSS 代码,精确到行号。
-
预处理器在开发过程中引入了一定程度的延时。尽管它们通常很快, 但仍然需要差不多一秒钟的时间来把你的源代码编译成 CSS。
编者的建议是,为了避免可能发生的 “依赖”或“滥用”,在每个项目开始时使用纯 CSS,只有当代码开 始变得无法保持 DRY 时,才切换到预处理器的方案。
二、背景与边框
1. 半透明边框
半透明颜色
rgba() 和 hsla()。
background-clip属性
值 | 说明 |
---|---|
border-box | 默认值。背景绘制在边框方框内(剪切成边框方框)。 |
padding-box | 背景绘制在衬距方框内(剪切成衬距方框)。 |
content-box | 背景绘制在内容方框内(剪切成内容方框)。 |
默认状态下,背景会延伸到边框的区域下层
background-clip:padding-box可以修复这个问题
2. 多重边框
(1)box-shadow
相对于border,支持逗号分隔语法,可创建任意数量投影
注意事项:
- 投影的行为跟边框不完全一致,因为它不会影响布局,而且也不会受到 box-sizing 属性的影响。不过,你还是可以通过内边距或外边距(这取决于投影是内嵌和还是外扩的)来额外模拟出边框所需要占据的空间。
- 上述方法所创建出的假“边框”出现在元素的外圈。它们并不会响应鼠标事件,比如悬停或点击。如果这一点非常重要,你可以给 box-shadow 属性加上 inset 关键字,来使投影绘制在元素的内圈。请注意,此时你需要增加额外的内边距来腾出足够的空隙。
(2)outline
在某些情况下,你可能只需要两层边框,那就可以先设置一层常规边框,再加上 outline(描边)属性来产生外层的边框。
优点:
-
outline样式十分灵活,不像上面的 box-shadow 方案只能模拟实线边框 (假设我们需要产生虚线边框效果,box-shadow 就没辙了)。
-
另一个好处在于,你可以通过 outline-offset 属性来控制它跟元素边缘之间的间距,这个属性甚至可以接受负值。这对于某些效果来说非常有用。如下图。
缺点:
-
边框不会贴合 border-radius 属性产生的圆角,因此如果元素是圆角的,它的描边还是直角的。
-
它只适用于双层“边框”的场景,因为 outline 并不能接受用逗号分隔的多个值。所以当需要多层边框时,使用前一种方案。
3. 灵活的背景定位
很多时候,我们想针对容器某个角对背景图片做偏移定位,如右下角。 在 CSS 2.1 中,我们只能指定距离左上角的偏移量,或者干脆完全靠齐到其他三个角。但是,我们有时希望图片和容器的边角之间能留出一定的空隙 (类似内边距的效果),以免得到下图效果。
(1)background-position 的扩展语法
background: url(code-pirate.svg) no-repeat #58a;
background-position: right 20px bottom 10px;
兼容性问题
在不支持 background-position 扩展语法的浏览器中,背景图片会紧贴在左上角(背景图片的默认位置)。
解决方法
就是把老套的 bottom right 定位值写进 background 的简写属性中
(2)background-origin 方案
默认情况下,background-position 是以 padding box 为准的,这样边框才不会遮住背景图片。因此,top left 默认指的是 padding box 的左上角。
background-origin可改变这种行为。 在默认情况下,它的值是 padding-box。如果把它的值改成 content-box
padding: 10px;
background: url("code-pirate.svg") no-repeat #58a
bottom right; /* 或 100% 100% */
background-origin: content-box;
我们在 background-position 属性中使用的边角关键字将会以内容区的边缘作为基准
(3)calc() 方案
如果我们仍然以左上角偏移的思路来考虑,其实 就是希望它有一个 100% - 20px 的水平偏移量,以及 100% - 10px 的垂直偏移量。
background: url("code-pirate.svg") no-repeat;
background-position: calc(100% - 20px) calc(100% - 10px);
注意!请不要忘记在 calc() 函数 内部的 - 和 + 运算符的两侧各加一个空白符,否则会产生解析错误!这个规则如此怪异,是为了向前兼容:未来,在 calc() 内部可能会允许使用关键字,而这些 关键字可能会包含连字符(即减号)。
4.边框内圆角
有时我们需要一个容器,只在内侧有圆角,而边框或描边的四个角在外部仍然保持直角的形状,如图所示。
使用两个元素可轻易实现,若想用一个元素实现,则
background: tan;
border-radius: .8em;
padding: 1em;
box-shadow: 0 0 0 .6em #655;
outline: .6em solid #655;
描边并不会跟着元素的圆角走,但 box-shadow 却是会的。因此,如果我们把这两者叠加到一起,box-shadow 会刚好填补描边和容器圆角之间的空隙
指定一个等于描边宽度的扩张值在某些浏览器中可能会得到渲染异常,因此编者推荐一个稍小些的值。
5.条纹背景
linear-gradient() 函数
用于创建一个表示两种或多种颜色线性渐变的图片。
background-image: linear-gradient(direction, color-stop1, color-stop2, ...);
(1)水平条纹
background: linear-gradient(#fb3 50%, #58a 50%);
background-size: 100% 30px;
linear-gradient 默认值 to bottom,所以可省略
(2)垂直条纹
background: linear-gradient(to right, /* 或 90deg */
#fb3 50%, #58a 0);
background-size: 30px 100%;
“ 如果某个色标的位置值比整个列表中在它之前的色标的位置值都要小,则该色标的位置值会被设置为它前面所有色标位置值的最大值。”
——CSS 图像(第三版)(http://w3.org/TR/css3-images)
这意味着,如果我们把第二个色标的位置值设置为 0,那它的位置就 总是会被浏览器调整为前一个色标的位置值。
(3)斜向条纹
单个贴片包含了四条条纹,而不是两条,只有这样才有可能做到无缝拼接。
因此我们需要增加一些色标:
background: linear-gradient(45deg,
#fb3 25%, #58a 0, #58a 50%,
#fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;
但此时,条纹的宽度变细了,若需要宽度与之前一致,则需要使用勾股定理计算,则
background-size: 42.426406871px 42.426406871px
(4)更好的斜向条纹
当我们想要的不是45°,而是其他角度的条纹怎么办?
我们可以使用: linear-gradient() 和 radial-gradient()
各有一个循环式的加强版:repeating-linear-gradient() 和 repeating-radial-gradient()。
background: repeating-linear-gradient(60deg,
#fb3, #fb3 15px, #58a 0, #58a 30px);
只需修改角度,不需思考如何生成无缝贴片
(5)灵活的同色系条纹
当我们想要的条纹图案并不是由差异极大的几种颜色组成的,这些颜色往往属于同一色系,只是在明度方面有着轻微的差异时。
不再为每种条纹单独指定颜色,而是把最深的颜色指定为背景色,同时把半透明白色的条纹叠加在背景色之上来得到浅色条纹
background: #58a;
background-image: repeating-linear-gradient(30deg,
hsla(0,0%,100%,.1),
hsla(0,0%,100%,.1) 15px,
transparent 0, transparent 30px);
我们还得到了一个额外的好处,对于那些不支持 CSS 渐变的浏览器来说,这里的背景色还起到了回退的作用。
6. 复杂的背景图案
adial-gradient() 函数
用径向渐变创建 "图像"。
background-image: radial-gradient(shape size at position, start-color, ..., last-color);
值 | 描述 |
---|---|
shape | 确定圆的类型:ellipse (默认): - 指定椭圆形的径向渐变。 - circle :指定圆形的径向渐变 |
size | 定义渐变的大小,可能值: - farthest-corner (默认) : 指定径向渐变的半径长度为从圆心到离圆心最远的角 - closest-side :指定径向渐变的半径长度为从圆心到离圆心最近的边 - closest-corner : 指定径向渐变的半径长度为从圆心到离圆心最近的角 - farthest-side :指定径向渐变的半径长度为从圆心到离圆心最远的边 |
position | 定义渐变的位置。可能值: - center(默认):设置中间为径向渐变圆心的纵坐标值。 - top:设置顶部为径向渐变圆心的纵坐标值。 - bottom:设置底部为径向渐变圆心的纵坐标值。 |
start-color, ..., last-color | 用于指定渐变的起止颜色。 |
conic-gradient()函数
圆锥渐变生成图片
可用于制作金属拉丝效果、发射状光芒
SVG与CSS实现贴片的区别:
SVG实现所需代码量少
CSS 渐变能省掉 HTTP 请求,但可以将SVG文件以 data URI 的方式内嵌到样式表中, 甚至不需要用 base64 或 URLencode 来对其编码
background: #eee url('data:image/svg+xml,
<svg xmlns="http://www.w3.org/2000/svg"
width="100" height="100"
fill-opacity=".25">
<rect x="50" width="50" height="50" />
<rect y="50" width="50" height="50" />
</svg>');
background-size: 30px 30px;
7. 伪随机背景
Alex Walker 定名为“蝉原则”:通过质数来增加随机真实性
运用场景:
- 在照片图库中,为每幅图片应用细微的伪随机旋转效果时,可以使用多个 :nth-child(a) 选择符,且让 a 是质数。
- 如果要生成一个动画,而且想让它看起来不是按照明显的规律在循环时,我们可以应用多个时长为质数的动画。
伪随机的条纹图案:
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);
background-size: 41px 100%, 61px 100%, 83px 100%;
8. 连续的图像边框
想用一张图片作为边框,用border-image
padding: 1em;
border: 1em solid transparent;
background:
linear-gradient(white, white) padding-box,
url(stone-art.jpg) border-box 0 / cover;