前言

本文是总结《CSS揭秘》书中教述的一些CSS技巧,并呈现了对应的代码和效果,和一些本人对CSS理解补充,非常感谢作者 Lea Verou 编写此书,受益匪浅,一起体会CSS的乐趣

注意

本文不考虑兼容问题,只适用于大部分浏览器和情况,如需考虑兼容,或自行找回退方案,或看《CSS揭秘》本书寻找回退方案

编码追求

  1. DRY
    1. Don`t Repeat Yourself,不应该重复你做的事情
    2. 反义即WET(Write Everything Twice)
  2. 可维护
  3. 灵活性
  4. 轻量级
  5. 尽可能符合标准

    1. CSS编码技巧

    可维护性最大的要素:尽量减少改动编辑的地方

    当某些值依赖时, 应该把它们的相互关系用代码表达出来
  • 根据字号大小改变元素其他属性大小
  • 用hsl()改变颜色 ```html

  1. [点击查看【codepen】](https://codepen.io/hegangshi/embed/KKMEVrZ)
  2. <a name="FE7Dp"></a>
  3. ## 代码易维护 vs. 代码量少
  4. 有时候, **代码易维护和代码量少不可兼得**
  5. - 为元素添加10px宽的边框, **但左侧不加边框**
  6. ```css
  7. /* no good */
  8. /* 改动边框长需要改动3处*/
  9. border-width: 10px 10px 10px 0;
  10. /* good */
  11. /* 改动1处,且可读性更高 */
  12. border-width: 10px;
  13. border-left-width: 0;

currentColor

CSS中有史以来的第一个变量,一直被解析为 color

  • 自动与文本颜色保持一致
  • currentColor 本身就是很多CSS颜色属性的初始值,比如 border-coloroutline-colortext-shadowbox-shadow

    继承 inherit

    普通元素继承父元素,伪元素继承宿主元素

  • 字体设定为与页面的其他部分相同

    1. input, select, button{ font: inherit; }
    2. a { color: inherit; }
  • 伪元素的背景色继承

    1. .inherit::before {
    2. background: inherit; /* important*/
    3. border: inherit;
    4. }

    点击查看【codepen】

    相信你的眼睛,而不是数字(对于设计而言)

  • 垂直居中,物体从几何中心点再稍微向上挪一点,才能取得理想的视觉效果

  • 圆形和矩形相比,会看起来小一点

点击查看【codepen】

关于响应式设计

请参考bootstrap的媒体查询尺寸
image.png
一些建议

  • 尽量使用百分比长度来取代固定尺寸。实在做不到,也应该尝试与视图相关单位 vw、vh、vmin、vmax
  • 需要在较大分辨率下得到固定尺寸,使用 max-width 而不是 width
  • 不要忘了为替换元素(例如 img、object、video、iframe 等)设置一个 max-width ,值为100%
  • 行列式布局时,让视口的宽度来决定列的数量。 Flexbox 加上常规的文本折行行为可以实现。
  • 使用多列文本时,指定 column-width 列宽,而不是指定 column-count 列数,在较小的屏幕上自动显示为单列布局

合理使用简写

合理使用简写是一种良好的防卫性编码方式,可以抵御未来的风险

  • 这两行CSS代码不等价 ```css background: rebeccapurple;

background-color: rebeccapurple;

  1. 前者是简写,确保得到纯色背景;但后者有可能是其他效果,因为可能会有 `background-image`
  2. 展开式写法并不会清空所有相关的其他属性,从而可能会干扰你想要达到的效果。
  3. 展开式写法是为了 **明确覆盖某个具体的展开式属性**
  4. - 展开式属性与简写属性的配合使用
  5. **如果只为某个属性提供一个值,那它就会扩散并应用到列表中的每一项**
  6. ```css
  7. /* no good */
  8. background: url("/3.png") no-repeat top right / 2em 2em,
  9. url("/23.png") no-repeat bottom right / 2em 2em,
  10. url("/23.png") no-repeat bottom right / 2em 2em;
  11. /* good */
  12. background: url("3.png") top right,
  13. url("3.png") bottom right,
  14. url("3.png") bottom right;
  15. background-size: 2em 2em;
  16. background-repeat: no-repeat;

预处理器

优点:大型项目中代码更加灵活
缺点:

  • CSS的 文件体积复杂度 可能会失控
  • 调试难度会增加
  • 打包时间增加
  • 团队的学习时间增加
  • 抽象泄露法则, 它们有它们自己的bug

颜色

hsla()

H是色度,取值在0度~360度之间,0度是红色,120度是绿色,240度是蓝色。360度也是红色。
S是饱和度,是色彩的纯度,是一个百分比的值,取值在0%~100%,0%饱和度最低,100%饱和度最高
L是亮度,也是一个百分比值,取值在0%~100%,0%最暗,100%最亮。
A是不透明度,取值在0.0~1.0,0.0完全透明,1.0完全不透明

HSL是一种圆柱坐标系,其坐标系图如下:
image.png

2. 背景与边框

多重边框

box-shadow

  • 支持逗号语法,可以创建任意数量的投影,第一个在最上层
  • 可以实现多重边框
  • 受border-radius影响
  • 和border区别,不占空间(可以用外边距或内边距(inset)来模拟),不会响应事件(可以用inset)

    1. box-shadow: 0 0 0 10px #655,
    2. 0 0 0 20px deeppink,
    3. 0 2px 5px 25px rgba(0,0,0,.6);

    点击查看【codepen】

    outline

    描边样式十分灵活

  • 可以实现虚线, box-shadow 实现边框不行

  • 可以通过 outline-offset ,控制和元素边缘之间的间距,接受负值

    1. border: 20px solid brown;
    2. outline: 2px dashed white;
    3. outline-offset: -10px;

    点击查看【codepen】
    注意:

  • 只适用于双层背景,多层背景要使用box-shadow

  • outline不一定会贴合border-radius,CSS工作组认为是一个bug,未来有可能会改

背景定位

background-clip

指定 背景 绘制区域

  • border-box (default)
  • padding-box
  • content-box

image.png
更多列子请看下面 background-origin

background-origin

指定 背景图片 绘制区域

  • border-box
  • padding-box (default)
  • content-box
    1. padding: 20px;
    2. border: 20px solid rgba(0,0,0,.2);
    3. background: yellowgreen url(https://www.baidu.com/img/flexible/logo/pc/result.png) no-repeat;
    4. background-origin: content-box;
    5. background-clip: padding-box;
    点击查看【codepen】

    background-position扩展语法

    指定 背景图片 距离任意角的偏移量 ```css background-position: right 20px bottom 10px;

/ calc()方案 / background-position: calc(100% - 20px) calc(100% - 10px);

  1. <a name="OvWJ8"></a>
  2. ## 边框内圆角
  3. box-shadow的扩展距离 = border-radius的一半
  4. ```css
  5. border-radius: .8em;
  6. padding: 1em;
  7. box-shadow: 0 0 0 .4em #655;
  8. outline: .6em solid #655;

点击查看【codepen】

线性渐变、条纹背景

  1. // 普通渐变
  2. .stripe{
  3. width: 200px;
  4. height: 200px;
  5. border: 2px dashed;
  6. background: linear-gradient(#fb3,#58a);
  7. }
  8. // 控制背景大小
  9. .stripe2{
  10. background: linear-gradient(#fb3 50%,#58a 50%);
  11. background-size: 100% 100px;
  12. }
  13. // 控制背景大小,不重复
  14. .stripe3{
  15. background: linear-gradient(#fb3 50%,#58a 50%) no-repeat;
  16. background-size: 100% 100px;
  17. }
  18. // 控制背景渐变颜色位置
  19. .stripe4{
  20. background: linear-gradient(#fb3 0, #fb3 20%, #58a 0, #58a 50%,transparent 0,transparent 100%);
  21. }
  22. // 斜向条纹 repeating-linear-gradient
  23. .sliant-stripe{
  24. background:repeating-linear-gradient(60deg,#fb3,#fb3 15px,#58a 0,#58a 30px);
  25. }
  26. // 同色系条纹
  27. .similar-stripe{
  28. background: #58a;
  29. background-image: repeating-linear-gradient(30deg,hsla(0,0%,100%,.1),hsla(0,0%,100%,.1) 10px,transparent 0,transparent 30px);
  30. }

点击查看【codepen】

  • 还可以做切角效果

    径向渐变、波点条纹、棋盘条纹

    ```css .dot{ background: tan radial-gradient(#655 30%,transparent 0); }

.dot-stripe{ background: tan; background-image: radial-gradient(#655 30%,transparent 0),radial-gradient(#655 30%,transparent 0); background-size: 33px 33px; background-position: 0 0, 15px 15px; }

.checker { 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-position: 0 0,15px 15px,15px 15px,30px 30px; background-size: 30px 30px; }

  1. [点击查看【codepen】](https://codepen.io/hegangshi/embed/vYKPbjg)
  2. - 还可以做弧形切角
  3. <a name="NADyU"></a>
  4. ## 伪随机背景条纹
  5. - 背景贴片的尺寸实际上是所有background-size的最小公倍数
  6. - 蝉原则:通过质数来增加随机真实性
  7. - background-size尽量选质数
  8. ```css
  9. .random {
  10. width: 1000px;
  11. height: 100px;
  12. background: hsla(20, 40%, 90%);
  13. background: linear-gradient(90deg,#fb3 11px,transparent 0),
  14. linear-gradient(90deg,#ab4 23px,transparent 0),
  15. linear-gradient(90deg,#fab4 41px,transparent 0);
  16. background-size: 41px 100%,61px 100%,83px 100%;
  17. }

点击查看【codepen】
蝉原则可以用于涉及有规律重复的情况:

  • 伪随机旋转效果
  • 生成随机时长的循环动画

3. 图形

border-radius

  • 可以设置8个值,前四个是水平半径,后四个是垂直半径,以 / 分开
  • 省略不写则用前面的值,垂直半径全不写则和水平半径相同 ```css // 两者等效 border-rabius: 1px / 20px 5px; border-radius: 1px 1px 1px 1px / 20px 5px 20px 5px;

// 半椭圆 border-radius: 50% / 100% 100% 0 0 border-radius: 100% 0 100% 0 / 50%;

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/2453125/1605601622027-c4782b26-d19b-4902-a43c-e9aa84027ff3.png#align=left&display=inline&height=128&margin=%5Bobject%20Object%5D&name=image.png&originHeight=276&originWidth=660&size=15081&status=done&style=none&width=307)
  2. <a name="jlKSp"></a>
  3. ## 图像边框
  4. border-image效果不够好
  5. ```css
  6. background: linear-gradient(white, white) padding-box,
  7. url(xxx.jpg) border-box
  8. 0 0 /cover;

蚂蚁行军

  1. .marching-ants{
  2. width: 100px;
  3. height: 200px;
  4. padding: 1em;
  5. border: 1px solid transparent;
  6. background: linear-gradient(white,white) padding-box,
  7. repeating-linear-gradient(-45deg,black 0,black 25%,white 0, white 50%) 0 / .6em .6em;
  8. animation: ants 12s linear infinite;
  9. }
  10. @keyframes ants{
  11. to {
  12. background-position:100%;
  13. }
  14. }

点击查看【codepen】

图形变换:平行四边形

skew()

进行倾斜变换

嵌套元素方案

  1. .button {
  2. width: 100px;
  3. height:50px;
  4. line-height: 50px;
  5. text-align: center;
  6. background: tan;
  7. transform: skewX(-45deg);
  8. }
  9. .button > div {
  10. transform: skewX(45deg);
  11. }

image.png

✨伪元素方案

  • 伪元素作为背景,进行变换
  • 适用于其他任何线性样式,而不想影响内容时

图形变换:菱形图片

clip-path

使用裁剪方式创建元素的可显示区域。区域内的部分显示,区域外的隐藏。

  1. clip-path: ploygon(50% 0,100% 50%,50% 100%,0 50%);
  • 此方法可以实现多边形裁切

    图形变换:矩形

    1. transform: scaleY(1.3) perspective(.5em) rotatex(5deg);
    2. transform-origin: bottom;

    饼状图

    animation

    ```css // 核心 animation: spin 3s linear infinite; animation: bg 6s step-end infinite;

@keyframe spin { to { transform: rotate(.5turn) } }

@keyframe bg { 50% { background: #655; } }

  1. <a name="1T3XM"></a>
  2. ### animation-delay
  3. 值可以为负,实际效果就是 **动画跳过指定时间而从中间开始播放了**
  4. <a name="oIOXb"></a>
  5. ### animation-play-state
  6. paused 暂停
  7. ```html
  8. <div class="pie" style="animation-delay:-30s">50</div>
  9. <style>
  10. .pie {
  11. float: left;
  12. position: relative;
  13. width: 100px;
  14. margin: 40px;
  15. line-height: 100px;
  16. border-radius: 50%;
  17. background: yellowgreen;
  18. background-image: linear-gradient(to right, transparent 50%, #655 0);
  19. color: transparent;
  20. text-align: center;
  21. }
  22. @keyframes spin {
  23. to {
  24. transform: rotate(0.5turn);
  25. }
  26. }
  27. @keyframes bg {
  28. 50% {
  29. background: #655;
  30. }
  31. }
  32. .pie::before {
  33. content: "";
  34. position: absolute;
  35. top: 0;
  36. left: 50%;
  37. width: 50%;
  38. height: 100%;
  39. border-radius: 0 100% 100% 0 / 50%;
  40. background-color: inherit;
  41. transform-origin: left;
  42. animation: spin 50s linear infinite, bg 100s step-end infinite;
  43. animation-play-state: paused;
  44. animation-delay: inherit;
  45. }
  46. </style>

image.png

3. 视觉效果

投影

box-shadow

支持逗号多值创造多层投影,先写的在上层

  1. // 单侧投影
  2. box-shadow: 2px 5px 4px -4px rgba(0,0,0,.5);

绘制过程:

  1. 画出一个rgba(0,0,0,.5)的矩形
  2. 把它向右移2px,向下移3px
  3. 使用高斯模糊,进行4px的模糊处理, 阴影色和纯透明色之间的颜色过渡长度近似于模糊半径的两倍 (这里是8px)
  4. 缩小投影4px,即宽度和高度各减小4px
  5. 原始元素的交集部分会被切除掉, 没有任何投影绘制在元素的下层

问题:

  1. box-shadow不能给伪元素或者透明、半透明元素加阴影,可以使用drop-shadow

filter: drop-shadow()

drop-shadow的参数基本和box-shadow差不多,但不包括扩张半径,不包括inset关键字,也不支持逗号分割的多层投影语法。

  1. // 两者等价
  2. box-shadow: 2px 2px 10px rgba(0,0,0,.5);
  3. filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));

问题:

  1. 任何非透明的部分都会被一视同仁地打上投影,包括文本

染色效果

解决图片颜色变化,需要设计出多张图片
其他方案:

  1. 透明层覆盖图片
  2. javaScript置入,利用脚本对其进行染色处理

    滤镜filter

    ✨grayscale()

    像转换为灰度图像。值定义转换的比例。值为100%则完全转为灰度图像,值为0%图像无变化

✨contrast()

调整图像的对比度。值是0%的话,图像会全黑。值是100%,图像不变。值可以超过100%,意味着会运用更低的对比

✨brightness()

控制亮度,如果值是0%,图像会全黑。值是100%,则图像无变化。值超过100%也是可以的,图像会比原来更亮

✨invert()

反转输入图像。值定义转换的比例。100%的价值是完全反转。值为0%则图像无变化

sepia()

将图像转换为深褐色,相当于褪色的效果,值为100%则完全是深褐色的,值为0%图像无变化

saturate()

转换图像饱和度,值为0%则是完全不饱和,值为100%则图像无变化。超过100%的值是允许的,则有更高的饱和度

hue-rotate()

给图像应用色相旋转,和hsla中hue一样,超过360deg的值相当于又绕一圈

具体和其他请看菜鸟联盟的filter介绍

  1. filter: sepia(1) saturate(4) hue-rotate(295deg);

image.png

混合模式

mix-blend-mode

元素的直系父元素的内容和元素的背景如何混合,为整个元素设置混合模式

  1. <div class="img">
  2. <img src="https://www.baidu.com/img/flexible/logo/pc/result.png" alt="">
  3. </div>
  4. <style>
  5. .img{
  6. display: inline-block;
  7. background: hsl(335,100%,50%);
  8. }
  9. .img > img{
  10. mix-blend-mode: luminosity;
  11. }
  12. </style>

image.png

background-blend-mode

为每层背景元素单独指定混合模式(图片与颜色)

  1. <div class="blend"></div>
  2. <style>
  3. .blend {
  4. width: 290px;
  5. display: inline-block;
  6. height: 69px;
  7. background-size: 290px 69px;
  8. background-repeat:no-repeat;
  9. background-image: linear-gradient(to right, green 0%,white 100%), url('https://www.baidu.com/img/flexible/logo/pc/result.png');
  10. background-blend-mode: color-dodge;
  11. }
  12. </style>

image.png

混合模式的动画

只有一个背景图片以及一个透明背景色,不会出现任何混合效果

  1. background-color: hsl(335, 100%, 50%);
  2. transition: .5s background-color;
  3. background-color: transparent;

具体参数详情可看这里

毛玻璃效果

  1. <div class="blur">
  2. <div class="blur-item">长夜将至,我从今开始守望,至死方休。我将不娶妻、不封地、不生子。我将不戴宝冠,不争荣宠。我将尽忠职守,生死于斯</div>
  3. </div>
  4. <style>
  5. // 使用伪元素作为背景
  6. .blur{
  7. margin: 40px;
  8. width: 300px;
  9. height: 300px;
  10. display: flex;
  11. align-items: center;
  12. justify-content: center;
  13. // 要点二:使父元素变为层叠上下文
  14. position: relative;
  15. z-index:0;
  16. &,.blur-item::before{
  17. background: url('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3774887219,31394809&fm=26&gp=0.jpg') 0 / cover fixed;
  18. }
  19. .blur-item{
  20. width: 200px;
  21. height: 200px;
  22. padding: 20px;
  23. position: relative;
  24. background: hsla(0,0%,100%,.3);
  25. overflow: hidden; // 要点二
  26. &::before{
  27. content: '';
  28. position: absolute;
  29. top: 0;
  30. left: 0;
  31. bottom: 0;
  32. right: 0;
  33. z-index:-1;
  34. filter: blur(20px);
  35. margin: -30px; // 要点一
  36. }
  37. }
  38. }
  39. </style>

image.png

  • 要点一: 模糊效果会消减消减实色像素所能覆盖的范围,消减半径正是模糊半径的长度,所以要相对于宿主元素的尺寸再向外扩大至少模糊半径,margin:-30px可以达到效果,但会有一圈模糊效果超出容器,所以加overflow: hidden;

不加margin和不加overflow效果:
image.png image.png

  • 要点二:

形成层叠上下文
CSS 总结 - 图12

4. 字体排版

连字符断行

hyphens

  • none
  • manual (defualt) 手工插入软连字符(­)
  • auto
    1. .text-justify{
    2. display: inline-block;
    3. text-align: justify;
    4. hyphens: auto;
    5. }
    image.pngimage.png

    插入换行

    伪元素换行

    1. ::after{
    2. content: '\A';
    3. white-space: pre; // 只会作用于伪元素
    4. }

文本行的斑马纹

背景颜色加斑马纹

  1. padding: .5em;
  2. line-height: 1.5;
  3. background: beige;
  4. background-size: auto 3em;
  5. background-origincontent-box;
  6. background-image: linear-grandient(rgba(0,0,0,.2) 50%,transparent 0);

调整tab宽度

  1. white-space: pre;
  2. tab-size: 2;

修改单独字符

  1. @font-face {
  2. font-family: Ampersand;
  3. src: local('xxx'),
  4. local('xxx'),
  5. local('xxx');
  6. unicode-range: U+26; // 十六进制
  7. }

自定义下划线

  1. // 通常方案
  2. text-decoration: underline; // 不够灵活
  3. border-bottom: 1px solid gray; // 文本之间空隙很大,会阻止正常文本换行
  4. box-shadow: 0 -1px gray inset; // 同上
  1. // 最佳方案
  2. background-image: linear-gradient(gray, gray) no-repeat;
  3. background-size: 100% 1px;
  4. background-position: 0 1.15em;
  5. text-shadow: .05em 0 white, -.05em 0 white; // 为了使字母降部(如p和y)下划线可以自动避让
  6. // 极为灵活,虚线下划线
  7. background-image: linear-gradient(90deg, gray 66%,transparent 0) repeat-x;
  8. background-size: .2em 2px;
  9. background-position: 0 1em;
  10. // 波浪下划线,两次径向渐变

现实的文字效果

凸版印刷效果

尤其适用 背景和文字对比度高 的场景,只要文字不是黑色并且背景纯白或纯黑就行
原理:

  • 人们习惯 光源总是悬在头顶 ,凸起物的下方会产生阴影,而凹陷的底部边缘会被打亮
  • 底部浅色投影顶部暗色投影 产生凹进平面的错觉
  • 底部暗色投影顶部的浅色投影 产生平面上凸起的错觉

浅背景+深文字, 底部加上浅色投影通常效果最佳

  1. background: hsl(210, 13%, 60%);
  2. color: hsl(210, 13%, 30%);
  3. text-shadow: 0 0.03em 0.03em hsla(0, 0%, 100%, 0.8);

image.png

空心字

  1. background: pink;
  2. color:white;
  3. text-shadow: 1px 1px black, -1px -1px black,1px -1px black, -1px 1px black;

image.png
注意: 当text-shadow宽度增加时候,效果并不好,可以用svg来实现

文字外发光

  1. background: #203;
  2. color: #ffc;
  3. text-shadow: none;
  4. transition: text-shadow 500ms linear;

image.png

文字凸起效果

  1. text-shadow: 0 1px hsl(0, 0%, 85%), 0 2px hsl(0, 0%, 85%),
  2. 0 3px hsl(0, 0%, 85%), 0 4px hsl(0, 0%, 85%), 0 5px hsl(0, 0%, 85%),
  3. 0 5px 10px black;

image.png

环形文字

用SVG实现

6. 用户体验

选用合适的鼠标光标

具体可看鼠标光标

扩大可点击区域

Fitts法则

  • 人类 移动到某个目标区域所需的最短时间 是由 目标距离目标宽度 之比所构成的对数函数

可点击区域(热区)向外扩张 往往也可以带来可用性的提升

  1. // border方案
  2. border: 10px solid transparent; // 扩张边缘
  3. box-shadow: 0 0 0 1px rgba(0,0,0,.3) inset; // 加边框
  4. background-clip: padding-box;
  5. // ✨伪元素方案
  6. xxx::before{
  7. content: '';
  8. position: absolute;
  9. top: -10px; right: -10px; bottom: -10px; left: -10px; // 比宿主元素大出10px
  10. }

自定义单/复选框

// 使用<label>元素与复选框关联之后,也可以起到触发开关的作用
<input type="checkbox" id="awesome">
<label for="awesome">Awesome!</label>


<style>
#awesome[type="checkbox"] + label::before{
  content:'\a0'; /*不换行空格*/
  display: inline-block;
  vertical-align: .2em;
  width: 0.8em;
  height: 0.8em;
  margin-right: 0.2em;
  border-radius: .2em;
  background: silver;
  text-indent: .15em;
  line-height: .4;
}

#awesome[type="checkbox"]:checked + label::before{
  content:'\2713';
  background: yellowgreen;
}
</style>

image.png

通过阴影来弱化背景

HTML方案

.overlay {
  // 遮挡元素
    position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0,0,0,.8);
}

.lightbox {
  // 突出元素
    postion: absolute;
  z-index: 1;
}

伪元素方案

// 不好控制层级
body .dimed::before{
    position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  background: rgba(0,0,0,.8);
}

box-shadow方案

// 滚动页面时,遮罩层的边缘就漏出来了,无法产生交互
box-shadow: 0 0 0 50vmax rgba(0,0,0,.8);

image.png

backdrop方案

// 浏览器对它支持有限
dialog::backdrop {
    background: rgba(0,0,0,.8);
}

通过阴影+模糊来弱化背景

filter: blur(3px) contrast(.8) brightness(.8);

滚动提示

<style>
.scroll-wrap{
  margin: 100px;
  width: 200px;
  height: 500px;
  border: 1px solid #ccc;
  overflow-y: scroll;
  padding: .3em 1em 0;

  background: linear-gradient(white 30%, transparent), radial-gradient(at top, rgba(0,0,0,.2), transparent 70%), linear-gradient(0deg,white 30%, transparent), radial-gradient(at bottom, rgba(0,0,0,.2), transparent 70%);
  background-repeat: no-repeat;
  background-size: 100% 50px,100% 15px;
  background-position: 0 0,0 0,100% 100%,100% 100%;
  background-attachment: local, scroll,local,scroll;
}
</style>

点击查看【codepen】

对比控件

resize

  • none (default)
  • horizontal
  • vertical
    overflow: hidden;
    resize: horizontal;
    
    点击查看【codepen】

    7. 结构与布局

    自适应内部元素

    fill-available、max-content、min-content、fit-content

    具体请看链接
    其中最有用的是

    min-content

    内部元素最小宽度值最大的那个元素的宽度作为最终容器的宽度。如果是图片的话最小宽度值就是图片所呈现的宽度,如果是汉字就是一个字的宽度,如果是英文就是单词的宽度。 ```html
    八百标兵奔北坡,炮兵并排北边跑

![image.png](https://cdn.nlark.com/yuque/0/2020/png/2453125/1605865055964-03d1491a-1ac3-4b0f-ab66-ecb7f07fb8a0.png#align=left&display=inline&height=126&margin=%5Bobject%20Object%5D&name=image.png&originHeight=196&originWidth=284&size=20471&status=done&style=none&width=183)
<a name="D4Pn9"></a>
## 根据兄弟元素的数量设置样式

```css
// 只有一个节点,两者相等
xxx:first-child:nth-last-child(1)
xxx:only-child

// 当列表正好包含四项时
:first-child:nth-last-child(4)

// 当列表至少包含四项时
:first-child:nth-last-child(n+4)

// 当列表最多包含四项时
:first-child:nth-last-child(-n+4)

// 当列表包含2~6项时
:first-child:nth-last-child(n+2):nth-last-child(-n+6)

//【限制范围】选择第6个到第9个,取两者的交集
:nth-child(-n+9):nth-child(n+6){}

满幅的背景,定宽的内容

// 得到450px居中内容
padding: 1em calc(50% - 450px)

image.png

垂直居中

绝对定位优化版

// no good
main{
  position: absolute;
  width: 18em;
  height: 6em;
  top: 50%;
  left: 50%;
  margin-top: -3em;
  margin-left: -9em;
}

// good
main{
    position: absolute;
  top: calc(50% - 3em);
  left: calc(50% - 9em);
}

// better
main{
    position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

视口单位

main{
    margin: 50% auto 0; // 基于父元素
     margin: 50vh auto 0; // 基于视口
  transform: translateY(-50%);
}

Flexbox方案

father{
    display: flex;
}

main{
    margin: auto; // 普通盒子中只会水平居中,flexitem会整体居中
}
main{
    display: flex;
  align-items: center;
  justify-content: center; 
}

页脚布局

body{
    display: flex;
  flex-flow: column;
  min-height: 100vh;
}

main{
    flex: 1;
}

footer{
    ...
}

8. 过渡与动画

缓动效果

cubic-bezier

定义了一个贝塞尔曲线(Cubic Bezier)。
贝塞尔曲线曲线由四个点 P0,P1,P2 和 P3 定义。P0 和 P3 是曲线的起点和终点。P0是(0,0)并且表示初始时间和初始状态,P3是(1,1)并且表示最终时间和最终状态
具体可见 菜鸟联盟介绍模拟演示

transition: .5s cubic-bezier(.25,.1,.3,.1.5); // 大于1的时候可以产生【越过】效果

逐帧动画

steps()

animation: loader 1s infinite steps(8); // 8帧动画

闪烁效果

animation-direction

  • normal (default)
  • alternate
  • reverse
  • alternate-reverse ```css @keyframes blink-smooth{ to { color: transparent } }

.heightlight{ animation: .5s blink-smooth 6 alternate; } ```

沿环形路径平移的动画

可以看这篇文章,非常有意思

2020年11月22日