CSS知识总结

223 阅读8分钟

1.什么是CSS

层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML或者XML等文件样式的计算机语言。CSS不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。CSS 能够对网页中元素位置的排版进行像素级精确控制,支持几乎所有的字体字号样式,拥有对网页对象和模型样式编辑的能力。

什么是层叠

  • 样式层叠:可以多次对一个选择器声明样式
  • 选择器层叠:可以用不同选择器队同一个元素声明样式
  • 文件层叠:可以用多个文件进行层叠

2.版本与可用性

现在常用的版本为CSS2.1和CSS3,由于不同浏览器兼容性不同,需要对CSS的可用性进行查询,使用caniuse.com查询。

3.CSS基础语法

CSS的核心语法只有以下两种,复杂的语法通过以下两种语法进行组合

样式语法:
    选择器{
      属性名:属性值;
      /*注释*/
    }
at语法:
    @charset "UTF-8"  /*字符集指定*/
    @import url(2.css);/*文件引入*/
    @media (min-width:100% 100px) and (max-width:200px) {
      /*样式语法*/
    }/*媒体查询*/

注意:

  • @charset必须在CSS的第一行
  • 字符集指定和文件引入必须以分号结尾

4.如何调试CSS

  • W3C验证器调试 (过于繁琐,不推荐使用)
  • VSCode 查看颜色 (功能相对于WebStorm较弱)
  • WebStorm 查看颜色 (推荐使用)
  • 开发者工具查看警告 (推荐使用)
  • border调试法:
    • 怀疑某个元素有问题,就给该元素添加border
    • 没出现border,说明选择器或语法错了
    • border出现了,查看边界是否符合预期
    • bug解决后再删除border

常见的错误:

  • 拼写错误
  • 大小写错误
  • 单位错误
  • 没添加单位

5.怎么查CSS的资料

  • 权威:MDN
  • 技巧: CSS tricks 或者张鑫旭的博客

6. 文档流

文档中可显示对象在排列时所占用的位置

  • 流动方向
    • inline 元素从左到右,到达最右边才会换行
    • block 元素从上到下,每一个都另起一行
    • inline-block 从左到右
  • 宽度
    • inline 宽度为内部inline元素之和,不能用width指定
    • block 默认自动计算宽度,可用width指定
    • inline-block 结合前两者特点,可以用width指定
  • 高度
    • inline 高度由inline-height间接确定,跟height无关
    • block 高度由内部文档流元素决定,可以设height
    • inline-block 和block类似 可以设置height

注意:

  1. CSS最新版本中不区分内联元素和块级元素,只看实际的状态
  2. 不要再内联元素的内部插入块级元素
  3. 轻易不要写 width:100%

7. overflow

当内容所占的大小大于容器时,会导致内容溢出

  • 使用overflow设置是否显示滚动条,可分为overflow-x和overflow-y
    • atuo:根据实际情况灵活设置
    • scroll:永远显示
    • hidden:隐藏溢出部分
    • visible:显示溢出部分

8. 脱离文档流

使元素不在文档流中,用于改变位置排版

能触发脱离文档流的属性:

  • float:left/right
  • position: absolute/fixed

9.盒模型

CSS 假定所有的HTML 文档元素都生成了一个描述该元素在HTML文档布局中所占空间的矩形元素框,可以形象地将其看作是一个盒子。

CSS 盒模型有两种,一种是 content-box 一种是 border-box。
content-box 的宽度 width 表示内容区的宽度,不包含 padding 和 border;
border-box 的宽度 width 表示内容区 + padding + border 的总和。
一般优先使用后者。

详细内容可以参考博客

10.外边距合并

  • 发生外边距合并的元素:块元素之间(父子、兄弟、空块);发生外边距合并的边距:上、下边距(左右边距不会合并);

  • 相邻的兄弟元素之间必出现margin合并(除非后者兄弟姐妹需要清除过去的浮动);

  • 父元素与第一个子元素间,如果没有padding、border、inline content、清除浮动这四个属性之一,就会出现上边距合并;

  • 父元素与最后一个子元素之间,如果没有padding、border、inline content、height、min-height、max-height这几个属性之一,就会出现下边距合并;

  • 空的块级元素,如果其border、padding、inline content、height、min-height都不存在,那么它的上下外边距将会合并。

怎么阻止合并:

  • 阻止父子元素margin合并
    • 使用padding/border
    • 使用overflow: hidden
    • 使用display:flex
  • 同级元素margin合并是符合预期的
    • 也可以用inline-block消除

11.float布局

用于兼容IE9及以下时使用float布局,基本满足PC页面需求,手机页面不适用。

  • 子元素添加float:left和width
  • 父元素加上 .clearfix
.clearfix::after{
  content:'';
  display:block;
  clear:both;
}

缺点: 需要自己计算宽度,不灵活。

相关经验:

  1. float布局不兼容手机,不需要考虑响应式的问题
  2. 一般最后一个元素不指定width
  3. IE6/7中存在双倍margin的bug,可以手动减半解决或者改为inline-block

12. flex布局

一维布局,适用于较新的浏览器和手机浏览器等

具体语法:

使一个元素变成flex容器

.container{
  display:flex;
}

父元素样式

.container{
//改变items流动方向(主轴)
flex-direction: row | row-reverse | column | column-reverse;

//换行方式
flex-wrap: nowrap | wrap | wrap-reverse ;

//主轴对齐方式,默认为横轴,当flex-direction:column 时,主轴为纵轴
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;

//次轴对齐方式,默认为纵轴,当flex-direction:column 时,次轴为横轴
align-items: flex-start | flex-end | center | stretch | baseline;

//多行内容分布,很少用
align-content: flex-start | flex-end | center | stretch | space-between | space-around;
}

子元素样式

.item{
//主轴顺序,数字
order:0 | 1 | -1;

//占据空间,如果有多余的空间,则分成x份,给该item数字的份数。0则不占据多余空间。
flex-grow: 0 | 1 | 2;

//当空间不足时,压缩数字大的空间,0则不压缩
flex-shrink: 0 | 1 | 2 ;

//控制基准宽度,默认为auto
flex-basis: 100px;

//合并使用
flex: flex-grow flex-shrink flex-basis;

//定制某个元素特有的对齐方式
align-self: flex-start | flex-end
}

常用flex布局代码

display:flex
flex-direction:row | column
flex-wrap:wrap
justify-content:center | space-between
align-items:center

13. grid布局

二维布局,兼容性较差,功能强大

grid布局的容器

.container{
  display:grid | inline-grid;
}

常用属性

.container{
//设定grid的格子,53列,单位可以为px,em,vh,百分比,auto
//可以设置为fr fr等比分成N个fr,1fr表示占据1/N的大小
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
//可以合并
grid-template: rows / columns;

//空隙
grid-column-gap: 10px;
grid-row-gap:10px;
grid-gap:15px;
}

.item{
//设定子区域,从第几条线到第几条线,默认到下一条线,每条线可以起别名
grid-column-start: 2;
grid-column-end:4;
grid-row-start:1;
grid-row-end:3;
//起止两个属性可以合并
grid-column:2/4;
grid-row:1/3;
//行列也可以合并
grid-area:r-start / c-start / r-end / c-end;
}

//分区
.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
  grid-template-areas: 'a . c'
                     'd . f'
                     'g . i';

}
//为区域命名,空区域可以用.占位

14.CSS中的div分层

从上向下分别为:

  • 内联子元素
  • 浮动元素
  • 块级子元素
  • border
  • backgroud

浮动元素脱离文档流

15. Position

指定一个元素的定位方法的类型。

  • static:默认值,待在文档流中
  • relative: 相对于原始的定位,升起,不脱离文档流,一般用于给absolute元素做父元素,很少用作位移。
    • 配合z-index做新层叠的上下文,z-index的默认值为auto,不要写9999这类的z-index
      • z-index只对position属性的元素有效
      • 指定一个元素的堆叠顺序,-1<0(auto)<1
  • absolute:脱离原来的层级,另起一层;或者鼠标提示
    • 需要父元素为position:relative
    • 相对于上级元素中第一个不是static的元素定位
    • 某些浏览器中缺少left或者top属性会导致位置错乱
  • fixed:相对于视口固定位置显示
    • 尽量不要和transform同时使用
    • 手机上不要使用
    • 也可以配合z-index使用
  • sticky:粘滞定位,用于实现类似固定导航条的功能,兼容性差

16.层叠上下文

假定用户正面向(浏览器)视窗或网页,而 HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。

  • 层叠上下文可以包含在其他层叠上下文中,并且一起创建一个层叠上下文的层级。
  • 每个层叠上下文都完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
  • 每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。
  • 每个上下文会产生一个层叠作用域,同作用域的z-index才可以互相比较
  • 负数的z-index也不能离开其所在的作用域

常见的产生层叠上下文的属性:

  • transform
  • opacity
  • flex
  • z-index
  • position:obsolute | relative 且 z-index!=auto
  • position:fixed/sticky 其他属性:MDN

17. 浏览器渲染原理

渲染流程

1). 根据HTML构建HTML树 (DOM)
2). 根据CSS构建CSS树 (CSSOM)
3). 将两棵树合并为一棵渲染树 (render tree)
4). Layout布局 (文档流、盒模型、计算大小和位置)
5). Paint绘制 (把边框颜色、文字颜色、阴影等画出来)
6). Compose合成 (根据层叠关系展示画面)

其中layout和paint可能会被省略,例如改变背景颜色会跳过layout,改变transform属性跳过layout和paint,详情查询CSS各属性触发 性能优化:

  • 谷歌经验
  • JS优化:使用requestAnimationFrame代替setTimeout或setInterval
  • CSS优化:使用will-change或translate

18.transform

用于制作补间动画只有开始状态和结束状态 常用功能

  • translate 位移
  • scale 缩放
  • rotate 旋转
  • skew 倾斜
.demo{
   backgroud:green;
   transition:all 1s;//指定过渡的属性和时间
}
//鼠标悬浮触发事件
.demo:hover{
   transform:translateX(100px);
   transform:scale(1.5)
   transform:rotate(45deg)
   background:blue;
}
  • 一般需要配合transition使用
  • inline元素不支持transform

具体语法查询MDN

19.transition

补充过渡的中间帧

语法: transition:属性名 时长 过渡方式 延迟。

  • 可以用逗号分割两个不同的属性
  • 可以用all同时控制全部属性。
  • 不是所有属性都能过渡
    • display:none =>block 不可行,一般使用visibility
    • 注意background和opacity
  • 过渡过程必须要有起始状态和终止状态,只能进行一次改变,多次改变需要添加中间状态。中间过程使用setTimeout或者transitionend事件监听。

20. CSS animation动画

帧动画:不仅有开始和结束状态,还可以用关键帧来定义中间的状态,可以做出比较复杂的动画。详情戳MDN 语法:

//animation-name@keyframes定义的名字
//animation-duration : 持续时间
//animation-timing-function : 动效函数
//animation-delay :延迟时间 第二个数字
//animation-iteration-count:次数 无限为infinite
//animation-direction:方向 normal正向播放 reverse反向播放 alternate来回播放
//animation-play-state:运行状态 running运行 paused动画暂停
.demo{
  animation: xxx
}
@keyframes xxx{
  0%{
    transform:none;
    background-color:red;
  }
  50%{
    transform:translateX(100px);
    background-color:blue;
  }
  100%{
    transform:translateX(100px);
    transform:translateY(100px);
    background-color:yellow;
  }
}

21. 其他技巧

等待后续总结