CSS权威指南学习笔记6

2020-06-16

过渡

CSS过渡能控制一段时间内属性的值如何在视觉上变成另外一个值。

过渡的动画效果是无侵入的,这意味着就算浏览器不支持过渡,也会完成属性的变化,只不过变化是瞬间完成的。

过渡在用户交互上作用很大,动态内容是非常容易惹人注意的,可以让用户注意到某个重点。使用过渡也能制造出平滑的动画,用户都喜欢看动画。

一般和伪类搭配实现触发动画,例如:hover。也可以使用js直接替换属性,同样可以触发。如该例子就展示了两种触发过渡的方法:codepen

定义过渡

定义过渡的属性有:

  • transition-property
    • 指定有那些属性展现过渡效果。接收一个属性列表,也可以设置为all,表示响应所有属性变化。
  • transition-duration
    • 指定过渡动画时长。接收一个时间单位。
  • transition-timing-function
    • 定义中间值计算方法,或陈时序函数,例如最简单的就是线性计算(linear)。当前该属性还是实验功能,需要加浏览器前缀,建议少用。
  • transition-delay
    • 定义过渡延迟。接收一个时间单位。

以及四个属性的简写属性transition

/* property name | duration | timing function | delay */
transition: margin-right 4s ease-in-out 1s;

过渡支持的属性

判断属性是否支持过渡动画的关键是确定其取值是否能内插(interpolation)。这就意味着值必须是有中间点,可以量化的。所以display:blockdisplay:inline这种显然不能内插的属性是不能过渡的。而数值的属性基本上都是可以过渡的。

动画

前一章介绍了过渡这种简单的创建动画方式。更加强大的创建动画的方式是使用CSS动画。

关键帧

使用CSS动画需要定义关键帧。使用@keyframes块定义可复用的CSS关键帧动画,如:

@keyframes color-pop{
    0% { /* 动画开始 */
        color: black;
    }
    33% { /* 动画进行1/3 */
        color: gray;
    }
    100% { /* 动画结束 */
        color: white;
    }
}

关键帧并没有指定动画的持续时间。除了使用百分比表示动画进行过程,也可以使用from和to。from表示0%,to表示100%。关键帧内需要定义属性的变化。

通过JavaScript控制动画关键帧

值得一提的是,有一个实验中API(WD)可以通过JavaScript控制动画关键帧,在CSSRule接口上实现:MDN文档。我也想象不出来使用可编程关键帧可以做出怎样的效果,不过肯定是能够功能更加多。

把动画应用到元素上

控制动画如何应用到元素的属性有:

  • 使用animation-name可以将动画应用到元素上。
  • 使用animation-duration可以定义关键帧在元素上循环一次所用的时间长度。默认0。
  • 使用animation-iteration-count可以声明动画的迭代次数。默认1次。可以设置为infinite
  • 使用animation-direction可以定义动画播放方向(正向、反向、迭代)。默认正向,即从0%播放到100%。
  • 使用animation-delay可以定义动画延迟。默认0.
  • 使用animation-timing-function可以定义动画时序函数。默认ease
  • 使用animation-play-state可以定义动画播放还是暂停。默认running。比较适合用在伪类上,或者用js控制。
  • 使用animation-fill-mode可以设置CSS动画在结束后元素是否保留动画计算出的最后一帧的属性。

使用这些属性的例子:

div{
    animation-name: color-pop;
    animation-duration: 2s;
    animation-iteration-count: 5;
    animation-direction: reverse
}

通过JavaScript监控动画

与动画相关的事件有三个:animationstartanimationiterationanimationend,代表动画的开始、迭代、结束。可以查看我写的这个codepen例子。

关于GPU性能

大多数浏览器在绘制透明度(opacity)和变形(transform)动画有GPU加速,而不在GPU管理的UI线程中播放,动画性能会略高一些。而盒模型属性的动画(如top、margin)等,不能使用GPU硬件加速,并且会造成重绘,性能普遍更低。所以推荐使用变形做动画。

简写属性

使用animation简写属性可以一次定义动画相关的八个属性,八个属性及其默认值为:

  • animation-name: none
  • animation-duration: 0s
  • animation-timing-function: ease
  • animation-delay: 0s
  • animation-iteration-count: 1
  • animation-direction: normal
  • animation-fill-mode: none
  • animation-play-state: running
/* duration | timing-function | delay | name */
animation: 3s linear 1s slidein;

通常来说当动画比较简单时用简写属性会比较方便

动画属性特指度

动画属性不遵守通常来说的特指度顺序。关键帧设置的属性都类似行内声明+!important。所以我们不能再在动画关键帧属性上加!important

图像处理

CSS提供了一些数字图像处理能力。

滤镜

CSS滤镜可以实现一些图像处理效果,例如灰阶、模糊、高对比度等等。

filter: none | <filter-function-list>

过滤函数列表(filter-function-list)主要包括以下函数的组合:

  • blur() 高斯模糊
  • opacity() 透明度
  • drop-shadow() 投影
  • grayscale() 灰阶滤镜
  • sepia() 墨色调滤镜
  • invert() 反色滤镜
  • brightness() 亮度滤镜
  • contrast() 对比度滤镜
  • saturate() 饱和度滤镜
  • url() 可以引用svg定义的滤镜

混合

CSS提供了将重叠的图层混合起来的不同模式。混合是指当不同元素重叠时,重叠部分如何显式的问题。在CSS中,最基本的混合方式就是当前景的alpha通道(透明度通道)小于1时,背景图片直接按照alpha通道的差值显式,又称alpha合成。除此之外,还有一些其他显式方式,主要有:

mix-blend-mode: <blend-mode>
  • normal:alpha合成
  • darken:重叠的两像素对比,选择较暗的像素
  • lighten:重叠的两像素对比,选择较亮的元素
  • difference:重叠的两像素绝对差值
  • hard-light:强光,类似投影效果
  • soft-light:柔光,类似投影效果

裁剪

除了滤镜和混合,CSS害提供了裁剪能力。

clip-path: <clip-source> | [ <basic-shape> || <geometry-box> ] | none

where
<clip-source> = <url>
<basic-shape> = <inset()> | <circle()> | <ellipse()> | <polygon()> | <path()>
<geometry-box> = <shape-box> | fill-box | stroke-box | view-box

where
<shape-box> = border-box | padding-box | content-box | margin-box

各值为:

  • <clip-source>提供一个url函数,引用SVG形状的裁剪
  • <basic-shape>提供基本的图形形状裁剪,其值与浮动形状裁剪(shape-outside)一致,不再复述
  • <geometry-box>可以用CSS盒模型的border-box、padding-box等模型去裁剪元素,也可以使用SVG对象的fill-box等模型去裁剪对象

蒙版

使用过PhotoShop等图像处理软件的同学应该对蒙版非常熟悉。蒙版与裁剪类似,提供一个裁剪形状,在形状内部的内容可见,在形状外部的内容不可见。

mask-image: <image> | none
  • <image>是任何类型的图像(如url()引用的图像或gradient定义的图像)或SVG对象

媒体查询

媒体查询是可以对样式表进行限制,只应用于特定媒体的方式。之前的笔记中也多多少少提到了一些媒体查询相关技术。

使用媒体查询

引入媒体查询的方式主要有:

  • 在HTML中使用media限制link和style元素

    <link rel="stylesheet" type="text/css" media="print" href="style.css">
    
  • 在CSS @import指令后加上媒体限制

    @import url(style.css) print
    
  • 使用@media块定义CSS属性

    @media print{
        body{
            font-family: serif
        }
    }
    

最基本的媒体类型是:

  • all 全部媒体
  • print 打印和打印预览
  • screen 屏幕
  • speech 屏幕阅读器

媒体查询表达式

媒体查询表达式是一种布尔运算,出现在上一节所述的三个地方,基本语法是:

  • ,表示或
  • and表示且
  • not表示非
  • only表示仅在支持媒体查询功能的浏览器上启用媒体查询规则

例如:

@media only and screen and (min-resolution: 72dpi){
    .cl01 {font-style: italic}
}

媒体特性描述符

媒体特性描述符和媒体类型一起组成媒体查询表达式的值,必须以键值对的形式放在圆括号()中。主要的媒体特性描述符包括:

  • 描述宽度:width, min-width, max-width

  • 描述高度: height, min-height, max-height

  • 描述设备宽度:device-width, min-device-width, max-device-width

    设备宽度是设备横向显示的像素,和页面如何缩放无关,这是和宽度width最大的区别

  • 描述设备高度(同上)

  • 描述宽高比:aspect-ratio, min-aspect-ratio, max-aspect-ratio

    即width与height的比值。以斜线分隔,如16/9

  • 描述设备宽高比:device-aspect-ratio, min-device-aspect-ratio, max-device-aspect-ratio

    即device-width和device-height的比值

  • 描述媒体色彩支持:color, min-color, max-color

  • 描述设备分辨率:resolution, min-resolution, max-resolution

    单位一般用dpi

  • 描述设备放置方向:orientation

    取值只有portrait或landscape

响应式设计

使用媒体查询和其他CSS技术,可以使得样式表适应不同的媒体,特别是兼容桌面环境和移动设备。这种特性被人称作响应式设计。

响应式设计通常使用“断点”方式定义样式表:

@media (max-width: 400px){
    .forSmallScreen()
}
@media (min-width: 401px) and (max-width: 1000px){
    .forNormalScreen()
}
@media (min-width: 1001px){
    .forLargeScreen()
}

也经常看见设计人员使用orientation适应移动设备的横向或纵向放置。

响应式设计不仅仅指使用媒体查询,还有弹性布局、栅格布局、相对长度单位等等CSS技术可以用来实现响应式设计。在我的体验中,响应式设计当之无愧的教父级作品就是twitter(网页版),那真的是很厉害了,有空可以研究研究他们的设计。