前端--CSS

420 阅读26分钟

这部分的内容较多,通常面试提问会以CSS开场。 尽管现如今组件库乱花渐欲迷人眼,前端开发人员对于CSS的掌握还是不可或缺的。

引用方式

外部样式表

  • <link>

link 是 HTML 提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性、引入网站图标等。 与HTML同时加载。 可以通过JS操作DOM引入。

  • @import

import只有导入样式表的作用。 页面加载完毕后加载。

内部样式

<style>

内联样式

可继承属性

可继承属性,在没有指定值时,会使用父元素同属性的值。 当不是可继承属性时,可通过inherit关键字指定从父元素继承。

可继承属性简记版:text-,font- ,line- 系列。

  • 字体系列(font-)

font、font-family、font-weight、font-size、font-style、font-variant、font-stretch、font-size-adjust

  • 文本系列

text-indent、text-align、text-shadow、line-height、word-spacing、letter-spacing、 text-transform、direction、color

  • 表格布局

caption-side、border-collapse、empty-cells

  • 列表布局

list-style, list-style-type

  • 光标属性

cursor

  • 元素可见性

visibility

替换元素

通过修改某个属性值就可以替换所呈现内容的元素。如: img, object, video, iframe, textarea, input, select等。

伪类和伪元素

CSS引入伪类和伪元素概念是为了格式化文档树以外的信息,找到那些不存在DOM树中的信息以及不能被常规CSS选择器获取到的信息。

伪类

伪类,一般是为了获取元素的某些特殊状态或子元素。
在CSS3中,常用单冒号表示伪类。
元素的状态可能随用户行为变化,比如a标签的 :link(访问前):visited(访问后):hover(鼠标滑过):active(激活)等, :enabled  :disabled  :checked
:first-child 来获取第一个子元素。

LVHA

当CSS选择器的权重一致时,后面的规则会覆盖前面的规则,因此有时候CSS规则的书写顺序很重要。

  • 当链接未访问过时

(1)当鼠标滑过a链接时,满足:link和:hover两种状态,要改变a标签的颜色,就必须将:hover伪类在:link伪 类后面声明; (2)当鼠标点击激活a链接时,同时满足:link、:hover、:active三种状态,要显示a标签激活时的样式(:active), 必须将:active声明放到:link和:hover之后。因此得出LVHA这个顺序。

  • 当链接访问过时

情况基本同上,只不过需要将:link换成:visited。

伪元素

伪元素,一般用于创建一些不在文档树中的特殊元素,并为其添加样式。
在CSS3中,推荐用双冒号表示。
比如::before::after::first-line::first-letter::selection::placeholder等。
与内容 content 搭配使用,可自定义符号。
与计数器 cunter 搭配使用,可自定义序列号。

选择器

  • !important
  • 行内样式style="",权重1000
  • ID选择器,权重0100
  • 类选择器/属性选择器/伪类选择器,权重0010

E[att]:匹配所有具有att属性的E元素,不考虑它的值 E[att=val]:匹配所有att属性等于"val"的E元素 E[att~=val]:匹配所有att属性具有多个空格分隔的值、其中一个值等于"val"的E元素

  • 元素选择器/关系选择器/伪元素选择器,权重0001

相邻关系:html + div 子关系:ul > li 后代关系:li a html+div>span::after

  • 通配符选择器*

继承样式的优先级低于通配符选择器。

在计算权重时,选择器出现的次数可相加。权重相同的情况下,后面的样式会覆盖前面。

浏览器解析CSS时,从右向左匹配,从关键元素开始左移查找规则选择器的祖先元素。只要选择器的子树一直在工作,样式系统就会持续左移,直到和规则匹配,或者是因为不匹配而放弃该规则。如果从左向右匹配,要多次回溯。

单位

  • px
  • em

相对单位,父元素的字号。

  • rem

相对单位,根元素的字号(可用于响应式布局)。

  • vh, vw

相对单位,1/ 100 of the height or width of viewport.

  • vmin, vmax

相对单位,1 / 100 of the maximum or minimum of those widths and heights

  • ex, ch

字母o的高度

盒模型

盒子的宽 / 高= 内容content + 内边距padding + 边框border + 外边距margin

  • W3C标准盒模型,content-box
  • IE盒模型,border-box,宽、高包含content,border和padding

  • 在IE8+浏览器中使用哪个盒模型可以由box-sizing(CSS3新增的属性)控制,默认值为content-box,即标准盒模型。
  • 在IE6,7,8中DOCTYPE缺失会将盒子模型解释为IE盒子模型。
  • 若在页面中声明了DOCTYPE类型,所有的浏览器都会解释为W3C盒模型,即box-sizing默认是content-box。

width

  • 100%,元素的宽度等于父元素的content-box的宽度。
  • auto,元素撑满整个父元素,margin, border, padding, content自由分配空间。
box-sizing: border-box;
resize: horizontal;
outline-offset: 15px;

padding

固定宽高比的矩形

1)高度设置为0,padding 设置为百分比,会根据父级元素的宽度计算。 2)高度和宽度,利用calc计算vw / vh。

#reactangle {
  width: 5%;  /* 或者用vw */
  height: 0;
  padding-top: 10%;
  background: tomato;
}

code pen demo

border

三角形与扇形

利用了元素边框连接处的等分原理。

#triangle {
  width: 0;
  height: 0;
  border-width: 10px;
  border-style: solid;
  border-color: transparent tomato transparent transparent;
}
/* 扇形在三角形的基础上设置border-radius: 100%, 但是得到的都是90度的,想得到其他大小的扇形,可以使用遮罩 */
/* canvas 的 arc 方法可以画任意大小的扇形 */

margin

margin合并

块级元素的上外边距(margin-top)与下外边距(margin-bottom)有时会合并为单个外边距,这样的现象称为“margin合并”。

  • 相邻兄弟元素

设置BFC

  • 父元素和第一个/最后一个子元素 对于margin-top合并,可以进行如下操作(满足一个条件即可):> - 父元素设置为块状格式化上下文元素;
  • 父元素设置border-top值;
  • 父元素设置padding-top值;
  • 父元素和第一个子元素之间添加内联元素进行分隔。

对于margin-bottom合并,同理

  • 空块级元素
  • 设置垂直方向的border;
  • 设置垂直方向的padding;
  • 里面添加内联元素(直接Space键空格是没用的);
  • 设置height或者min-height

margin无效

  • display:inline 

行内非替换元素,垂直margin是无效的,因为行内元素不可设置宽高。 行内的替换元素,垂直margin有效,并且没有margin合并的问题。

  • 表格中的<tr>和<td>元素,或者 display: table-cell | table-row
  • 绝对定位元素,非定位方位的margin值“无效”。
  • 定高容器的子元素的 margin-bottom,定宽容器的子元素的 margin-right “无效”。

BFC

BFC(Block Formatting Context)指的是块级格式化上下文,一个元素形成了BFC之后,那么它内部元素产生的布局不会影响到外部元素,外部元素的布局也不会影响到BFC中的内部元素。一个BFC就像是一个隔离区域,和其他区域互不影响。与之相对应的是行级格式化上下文IFC。

BFC的布局规则

  • BFC的垂直方向排列。
  • BFC的区域不会与浮动元素重叠
  • 计算BFC的高度时,浮动元素也参与计算
  • BFC就是页面上的一个独立容器,容器里面的子元素不会影响容器外的元素

BFC的触发条件

  • 根元素HTML
  • float不为none(漂浮于标准文档流)
  • position为absolute、fixed(脱离标准文档流)
  • overflow不为visible(盒模型的性质是不影响外部布局)
  • display为inline-block, table-cell, table-caption, flex, inline-flex(行内块元素,默认宽度是内容宽度)

BFC的应用

  • 防止外边距上下重叠
  • 清除浮动
  • 防止字体环绕

布局与定位

display

  • none,不显示
  • block,块级元素

默认宽度为父元素宽度,可设置宽高,换行显示(前后会带有换行符)。

  • inline,行内元素

默认宽度为内容宽度,不可设置宽高,同行显示(常见的行内元素有 span a  img )。 浏览器会把inline元素间的空白字符(空格、换行、Tab等)渲染成一个空格。( li 标签逐行写会产生空格)。

  • inline-block,行内块元素

默认宽度为内容宽度,可设置宽高,同行显示。

  • list-item,像块类型元素一样显示,并添加列表标记
  • table,块级表格显示,表格前后有换行符。
  • inline-table,内联表格,表格前后无换行符。
  • contents,
  • flex, 弹性布局。
  • grid,网格布局。
  • inherit,从父元素继承display属性。
  • initial

position

  • static

默认值,没有定位,出现在正常文档流中。

  • relative

相对定位,相对于元素本身的正常位置,宽高百分比相对于父元素的content-box。

  • fixed

绝对定位,相对于浏览器视图窗口来定位,这意味着即便页面滚动,它还是会停留在相同的位置,脱离了标准文档流。(例如,顶部导航栏,表头固定)。 fixed 的“根元素”固定为浏览器窗口。

  • absolute

绝对定位,相对于最近的已定位(position不为static)的祖先元素的border-box,如果无已定位祖先元素,以body元素为偏移参照基准,脱离了标准文档流。 absolute的”根元素“是可以设置的。

  • sticky

当overflow为scroll时,在relative和fixed之间切换。

  • inherit

从父元素继承。

float

浮动元素漂浮于普通文档流(不能与脱离文档流的absolute和fixed连用)。

清除浮动

子元素浮动,使得父元素的内部高度为0,一般称为“高度塌陷”。清除浮动是为了清除使用浮动元素产生的影响。

  • 父元素预先定义高度。
  • clear: both 属性,一般通过在父元素末尾增加空的div元素或伪元素。
  • 触发BFC,给父元素添加overflow: hidden 或 auto(盒模型不影响外部元素)。
.clearfix::after {
  content: "";
  display: block;
  clear: both;
}

display > position > float

  • 判断display属性是否为none,如果为none,则其余属性无效;
  • 判断position的值是否为absolute或者fixed,如果是则float属性失效,并且display的值应该被设置为table或者block,具体转换需要看初始转换值。
  • 判断float属性的值是否为none,如果不是,则display的值则按上面的规则转换。注意,如果position为relative并且float属性的值存在,则relative相对于浮动后的最终位置定位。
  • 判断float的值为none的元素是否为根元素,如果是,则display的值按照上面的规则转换,如果不是,则保持指定的display属性值不变。

overflow

根元素<html>和文本域<textarea>元素默认可以产生滚动条。 滚动条会占用容器的可用宽度和高度。

  • visible

内容不被休剪,呈现在元素框之外;

  • hidden

内容修剪,其余内容不可见;

  • scroll

内容修剪,显示滚动条;

  • auto

如果内容修剪,显示滚动条;如果空间有剩余,无修剪;

  • inherit

z-index

position不为static,relative和absolute会使得 z-index > 0; float不会改变z-index;

flex

采用flex布局的元素,称为flex容器;子元素自动成为容器成员,称为flex项目。
子元素的float,clear,vertical-align属性将失效。
水平主轴,垂直交叉轴,默认沿水平主轴排列。

容器的可设置属性:

  • flex-direction

主轴方向:row, column

  • flex-wrap

默认项目排列在一条轴线上,如果排不下如何换行: nowrap, wrap, wrap-reverse

  • flex-flow

是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap

  • justify-content

子元素在主轴上的排列方式:flex-start, center,flex-end,space-between, space-around

  • align-items

子元素在交叉轴上的排列方式:flex-start, center,flex-end,baseline, stretch

  • align-content

多根轴线的对齐方式

项目的可设置属性:

  • order

子元素的排列顺序,数值越小,排列越靠前,默认为0;

  • flex-grow

空间有剩余,放大比例,默认为0(不放大);
不论空间剩余或是不足,按照flex-grow的数值比例分享空间(都为1就是等分),与原始宽度无关。

  • flex-shrink

空间不足,缩小比例,默认为1(缩小);
空间不足时,只设置flex-shrink属性,如果所有项目的flex-shrink属性都为1,则按原始宽度比例缩小;
空间剩余时,只设置flex-shrink属性,无变化;

  • flex-basis

在分配多余空间之前,项目占据的主轴空间,默认为auto,即本来大小;

  • flex

是flex-grow,flex-shrink和flex-basis的简写,默认值为0 1 auto

none: 0 0 auto   // 不缩小,不放大,按照本来的大小

auto: 1 1 auto    //  空间不足时等比例缩小,空间剩余时等比例放大

非负数字(num): num 1 0%   // 等分布局

长度或百分比(per): 1 1 per

两个非负数字(num1, num2): num1 num2 0%

非负数字(num)和长度或百分比(per): num 1 per

code pen demo

  • align-self

允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父 元素的align-items属性,如果没有父元素,则等同于stretch。

grid

网格布局。display: grid/inline-grid

  • align-items

    控制垂直位置,取值为 start、end 和 center。

  • justify-items

    控制水平位置。

  • place-items

    是 align-items,justify-items 的简写。

  • grid-template-rows

    rows是代指行,用来声明高,控制垂直方向。

    取值可以是(1)数值 + %,px,vw等单位;(2)repeat();(3)数值 + fr

  • grid-template-columns

    columns是代指列,用来声明宽,控制水平方向。

  • grid-template

    <grid-template-rows> / <grid-template-columns>

  • grid-gap

    指定栅栏之间的距离。

隐藏元素

  • opacity:0

占据空间,不改变页面布局,不会触发回流,绑定事件有效。

  • visibility:hidden

占据空间,不改变页面布局,不会触发回流,绑定事件无效,是继承属性。 如果是table相关的元素,会和display:none一样。

  • display:none

不占据空间,改变页面布局,会触发回流,会渲染,绑定事件无效。

  • z-index=-1

置于其他元素下面

  • clip裁剪

绑定事件无效。

  • transform: scale(0)

将元素缩放为0,绑定事件无效。

  • 使用绝对定位移出可视区域内

居中元素

  • 对于行内元素:

text-align: center

  • 对于宽高固定的元素

(1)水平居中: margin: auto 实现,父元素的 text-align: center 实现;
(2)水平垂直居中:绝对定位absolute,用 top: 50%; left: 50% 定位到页面中心,再通过负值margin调整元素中心到页面中心;
(3)水平垂直居中:绝对定位absolute,用 top: 50%; left: 50% 定位到页面中心,再通过 transform: translate(50%, -50%) 调整元素中心到页面中心;
(4)水平垂直居中:用flex布局,设置父元素容器 align-items: center; justify-content: center (5) 水平垂直居中:用 grid 布局,设置父元素容器: display: grid; place-items: center (6) Logo 图片居中:object-fit:contain;

  • 对于宽高不固定的元素,用 (3)(4)(5)实现。

code pen demo

两栏布局

左边固定,右边自适应。

  1. 利用浮动

左边元素,固定宽度,设置向左浮动; 右边元素,margin-left: 左边元素的宽度,width: auto, 撑满父元素。

  1. flex布局

父元素,设置 flex 布局 左边元素,flex-basis设置基础宽度; 右边元素,flex: 1,width: auto;

  1. 绝对定位

父元素,设置相对定位(作为子元素绝对定位的参照); 左边元素,absolute,设置宽度; 右边元素,margin-left: 左边元素的宽度;

  1. 绝对定位

父元素,设置相对定位; 左边元素,设置宽度; 右边元素,absolute, left: 左边元素的宽度,其他方向定位为0;

code pen demo

三栏布局

左右两栏宽度固定,中间自适应。

  1. 利用浮动

左右设置固定大小,并左右浮动; 中间设置左右两个方向的margin值(HTML顺序里中间栏必须放最后);

  1. 绝对定位

左右设置为绝对定位; 中间设置对应方向大小的margin(HTML顺序里中间栏必须放最后);

  1. flex布局

左右元素的flex-grow和flex-shrink为0,并设置基础大小; 中间元素设置flex为1;

  1. 圣杯布局(顶部、底部、中间三栏)

父元素设置padding给左右栏预留位置,三栏均设置向左浮动,中间栏必须放最前,宽度为父元素的100%; 左右两列被挤到下一行, 通过margin负值移动到上一行,再利用relative相对定位到两边;

  1. 双飞翼布局

相对于圣杯布局,左右位置的保留是通过中间栏子元素的margin值来实现,而不是父元素的padding.

  1. 网格布局
.contariner { 
    display: grid; 
    grid-template: auto 1fr auto / auto 1fr auto; 
}

code pen demo

三明治布局

页眉、页脚始终在页面顶部和末端,中间的内容区可伸缩。

  1. 网格布局
.container { 
    display: grid; 
    grid-template-rows: auto 1fr auto; // auto 即本来的内容高度,1fr 即剩下的高度
}

全屏滚动

原理:有点类似于轮播,整体的元素一直排列下去,假设有5个需要展示的全屏页面,那么高度是500%,只是展示100%。 容器的父级元素overflow属性值设为hidden,容器及容器内的页面取当前可视区高度,通过更改容器可视区的位置来实现全屏滚动效果。主要是响应鼠标事件,页面通过CSS的动画效果,进行移动。

overflow:hidden;
transitionall 1000ms ease;

单行/多行文本溢出省略

/* 单行 */
p {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*多行文本溢出*/
p {
  position: relative;
  line-height: 1.5em;
  /*高度为需要显示的行数*行高,比如这里我们显示两行,则为3*/
  height: 3em;
  overflow: hidden;
}

p::after {
  content: "...";
  position: absolute;
  bottom: 0;
  right: 0;
  background-color: #fff;
}

图片

图片格式

  • BMP

无损,支持索引色和直接色的点阵图。

  • GIF

无损,采用索引色的点阵图,支持动画和透明,体积小。

  • JPEG

有损,采用直接色的点阵图。

  • PNG-8

无损,采用索引色的点阵图,支持动画和透明,体积更小,取代GIF。

  • PNG-24

无损,采用直接色的点阵图,体积略大。

  • SVG

无损的矢量图,没有像素,由线和绘制方法组成。

  • webp

目前只有Chrome和Opera支持,同时支持有损和无损压缩的、使用直接色的点阵图,更小的体积。

图片加载

URL

后台存储格式:图片以独立文件的形式存储在服务器的指定文件夹中,再将路径存入数据库字段中; 通过劫持SRC属性,实现图片在非可视区域的懒加载;

Blob

后台存储格式:图片被转换成二进制流,直接存储在数据库的 Image 类型字段中; 前端需要将其二进制流交由 blob 对象处理,然后通过 blob 的 API 生成临时 URL 赋值给 src 属性来显示;

Base64

Base64编码是一种基于64个可打印字符来表示二进制数据的表示方法,是一种常见的图片处理格式,通过特定的算法将图片编码成一长串字符串,在页面上显示的时候,可以用该字符串来代替图片的url属性。

优点

减少图片的HTTP请求。

缺点

  1. 根据Base64的编码原理,编码后的大小会比原文件大小大1/3,如果把大图片编码到HTML/CSS文件中,不仅会造成文件体积的增加,影响文件的加载速度,还会增加浏览器对HTML/CSS文件解析渲染的时间。(所以在webpack的url-loader配置里,通常只对小于10KB的文件使用base64编码)。一般适用于小图标。
  2. 使用Base64无法直接缓存,要缓存只能缓存包含base64的文件,比如HTML或者CSS,这相比直接缓存图片的效果要差很多。
  3. 兼容性的问题,IE8以前的浏览器不支持。

手摸手,带你优雅的使用 icon

图标

目标:减少HTTP请求,兼容浏览器,可维护。

手摸手,带你优雅的使用 icon

雪碧图(Sprite, SVG-Sprite)

将一个页面所设计到的所有图片放到一张大图,通过CSS的background-image, background-repeat, background-position的组合进行背景定位。

优点:

  1. 可以有效减少资源请求;
  2. 减少图片大小;
  3. 方便风格主题变更;

缺点:

图片的合并和维护比较麻烦。

FontAwesome / IconFont

开源图标库,方便管理,可能存在商用版权的问题。

  • unicode

兼容性最好。 支持像修改字体一样设置font-size, color属性。 不支持多色图标。

  • font-class

语义化,直观。

  • svg-icon

支持多色图标。 支持像修改字体一样设置font-size, color属性。 支持CSS动画。 矢量,支持缩放。

动画

传统的javascript 动画是通过定时器 setTimeout 或者 setInterval 实现的。但是定时器动画一直存在两个问题:

  • 动画的循时间环间隔不好确定,时间太长动画显得不够平滑流畅,时间太短浏览器的重绘频率会达到瓶颈,推荐的最佳循环间隔是17ms(由于多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上动画的最小间隔为1/60*1000ms=16.7ms)。
  • 定时器第二个时间参数只是指定了多久后将动画任务添加到浏览器的UI线程队列中,如果UI线程处于忙碌状态,那么动画不会立刻执行。

为了解决这些问题,H5 中加入了 requestAnimationFrame以及requestIdleCallback

Life of a Frame

一帧内需要完成如下六个步骤的任务:

  • 处理用户的交互

  • JS 解析执行

  • 帧开始。窗口尺寸变更,页面滚去等的处理

  • requestAnimationFrame(rAF)

  • 布局

  • 绘制

requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔跟随浏览器的刷新频率。在隐藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这当然就意味着更少的 CPU、GPU 和内存使用。requestAnimationFrame 是由浏览器专门为动画提供的 API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了 CPU 开销。

requestAnimationFrame的回调会在每一帧确定执行,属于高优先级任务;而如果一帧内任务完成后没超过 16 ms,时间有富余,就会执行 requestIdleCallback 里注册的回调任务,属于低优先级任务。

由于 requestIdleCallback 里的任务发生在一帧的最后,此时页面布局已经完成,所以不建议在 requestIdleCallback 里再操作 DOM,这样会导致页面再次重绘,且操作 DOM 所需要的耗时是不确定的。 同时,也不建议操作 Promise,因为 Promise 属于微任务,会在 requestIdleCallback 结束时立即执行,不管此时是否还有富余的时间,这样有很大可能会让一帧超过 16 ms。

Transform

/* 2D */
// 旋转
transform: rotate(20deg);
// 缩放
transform: scale(2, 3);
transform: scaleX(2);
transform: scaleY(3);
// 倾斜
transform: skew(20deg, 10deg);
transform: skewX(20deg);
transform: skewY(10deg);

/* 3D */
// 旋转
transform: rotate3d(1, 1, 1, 45deg);
transform: rotateX(20deg);
transform: rotateY(20deg);
transform: rotateZ(20deg);
// 缩放
transform: scale3d(2, 3, 2);
transform: scaleX(2);
transform: scaleY(3);
transform: scaleZ(2);
// 移动
transform: translate3d(10px, 10px, 10px);
transform: translateX(10px);
transform: translateY(10px);
transform: translateZ(10px);
// 3D透视
transform: perspective(1000px);  

Transition

Transition主要通过控制属性触发动画,过渡属性 --- 过渡持续时间 --- 过渡函数(曲线) --- 过渡延迟

transition demo

div {
  width: 100px;
  height: 100px;
  background: red;
  transition: width 2s, height 4s, transform 2s;  // 当宽度变化的时候,动画持续2s
}
div:hover {
  width: 300px;   // hover状态触发宽度变化
  height: 200px;
  transform: rotate(90deg);
}

div {
  transition-property: width;
  transition-duration: 2s;
  transition-timing-function: linear;
  transition-delay: 1s;
}
div {
  transition: width 2s linear 1s;
}

/* transition-timing-function */
#div1 {transition-timing-function: linear;}
#div2 {transition-timing-function: ease;}
#div3 {transition-timing-function: ease-in;}
#div4 {transition-timing-function: ease-out;}
#div5 {transition-timing-function: ease-in-out;}

Animation

Animation,作用于元素本身而不是样式属性,可以使用关键帧,更自由。

/* The animation code */
/* from to */
@keyframes example {
  0%   {background-color:red; left:0px; top:0px;}
  25%  {background-color:yellow; left:200px; top:0px;}
  50%  {background-color:blue; left:200px; top:200px;}
  75%  {background-color:green; left:0px; top:200px;}
  100% {background-color:red; left:0px; top:0px;}
}

/* The element to apply the animation to */
div {
  width: 100px;
  height: 100px;
  background-color: red;
  animation-name: example;
  animation-duration: 4s;  // 如果是0则没有效果
  animation-timing-function: linear | ease | ease-in | ease-out | ease-in-out;
  animation-delay: 2s;
  animation-iteration-count: 3;  // 可以设置为infinite
  animation-direction: normal | reverse | alternate | alternate-reverse;
}

div {
  animation: example 5s linear 2s infinite alternate;  // 简写形式
}

CSS动画之旋转魔方轮播

一些应用

0.5px的线

  1. transform: scale()
#line {
  height: 1px;
  background: tomato;
  transform: scaleY(0.5);
}
  1. metaviewport 利用缩放原理
<meta name="viewport" content="width=device-width; initial-scale=0.5; maximum-scale=0.5; minimum-scale=0.5; user-scalable=no;">
  1. border-image

圆环动画

#spinner {
  width: 10px;
  height: 10px;
  border-width: 2px;
  border-style: solid;
  border-color: tomato tomato transparent transparent;
  border-radius: 100px;
  animation: spin 2s linear infinite;
}
@keyframes spin {
  0% {transform: rotate(0);}
  100% {transform: rotate(360deg);}
}

code pen demo

轮播(Slideshow / Carousel)

  1. HTML
  2. CSS

所有图片默认 display:none; 利用Animation实现图片淡出效果。

  1. JS

初始设置第一张图片 display: block; 设置prev()、next()、jump(index)方法;利用setInterval做自动轮播。

滤镜

网站变灰

html {
    -webkit-filter: grayscale(100%);
    -moz-filter: grayscale(100%);
    -ms-filter: grayscale(100%);
    -o-filter: grayscale(100%);
    filter: grayscale(100%);
    filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
}

处理器

预处理器

CSS组件模块化开发,避免样式穿透,变量处理,代码混合,嵌套选择器,继承选择器。

Sass

Less

后处理器

规范化处理,兼容处理,CSS压缩工具。

PostCSS

类似于JS的 babel

性能优化

加载性能

  1. CSS压缩
  2. 减少使用@import,页面加载完成后加载;建议使用link,在页面加载时一起加载,必要时使用preload / prefetch

选择器性能

避免使用通配符,计算次数惊人; 避免嵌套层级过深;

渲染性能

  1. 慎重使用高性能属性:浮动,定位;
  2. 尽量减少页面回流;
  3. CSS雪碧图(小图标);

可维护性

样式分离,模块化

样式兼容

什么是跨端?

PC(屏幕适配), H5, 移动端(安卓、IOS), 小程序(微信、支付宝、百度、头条等)...

解决方案?

响应式设计(PC), RN(移动端), Taro(小程序), Flutter(移动端,web)...

移动端适配

绝对单位问题:如何让 10px 在 1 倍屏和 3 倍屏上看起来大小一样?

dpr(设备像素比) = 物理像素(设备像素) / 设备独立像素(css像素)

普通屏幕的dpr=1,高清屏幕的dpr>=2。我们在样式代码上定义的元素大小是css像素,这意味着普通屏和高清屏上展现的像素会有不同,同时也伴随着图片显示问题。

例如,width: 2px; height: 2px 在普通屏上物理像素是 2X2=4,在高清屏上则是(2X2)X(2X2)=16。从设计稿得到的尺寸通常是以px为单位的,如果要换算成rem作单位需要依赖编译器插件,而且会出现小数的情况,一般的做法是:

  1. 自定义flexible.js文件,将计算font-size标准值的n定为375,这样可以使得在高清屏中1rem = 1px。

  2. 在webpack里使用px2rem-loader。

相对单位问题:如何让宽、高跟随屏幕大小等比例变化?

vw, vh, vmin, vmax

最小单位问题:如何实现 1px 细线?

  1. 使用border-image ,但是border颜色变了就得重新制作图片,而且圆角会比较模糊。

  2. 使用viewport的scale缩放 适用于新项目,对于老项目的维护改动较大。

  3. 使用伪元素和transform

    伪元素设置绝对定位,并且和父元素左上角对其。将伪元素的长和宽先放大2倍,然后再设置边框,以左上角为中心,缩放到原来的0.5倍。

    优点:全机型兼容,实现了真正的1px,而且可以圆角。

    缺点:暂用了伪元素,可能影响清除浮动。

viewport

viewport(视口)代表当前可见区域,在PC端通常与浏览器窗口相同,但不包含浏览器的UI和菜单栏等。

<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">

width:正整数或device-width;
height:正整数或device-height;
initial-scale:定义初始缩放值,整数或小数;
minimum-scale:定义缩小最小比例;
maxmum-scale:定义放大最大比例;
use-scalable:定义是否允许用户手动缩放页面,默认yes;

  • layoutviewport布局视口

宽度大于浏览器可视区域,一般为980px,可以通过拖动和缩放来查看页面;

  • visualviewport视觉视口

一般为屏幕分辨率大小。

  • idealviewport理想视口

通过修改layoutviewport的大小等于设备宽度,因此根据idealviewport设计的页面,在不同分辨率屏幕下显示相同。

rem适配

过渡方案(用户使用更大的屏幕,是想看到更多的内容,而不是更大的字体)。 此外,阿里开源的flexible移动端适配方案。

flex,vw, vh, vmin, vmax

vw / vh 将视口宽度、高度等分为100份。 vmin / vmax 即视口宽度、高度中的较小、较大值。

媒体查询

通过媒体查询检测不同终端设备的尺寸,做兼容处理,页面头部必须有meta声明和viewport.

浏览器兼容

初始化样式

因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。 出于性能的考虑,不建议使用通配符初始化样式,通配符需要把所有的标签都遍历一遍,当网站较大时,样式比较多,这样写就大大的加强了网站运行的负载,会使网站加载的时候需要很长一段时间,因此一般大型的网站都有分层次的一套初始化样式。

在跨设备类型如果交互差异太大的情况,考虑分项目开发。