CSS 总结

170 阅读11分钟

1 文档流(normal flow)

文档流指元素在文档中的排列方式

元素类别文档流宽度高度
inline从左至右排列,会同时跨两行不能指定宽度不可指定高度,可通过line-height间接确定高度
block从上至下排列,每个元素为一行可以指定宽度,默认为auto,一般不设置100%可以指定高度
inline-block从左至右排列,但是一个元素不会跨行可以设置宽度可以设置高度

2 盒模型

CSS盒模型指的是在布局文档时,浏览器的渲染引擎根据标准CSS 基本框模型将每个元素表示为一个矩形框。常见的有两种,content-box内容盒模型,border-box边框盒模型,是通过box-sizing来指定,默认值是content-box。两者主要区别在于

  • content-box:

width = 内容区的宽度

height = 内容区的高度

  • border-box:

width = 内容的宽度 + 内边距之和(左右两内边距)+ 左右两边框之和

height = 内容区的高度 + 内边距之和(上下两内边距) + 上下两边框之和

3 overflow文本溢出

属性值注解
visible(默认)超出内容一样展示
hidden超出内容隐藏,不展示
scroll显示滚动条,无论文本内容是否溢出
auto文本溢出展示滚动条,未溢出不展示滚动条

4 margin合并

父元素和子元素的margin上下会合并

兄弟元素的margin上下会合并

阻止合并常见方式--两个元素之间加个高度

  • 父子合并设置border
  • 父子合并设置padding
  • 父子合并设置overflow:hidden
  • 兄弟合并display:inline-block;width:100%

5 布局

布局.png

5.1 float布局

实践过程中的注意点

  • img下边多出一部分(加背景色后看得明显),使用vertical-align:top/middle可以消除;

  • 边框盒模型中,使用border调试,固定宽度时容易因为border导致width不够,可使用outline进行调试

  • 让固定宽度的块级元素居中,margin:0 automargin-left:auto;margin-right:auto。后面的更优于前者,理由是,多余的css尽量不要写

  • 平局布局时,若最小块之间加了margin-right:10px,为了实现平均布局,需要在外层和具体项之间加上一个div(如class为x)包裹,.x需要加margin-right:-10px;

    例子:js.jirengu.com/daluk/4/edi…

5.2 flex布局

container的属性

  • flex-direction:row/row-reverse/column/colum-reverse 主轴方向,默认横轴

  • flex-wrap:nowrap/wrap/wrap-reverse 是否折行

  • justify-content:flex-start/flex-end/center/space-beween/space-around 内容的排列方式

  • align-items:stretch/flex-start/flex-end/center/baseline 次轴的方向,默认竖轴

  • align-content:flex-start/flext-end/center/stretch/space-between/space-around 多行内容排列方式

  • 实现顶部分两块,左边居左,右边居右,可以用

header{
	display:flex;
    justify-content:space-between;
}

或者对右边的块加上margin-left:auto;

  • flex-directionflex-wrap两个属性经常会一起使用,所以有缩写属性flex-flow。这个缩写属性接受两个属性的值,两个值中间以空格隔开。

item的属性

  • order 默认为0,按照数字从小到大从左往右排,可以为负数

  • flex-grow:[数字] 控制变大,数字越大,占的空间越大

  • flex-shrink:[数字] 控制变小,默认是1,一般为0,防止变小

  • flex-basis 设置基本宽度,类似于width,很少用

例子:js.jirengu.com/mezis/1/edi…

5.3 grid

多用于不规则布局,使用时参考

[www.ruanyifeng.com/blog/2019/0…]:

  • 父容器设置

1、display:grid/inline-grid 指定网格布局

2、grid-template-rows:绝对单位或者百分比 写几个就代表有几行 定义网格中每一行的行高

grid-template-columns 同上 定义网格中每一列的列宽

  • repeat() 在上述两个属性中,如果同时出现连续一样的值,可以指定repeat(重复次数,值)

grid-template-rows:20% 20% 20% 20% 20%可以简写成grid-template-rows:repeat(5,20%)

  • auto-fill 自动填充,让行或列容纳尽可能多的单元格
.container{
    display:grid;
    grid-template-rows:repeat(auto-fill,100px);
}

上述代码表示,固定行高是100px,然后自动填充多个,直至将容器中不能防止更多的行

  • fr 表示比例

    .container{
        display:grid;
        grid-template-rows:100px 1fr 3fr;
    }
    

    上述代码表示,网格中第一行行高为100px,剩下的部分按比例分成四份,第二行占一份,第三行占三份

    auto 浏览器自己决定长度

    grid-template-columns:100px auto 100px;
    

    上述代码中,左右两列列宽均为100px,中间部分为剩余宽度

3、grid-template-areas 用于定义区域

.container{
    display:grid;
    max-width:800px;
    grid-template-columns:200px auto 100px;
    grid-template-rows:40px 400px 50px;
    grid-template-areas:"header header header"
        "aside main ad"
        "footer footer footer"
}
.header{
    grid-area:header;
}
.aside{
    grid-area:aside;
}
.main{
    grid-area:main;
}
.ad{
    grid-area:ad;
}
.footer{
    grid-area:footer;
}

4、grid-templategrid-template-columns grid-template-rows``grid-template-areas的简写

5、gridgrid-template-rows grid-template-columns grid-template-areas grid-auto-rows grid-auto-columns grid-auto-flow的简写

  • 子元素的属性

    row行column列。从1开始编号,数每一条行或列的边

    • grid-column-start:[数字]|[别名] 从哪一列开始
    • grid-column-end:[数字]|[别名] 指定结束列
    • grid-column:[起始列] [结束列] 上面两个的简写
    • grid-row-start:[数字] | [别名] 指定开始行
    • grid-row-end:[数字] | [别名] 指定结束行
    • grid-row:[起始行] [结束行] 上面两个的简写
    • grid-area:grid-row-start grid-column-start grid-row-end grid-column-end grid-row grid-column的缩写

6 浮动 position

布局和定位的区别

布局是屏幕平面上元素的摆放,定位是垂直于屏幕的元素的摆放

position的取值值的含义
static默认值,使用正常布局行为,不脱离文档流,left/right/top/bottom/z-index等属性无效
relative相对定位,浮动,但不脱离文档流,在此元素未添加定位时所在的位置留下空白,相对于原位置的定位
absolute绝对定位,脱离文档流,不为元素留空间,定位是参照祖先元素中使用position但值不为static的元素
fixed固定定位,脱离文档流,不为元素留空间,定位是参照屏幕视口(viewport),当元素祖先的transform/perspective/filter属性非none时,容器由视口改为该祖先
sticky粘滞定位,根据正常文档流进行定位,要指定left/right/top/bottom四个其中之一,否则其行为与相对定位相同

经验总结:

  • 一般absolute搭配relative使用

  • 使用absolute或者fixed,一定要补top、left,某些浏览器上位置会错乱

  • sticky的兼容性移动端的浏览器,但老的桌面浏览器兼容性差

  • 移动端尽量不要使用fixed,容易踩坑

  • 学会管理z-index,不要随意使用z-index:9999

7. div的分层

内联子元素指的是display:inline/inline-block的元素

浮动元素指的是使用float定位的元素

块级子元素指的是display:block的元素

background是最后一层,border倒数第二层

divide.png

8. 层叠上下文

层叠上下文:对HTML元素的一个三位构想。在浏览页面时,HTML元素沿着其相对于用户的一条虚构的Z轴排开。

形成层叠上下文的常见条件(全部请见MDN-层叠上下文):

  • 文档根元素html
  • position值为absoluterelative,且z-index值不为auto的元素
  • position值为fixedsticky的元素
  • flex容器的子元素,且z-index不为auto
  • grid容器的子元素,且z-index不为auto
  • opacity值不为1的元素
  • 以下任一属性值不为none的元素
    • transform
    • filter
    • perspective
    • clip-path
    • mask/mask-image/mask-border

z-index默认为auto,计算为0,但不等于0。值<=-1,表示在background下层,值为>=1,表示在内联子元素上层。

注意:

  • 对应z-index:5z-index:-1的元素谁在上,视情况而定,如果是处在同一个层叠上下文,则z-index:5对应的元素在上,如果不处在同一个层叠上下文,则其祖先元素如果处于同一个层叠上下文,比较祖先元素的z-index值来决定

  • 当处于层叠上下文的世界中,即使子元素的z-index比父元素的小,也是在父元素的上层,父元素的background是最底下的一层

    .parent{
      height:200px;
      width:200px;
      margin:30px;
      border:1px solid black;
      position:relative;
      z-index:1;
    }
    .child{
      width:100px;
      height:100px;
      border:1px solid black;
      position:absolute;
      left:-10px;
      background:red;
      z-index:-1;
    }
    

    实际结果显示,即使父元素的z-index大于子元素的z-index,子元素还是在父元素的上层

z-index.png

9. CSS动画

9.1 动画的原理

由许多静止的的画面(帧),以一定的速度连续播放,肉眼因视觉残像产生错觉,而误以为是活动的画面。

9.2 transform

transform常见属性值,详情请见MDN

常见属性名含义备注
translate移动translateX translateY translateZ translate translate3d 长度/百分数,translateZ要搭配perspective(视角)使用
rotate旋转rotateX rotateY rotateZ rotate3d 角度
scale缩放scaleX scaleY scaleZ scale3d 数字
skew倾斜skewX skewY skew 角度

补充

  • 元素上下左右居中
left:50%;right:50%;transform:translate(-50%,-50%);
  • 使用scale时元素内容也会随之缩放,比如border、背景图等,尽量少用

9.3 transition 过渡

属性名含义备注
transition-property属性名指定要变化的属性名
transition-duration时长运动过程总时间
transition-timing-function动画移动方式常见的有:linear线性、ease默认、ease-in、ease-out、ease-in-out
transition-delay动画延迟时间延迟指定时间后再变化

简写方式 transition:属性名 | 时长 | 移动方式 | 延迟时间

补充

如何让动画停在最后的结束位置?transition的属性值中加上forwards

9.4 animate

通过@keyframe定义动画名及关键帧,有以下两种方式,第二种可定义多个帧,更常用

@keyframes [动画名]{
    from{
        /*起始帧*/
    }
    to{
        /*结束帧*/
    }
}
@keyframes [动画名]{
    0%{
        /*起始帧*/
    }
    50%{
        /*中间帧*/
    }
    100%{
        /*结束帧*/
    }
}

animate常见属性

属性名属性值备注
animation-name动画名
animation-duration动画一个运动周期的时长
animation-timing-function运动方式ease
linear
animation-delay延迟时间
animation-iteration-count播放次数inifite
number
animation-direction设置动画在每次运行完后是反向运行还是重新回到开始位置重复运行normal
reverse
alternate
alternate-reverse
animation-fill-mode指定动画执行前后如何为目标元素应用样式none
forwards
backwards
both
animation-play-state允许暂停和恢复动画,可以在js中更改属性值,控制动画暂停还是恢复paused
running

10. 浏览器渲染原理

10.1 渲染过程

  1. 处理HTML标记并构建DOM树
  2. 处理CSS标记并构建CSSDOM树
  3. 将DOM和CSSDOM合并成一个渲染树(render tree)
  4. 根据渲染树来布局(layout),计算每个结点的几何信息
  5. 绘制(paint)把边框颜色、文字颜色、阴影等画出来
  6. Composite 合成,根据层叠关系展示画面

10.2 渲染性能

  • 60fps与设备刷新频率

目前大多数设备的刷新频率是60次/秒(一次就是1/60=16.66毫秒)。如果在页面中有一个动画或者渐变效果,或者用户在滚动页面,那么浏览器渲染动画和页面的每一帧的速率也需要与设备屏幕的刷新频率保持一致。其中,每一帧的预算时间为16.66毫秒,但实际上,浏览器还有整理工作要做,要求所有的工作需要在10毫秒内完成,如果无法符合此预算,帧率将下降,并且内容在屏幕上会抖动。此现象通常称之为卡顿,会对用户体验产生负面影响

  • 像素管道

pipe.png

    • JavaScript。实现一些视觉变化的效果

    • 样式计算。根据匹配选择器计算出哪些元素应用哪些CSS规则,并计算每个元素的最终样式

    • 布局。浏览器计算元素要占据的空间大小及其在屏幕的位置

    • 绘制。填充像素的过程。涉及绘出文本、颜色、图像、边框和阴影,基本上包括每个元素可视部分。绘制一般是在多个层上完成的

    • 合成。由于页面的各部分可能被会知道多层,由此他们需要要按正确的顺序绘制到屏幕上

      考虑性能,需要尽量避免上述步骤,可以查看每个属性触发了什么流程,比如在chrome中使用transform,一般经过JS / CSS > 样式 > 合成,这种的性能开销是最小的。

补充: visibility: hiddendisplay: none 是不一样的。前者隐藏元素,但元素仍占据着布局空间(即将其渲染成一个空框),而后者 (display: none) 将元素从渲染树中完全移除,元素既不可见,也不是布局的组成部分。