《CSS 揭秘》读书笔记(一)

记录阅读《CSS 揭秘》一书中遇到的问题。

开始

行内元素的padding和margin:

行内元素的padding在任何方向上都是有效的,而margin只有在左右有效。
但是有一个问题就是,看起来span的高度被撑高了,但是却越界了了。设置line-height可以改变这种现象,或者直接设置displayinline-block
可以看到我在span标签的样式中定义了vertical-align:top,因为span的默认对齐方式应该是baseline,会导致父容器div不在同一水平线上。以后有时间再仔细研究吧。

背景与边框

半透明边框

正常情况下backgroundborder设置的颜色值会重叠,可以使用background-clip:padding-box来解决这个问题。


多重边框

box-shadow方案

1
2
3
4
5
6
div {
background:#55f;
box-shadow: 0 0 0 10px .#665,
0 0 0 15px deeppink,
0 2px 5px 15px rgba(0,0,0,.6);
}


需要注意的是投影不会影响布局,也不会受到box-sizing的影响。需要通过内边距或者外边距来额外模拟出边框所需要占据的空间。

outline方案
当你只需要两层边框,outline更灵活,可以产生虚线边框效果:

1
2
3
4
5
6
div {
background: darkgray;
border-radius: 5px;
outline: dashed white 1px;
outline-offset: -5px;
}


  • 只适用于双层“边框”的场景;
  • 边框不一定会贴合border-radius产生的圆角。

灵活的背景定位

难题:将背景图片定位到容器右下角
background-position

1
2
3
4
5
div {
background: url(code-pirate.svg) no-repeat bottom right #58a;
/* 针对不支持background-position浏览器的回退方案 */
background-position: right 20px bottom 10px;
}


background-origin方案
默认情况下,background-position是以padding box为准的,这样边框才不会遮住背景图片。
现在我们想让背景图片和content box对齐,只需要修改background-origincontent-box即可。

1
2
3
4
5
div {
padding: 10px;
background: url(code-pirate.svg) no-repeat bottom right #58a;
background-origin: content-box;
}

calc()方案

1
2
3
4
div {
background: url(code-pirate.svg) no-repeat;
background-position: calc(100% - 20px) calc(100% - 10px);
}

边框内圆角

1
2
3
4
5
6
7
div {
background: tan;
border-radius: .8rem;
padding: 1em;
box-shadow: 0 0 0 .4em #655;
outline: .6em solid #655;
}
I have a noce subtle inner rounding, don’t I look pretty?

有一个限制:为了让这个效果得到达成,扩张半径需要比描边的宽度值小,但它同时又要比(√2-1)r大(这里的r表示border-radius).这意味着如果描边的宽度比(√2-1)r小,那我们是不能用这个方法达到效果的。(√2-1≈0.34)。

条纹背景

利用垂直线性渐变,把两个色标拉近,颜色过渡区域就会减少,二者重合就会表现为条纹:

1
2
3
4
5
6
7
8
9
div {
background: linear-gradient(#fb3, #58a); /* 默认情况 */
}
div {
background: linear-gradient(#fb3 40%, #58a 60%); /* 拉近一些 */
}
div {
background: linear-gradient(#fb3 50%, #58a 50%); /* 重合 */
}

效果如下:

默认背景是重复平铺的:

1
2
3
4
div {
background: linear-gradient(#fb3 50%, #58a 50%);
background-size: 100% 20px;
}

捷径:

如果某个色标的位置值比整个列表中在它之前的色标的位置值都要小,则该色标的位置值会被设置为它前面所有色标位置值的最大值。

于是,可以这样:

1
2
3
4
div {
background: linear-gradient(#fb3 33.3%, #58a 0, #58a 66.6%, yellowgreen 0);
background-size: 100% 30px;
}

垂直条纹

1
2
3
4
5
div {
background: linear-gradient(to right,/*或 90deg*/
#fb3 50%, #58a 0);
background-size: 20px 100%;
}

斜向条纹

1
2
3
4
div {
background: linear-gradient( 45deg, #fb3 50%, #58a 0);
background-size: 20px 20px;
}

貌似不对劲!

1
2
3
4
5
6
7
div {
background: linear-gradient( 45deg,
#fb3 25%, #58a 0,
#58a 50%, #fb3 0,
#fb3 75%, #58a 0);
background-size: 20px 20px;
}

这下就好了!需要注意的是,条纹宽度和background-size的数学关系,条纹宽度为abackground-sizeb,则b = 2√2 * a ≈ 2.82 * a

更好的斜向条纹
我们想要改变角度了!当然有更好的方法:repeating-linear-gradient()repeating-radial-gradient()于是乎:

1
2
3
4
div {
background: repeating-linear-gradient( 60deg,
#fb3, #fb3 15px, #58a 0, #58a 30px);
}

需要注意的是,在渐变色标中指定长度,而不是background-size,这些长度是直接在渐变轴上进行度量的,直接代表了条纹自身的长度。

灵活的同色系条纹
通常我们需要这样指定条纹:

1
2
3
4
div {
background: repeating-linear-gradient( 30deg,
#79b, #79b 15px, #58a 0, #58a 30px);
}

效果如下:

还有一种更好的方法:不在为每种条纹单独指定颜色,而是把最深的颜色指定为背景色,同事把半透明白色的条纹叠加在背景色之上来得到浅色条纹:

1
2
3
4
5
6
7
div {
background: #58a;
background-image: repeating-linear-gradient( 30deg,
hsla(0, 0%, 100%, .1),
hsla(0, 0%, 100%, .1) 15px,
transparent 0, transparent 30px);
}

这样每次就只需要修改一个地方就可以了,也起到了回退作用。

0%