CSS总结

201 阅读11分钟

css由Håkon Wium Lie首先提出

体系化学习

学一门语言必须学会什么?

  • 语法(怎么写代码)
  • 如何调试(怎么知道自己的代码写错了)
  • 在哪查资料(抄代码)
  • 标准制定者是谁

语法一:样式语法

选择器 {
属性名:属性值;
/*注释*/
}

例:

p {
    color: pink;
    /* 字体颜色为粉红色 */
}

【注】

  • 所有符号都是英文符号,写错了浏览器会警告
  • 区分大小写
  • 注释为/* */

语法二:@语法

@charset “UTF-8”;
@import url(2.css);
@media (min-width:100px) and (max-width:200px){
}

【注】

  • charset必须放在第一行
  • charset是字符集的意思,但UTF-8是字符编码encoding(文件编码),这是历史遗留问题(UTF有9、16、32好几种需要区分)
  • 前两个@必须以分号;结尾
  • @media以后单独提出来

如何调试

方法:

  • 使用W3C验证器
  • 使用VSCode看颜色
  • 使用webstorm看颜色
  • 使用开发者工具看警告

如何使用开发者工具:

  • 找到标签
  • 看它是否有选择器
  • 看它样式是否被划掉
  • 看它样式是否有警告

Border调试法

步骤:

  • 怀疑某个元素有问题,给这个元素加个border逐次检验
  • border没出现?说明选择器错了或者语法错了
  • border出现了?看边界是否符合预期
  • bug解决后把border删掉

在哪查资料

网站推荐

  • Google搜索关键词加MDN
  • CSS tricks (英文)
  • 张鑫旭的博客

在哪搜练习素材

PSD

  • Freepik搜索PSD web(有免费版,注意限定版权问题)
  • 中文版有365PSD——UI套件

效果图(不提供下载)

  • dribbble.com顶级设计师社区,可以模仿

商业网站

  • 模拟常去的网站

几个重要基本概念

  • 文档流Normal Flow
  • 块、内联、内联块
  • margin合并
  • 两种盒模型(border-box更符合人类思维)

文档流

流动方向

  • inline元素从左到右,到达最右边才会换行(同一部分可以跨行)
  • block元素从上到下,每一个都独占一行
  • inline-block从左到右,但同一部分不跨行

宽度

  • inline宽度为内部inline元素之和(尽量窄),不能用width指定
  • block默认自动计算宽度(是auto,不是100%),可用width
  • inline-block结合前两者的特点:尽量窄,但可用width

高度

  • inline高度由line-height间接决定,与height无关
  • block高度由内部文档流元素决定,可以设height
  • inline-block与block类似,可设置height

overflow

  • 当内容的宽、高大于容器时会溢出,可用overflow来设置是否显示滚动条
  • auto灵活设置(溢出则显示,未溢出则不显示);scroll默认显示;hidden直接隐藏溢出部分,拖动不可见;visible直接显示溢出部分;
  • overflow-x和overflow-y可以使用,但可能出现bug,暂时不建议

脱离文档流

  • float
  • position:absolute/fixed;

盒模型

box-sizing: border-box | content-box;

Tips:

  1. 可以使用caniuse.com来查看css、grid等样式的兼容性
  2. 记住一个概念:没有定死的块级元素和内联元素之分,因为任何元素都可以变成块级或者内联的(display:block;——display:inline),可以说现在该元素是内联的或块级的
  3. 不要写宽度100%!!
  4. 不要在inline里面写block
  5. 内联元素不接受width和height直接指定宽高
  6. (用border测试法会发现) div无内容会默认有auto的宽度但不会有高度; span无内容会有line-height默认高度但不会有宽度。 简单来说就是:div无内容则无高度

CSS布局

布局分类:

  • 固定宽度布局,一般为960/1000/1024px
  • 不固定宽度布局,主要靠文档流原理布局(多见于手机)文档流自适应,不需要加额外的样式
  • 响应式布局。意思就是PC上固定宽度、手机上不固定宽度。也就是一种混合布局

布局思路一图流

image.png

float布局

步骤

  • 子元素上加 float:left和width
  • 父元素上加 .clearfix 很重要!
  • 因为float后的元素会脱离文档流,父元素加上.clearfix后父元素才会有高度。 (html里的父元素加上class=”clearfix”;css里写出
.clearfix::after {
content'';
display: block;
clear: both;
}

经验

  • 留一些空间或者最后一个不设宽度(可以设个最大宽度)
  • float布局不需要做响应式,因为手机上无ie,这个布局是专门为ie准备的
  • ie6/7存在双倍margin的bug,解决方式有两种 n 将错就错,把margin减半  _margin-left:5px; n 或者,加个display:inline-block;
  • _margin-left是ie可识别的,其他网页不识别,正常margin就好

平均布局

  • 如果margin布局发现最后多出了一部分margin,在中间加一个div,对该div的样式使用-margin
  • 如果在其他地方有个margin-top:10px;使用下面的就不会覆盖
  • 如果设置了宽度,且左右分别auto,会直接居中(只针对块元素)
margin0 auto;
/* 下面的两句得分高,因为不会覆盖掉上下边距 */
margin-left: auto;
margin-right: auto;

flex布局

flex container样式

先既定一个container和一个item

  • display:flex | inline-flex;(有些类似inline-block)

  • container的主轴方向由他自己控制(比如从左到右、从上到下)

    flex-direction:column;(从上到下,默认是row从左到右)

    flex-direction:row-reverse;(从右到左)

    flex-direction:column-reverse;(从下到上)

  • 折行

    flex-warp: nowrap;(默认不折行,会挤在一起,导致宽度变窄)

    flex-wrap:wrap;(折行,宽度不够会折行)

    flex-wrap:wrap;(从下往上折行,一般没啥用)

主轴对其方式

  • 默认主轴是横轴,除非改变了flex-direction的方向(前四个比较重要)

image.png

次轴对齐方式

image.png

  • 默认次轴是纵轴

多行内容

  • 基本不用

image.png

flex item样式

顺序

  • 在item上加order,可以改变item的顺序(从小到大,可以有负)

长胖

  • 在item上加flex-grow,可以改变各个item的宽度(在不加宽度的情况下,默认为等宽且尽可能窄)

image.png

变瘦

  • 一般写flex-shrink:0; 防止变瘦,默认为1(谁的数大谁贡献的多)

基准宽度

  • flex-basis控制基准宽度,默认是auto(暂时是不知道干嘛的)Question 缩写

  • flex:flex-grow flex-shrink flex-basis;(有shrink的时候必须加宽度)

一个有宽度的值会被当作flex-basis

定制

  • align-self定制align-items 例如:某个元素单独align-self:flex-end;(该元素单独居下)

image.png

重点:

  • display:flex;
  • flex-direction:row / column;
  • flex-wrap:wrap / nowrap;
  • just-content: center / space-between;
  • align-items:center;

经验

  • 永远不要把width和height写死,除非特殊情况

  • 用min-width / max-width / min-height / max-height

  • flex可以基本满足所有需求

  • flex和margin-left / right:auto配合有意外效果

  • 写死

  • width:100px;
    
  • 不写死 (特点:不使用px,或者min max前缀)

  • width:50%;
    
  • max-width:100px
    
  • width:30vw;
    
  • min-width:80%
    

Tips:

  • 如果发现图片下面有多余的部分(奇怪的空隙)就在css里面加上一行: vertical-align:middle/top;
  • 如果border调试的时候影响了,就把border改成outline
  • (布局谨记:浮动浮动、clearfix)

Grid布局

grid也分container和items

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

container

可以划分大小

.container {
    display: grid;
    grid-template-columns50px 100px auto 100px 50px;
    grid-template-rows50px 100px 50px;
}

分别以线分为第几行列

image.png

item

语法如上图所示(n表示第几根线)

.item-a { grid-row-start:n;
grid-row-end:n;
grid-column-start:n;
grid-column-end:n;
}

fr

free space

.container {
    display: grid;
    /* outline: solid 1px black; */
    background-color: skyblue;
    grid-template-columns1fr 1fr 1fr;
    grid-template-rows1fr 1fr;
    width600px;
    grid-column-gap13px;
    grid-row-gap13px;
}
img {
    outline: red 1px solid;
    height191px;
    width191px;
}

效果如图 image.png

空隙gap

  • grid-column-gap:10px;
  • grid-row-gap:15px; 空隙gap效果图 image.png

分区grid-template-areas

空隙gap设置同上

分区grid-template-areas代码 image.png 分区grid-template-areas效果图 image.png

CSS定位

布局和定位有啥区别

  • 布局是屏幕平面上的
  • 定位是垂直于屏幕的
  • 背景的范围:border外边沿围成的区域

position的五个取值

position

  • static ——待在文档流里,默认值
  • relative ——相对定位,升起来,但不脱离文档流
  • absolute ——绝对定位,定位基准是祖先里的非static(不一定是relative)
  • fixed ——固定定位,定位基准是viewport视口(有诈——transform) sticky ——粘滞定位,不好描述

经验:

  • 如果写了absolute,一般都会补一个relative
  • 如果写了absolute或fixed,一定要补top和left
  • sticky兼容性很差,主要用于装逼

position: relative;

使用场景

  • 用于做位移(很少用)
  • 用于给absolute元素做父亲(比如子绝父相) 配合z-index
  • z-index:auto默认值,不创建新层叠上下文
  • z-index:0/1/2
  • z-index:-1/-2

position: absolute;

使用场景

  • 脱离原来的位置,另起一层,比如对话框的关闭按钮
  • 鼠标提示 配合z-index 经验
  • absolute不是相对于relative定位的,而是相对于最近的一个非static的祖先元素
  • 某些浏览器如果不写top/left会位置混乱
  • 善用left:100%;
  • 善用left:50% 加 负margin值;

position: fixed;

使用场景

  • 小广告(因为相对于视口,所以划不掉)
  • 回到顶部 配合z-index 经验
  • 手机上尽量不要用这个属性,坑很多;不信可以搜索 移动端fixed
  • transform: scaleZ(1); ——不要和transform一起用,会出问题

position: sticky;

使用场景

  • 导航栏
  • 页封 (看得见时随页面滑动,本应该看不见时,固定在页面的某个位置) 经验
  • 兼容性极差
  • 不要使用,会变得不幸

Tips:

  • white-space:nowrap; ——文字内容不转行
  • button span{ display:none;} ——默认不显示
  • button: hover span{ display:inline-block;} ——搭配上一句:光标提示
  • left: 50%; transform: translateX(-50%); ——会自动居中(后面有)

层叠上下文

  • 每个层叠上下文独立成一个作用域
  • 单个作用域里的index-z与外界无关
  • 处于同一作用域的index-z才能比较

哪些不正交的属性可以创建层叠上下文

  • MDN文档有写
  • 速记: z-index / flex / opacity(<1) / transform
  • 不用太花时间记

例:

  • a、b在html里,而a1在a里,b1在b里
  • 当a index-z:0;a1 index-z:10; b1 index-z:8;最后是b>a1。 因为b是和作用域a里的a1比(相当于8和0比)
  • 当a1 index-z:10; b1 index-z:8; 最后是b<a1。 因为b是直接和a1比

Tips:

如果a在一个层叠上下文b的作用域内, 就算a z-index:-1;也不会跑到背景下面去

CSS动画

动画的原理

定义 许多静止的画面(帧) 以一定速度(如每秒30张)连续播放时 肉眼视觉残像产生错觉 而误以为是活动的画面
概念 帧:每个静止的画面都叫做帧 播放速度:每秒24帧

用left做动画

举例 将div从左移动到右

原理 每过一段时间 将div移动一段距离 直到移动到目标地点

注意性能

  • 绿色表示重新渲染(repaint)了
  • CSS渲染过程以此包含布局、绘制、合成
  • 其中布局和绘制有可能被省略 注:用setInternet做到 F12——Esc——rendering——Paint flashing

例:

<div id="demo">动画</div>
#demo {
    width100px;     
    height100px;     
    border1px solid red;     
    backgroundrgba(255000.322);     
    position: relative;     
    left0; 
    }
var n = 1 
var id = setInterval(() => {       //定时器     
    if (n <= 800) {         
        demo.style.left = n + "px" //一定要加px,不然无反应         
        n = n + 1     
    }     
    else {         
        clearInterval(id)          //当>800px运动,否则清除定时     
    } 
}, 1000 / 120)

用transform做动画

高手不用left做动画

原理

  • transform:translateX(0=>300px)
  • 直接修改会被合成,需要等一会修改
  • transition过渡性可以自动脑补中间帧 注意性能
  • 并没有repaint,只在开始和结束repaint(重新绘制)
  • 比left性能好

image.png

渲染

参考文章

浏览器渲染过程

步骤

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

如何更新样式

一般用JS更新样式,如下

  • div.style.background='red' 	
    
  • div.style.display='none' 	
    
  • div.classList.add('red') 
    
  • div.remove()直接删掉节点
    

这些方式有何不同

image.png

三种更新方式

第一种,全走

  • div.remove()会触发当前消失,其他元素relayout 第二种,跳过layout
  • 改变背景颜色,直接跳过repaint+composite 第三种,跳过layout和paint
  • 改变transform,只需composite 注意必须全屏查看效果,在iframe里看有问题 优化 参考Google文章

transform

transform 四个常用功能

  • 位移translate
  • 缩放scale
  • 旋转rotate
  • 倾斜skew 经验
  • 一般都需要配合transition过渡
  • inline元素不支持transform,需要先变成block

transition

transitation过渡

作用 补充中间帧(比如鼠标移进移出)

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

  • transition:left 200ms linear
  • 可以用逗号分隔两个不同属性
  • 可以用all代表所有属性
  • transition:all 200ms
  • 过渡方式有:linear(线性) l ease(非线性)丨ease-in(淡入)丨ease-out(淡出) | ease-in-out(淡入淡出) | cubic-bezier l step-star | step-end丨steps,具体含义靠数学知识

中间点

  1. 使用两次transform
  • .a === transform ===> .b
  • .b === transform ===> .c
  • 可以用setTimeout或监听transition事件
  1. 使用animation
  • 声明关键帧
  • 添加动画

Tips:

  • 不是所有属性都能过渡
  • display:none => block 就无法过渡(看不见到看见无法直接过渡,只会突然出现)
  • 一般可以用visibility:hidden => visible
  • background颜色可以过渡
  • opacity透明度可以过渡

display: none;与 visibility: hidden;的区别

  • 是否继承 display不是继承属性;visibility是继承属性,后代元素存在visibility则不继承,不存在则继承。
  • 是否占据空间 display:none;在文档渲染时,元素如同不存在;visibility:hidden;空间会被空白占位。
  • 是否重新渲染(页面相关属性值被修改后) display:none;不渲染; visibility:hidden;渲染。