Css 知识总结
目录
文档流/盒子模型
-
文档流是指,HTM元素的流动方向。
- inline元素从左到右,到达最右边才会换行。注意:元素到达最右边后会被分割,而不会保持完整。
- block元素是从上到下,每个元素都独占一行。
- inline-block元素是从左到右,到达最右边换行,但是与上面不同的是,inline-block不会切割元素,在元素宽度不够就会换行。
-
块 , 内联, 内联块
-
<span>标签是最常见的 内联(inline)元素- 宽度 inline是不能设置宽度的,那么它的宽是有内部的inline元素的宽度的和决定的.
- 高度 inline的高度有 line-height 间接决定的,跟height的没有关系
-
<div>标签是块元素常见标签 块(block)元素- 宽度 block元素默认为 auto 宽度,很多人认为默认宽度为 100%其实不是.特别强调:不推荐把宽度设置为 100%
- 高度 div 里面什么的都没有 div height 值就是 0;
- block的高度是内部的所有文档流元素决定(inline block inline-block )
- block可以设置高度.
-
内联块 (inline-block)
- 宽度 默认的时候跟inline是一样的,单可以设置width.
- 高度 跟block的高度类似,可以设置height.
-
-
溢出 overflow
- 给div(block) 设置固定高度,内容超过这个高度,就会出现下图的情况:
- overflow语法 常见用的
-
overflow: hidden: 隐藏溢出内容
-
overflow: scroll: 显示滚动条,但问题是,如果内容宽度和高度没有溢出,也会有滚动条
-
erflow: auto: 灵活地显示滚动条,只有在需要的时候才会出现滚动条
-
-
脱离文档流
- 文档流可以比喻成一个作用域,既然脱离了脱离了文档流那么原本的位置就会被其他元素占据.
- 其实就是他们的层级不同了,一般情况你的层级会更高.css中文表述是:层叠样式表.
- 怎么可以用: float:left /(定位)position:absolute(绝对定位)/fixde(创建层叠上下文)后面会说
-
margin 合并问题(外边距重叠)
- 只会上下合并 左右不会合并
- display:inline-border 可以不合并
- MDN 参考
-
盒子模型
- css 盒子模型 是计算元素页面所在占的空间方式
- content-box "标准盒子模型/内容盒子":内容就是盒子的边界;
- 属性:width/height 只包含content,不包含别的.
- border-box "边框盒子":边框就是盒子的边界 (推荐)
- 属性:width,height包含content+padding+border
- 计算方式:
- content-box 内容区的width
- border-box 内容区的width + 两边的padding + 两边的 border
*{box-sizing:border-box}
- 基本单位
- px像素
- em font -size 的倍数 就是
布局
布局的两种思路
- 在什么情况下用那种 css布局?下图
步骤:
- 子元素上加 float:left 和 width
- 父元素加上.clearfix
- 事例:
-
<div class="clearfix">父元素</div> .clearfix::after { content:''; display:block; clear:both; }
- 经验:
- 最后一个div 不设置width或者max-width
- img 设置成 max-width
- 图片下面溢出,可以写vertical-align:top或者middle
- 有时候我们设置 border:1px solid red;或占位置干扰布局.那么可以用 outline:1px solid red; 这种不占位置
- 块级元素居中,推荐写法是:
-
.div{ margin-left:auto; margin-right:auto; /* 还有一种写法,推荐上面的分别写 不用简写*/ margin:0 auto; } - 负margin 可以做到平局布局
flex布局
- flex布局加上:display:flex; 是在父元素上加创建一个容器
- MDN参考
- container 容器 样式
- flex-direction 主轴
- ``` css
.container{
flex-direction:row|row-reverse|column|column-reverse;
}
/*
依次解释:默认样式(不会换行,只会挤压当前元素)从左到右横向排列,reverse 意识是反方向;
column是上下排列
*/
- flex-wrap 是否换行
- {flex-wrap:wrap} 换行
- reverse 反过来
- justify-content 主轴对齐
-
.container{ justify-content:flex-start|flex-end|center|space-between |space-around|space-evenly; } /* 依次解释:从左到右,从右到左,中间对齐,距离之间对齐,后面不好解释可以自己试试 */
-
- align-items 纵轴对齐方式
- flex-start 从上往下对齐....end 从下往上等
- align-content 多行内容 属性跟上面差不多效果建议自己尝试
- items
- order 可有改变显示顺序 从小到大 负数最大
- flex-grow 分配多余的空间 默认为0
- flex-shrink 默认为1 ,0为防止变小
- flex-basis 控制基准宽度 默认为auto
- align-self 单独控制一个元素改变 属性跟上面差不多
- 经验
- 除非特使要求 不然不要把width/height 写死
- 用max-width/max-width/min-height/max-height 代替width/height
- 什么叫写死? width:100px 这样叫写死,反之 width:50% max-width:100px min-width:80% 特点就是 不是用px.或者加了 min max 前缀
- 有个练习小游戏推荐: flexboxfroggy.com/#zh-cn
Grid布局
二维布局 grid 一维布局flex MDN参考
- grid也是分 container和items
-
.container { display:grid|inline-grid; grid-template-columns: 20% 20% 20% 20% 20%; grid-template-rows: 20% 20% 20% 20% 20%; }
- 事例:
-
grid小游戏可以让你熟悉他们的熟悉操作.
css 定位
- 先了解下 div分层 我们在一个div中有多个层组成的.不同的元素在不同的层级.就像千层饼正面上看是一块,看到最外面的那一层.侧边看其实有多个层组成的.
- 我们div标签也是有多个 元素层组成 最外面是内联子元素(我们的看到的文字content),浮动元素,块级子元素, border , background 背景等
- 浮动元素会脱离文档流,层级会比文档流(文档流:inline ,block ,inline-block)高一点
- 同级的会按顺序覆盖,后面的会覆盖前面的
position 属性
- 是一个CSS模块,用来定义如何将元素在页面中进行绝对定位和相对定位。
- 默然值 static 待在文档流中
- relative 相对定位,升起来浮动,但不脱离文档流
- absolute 决定定位,需要一个定位基准一般父级哪里需要搭配relative
- absolute写了 一定要有 top和left 不写会有的浏览器会位置错乱
- fixed 固定定位
- 视口定位 视口就是我们页面看的地方.比如:两侧的广告 你不管往下滑动 都会显示在两边
- sticky 粘连定位 兼容性差
- z-index 当元素之间重叠的时候, z-index 较大的元素会覆盖较小的元素在上层进行显示。
- 默认 auto 不会创建层叠上下文.
- 整数 0/1/2 数字越大层级越高 -1/-2 反之
层叠上下文
- 每个层叠上下文都是一个新的作用域
- 作用域里面的z-index跟其他的没有关系,在域里面才能比较.
- 详情可以查看 MDN
- 比较用的 z-idnex/flex/opacity/transform等
- opacity跟background 属性不同点是什么?
- opacity会影响全部元素,background只会影响背景
浏览器的渲染过程
- 根据HTML构建HTML树(DOM)
- 浏览器接收服务器的响应来HTML文档后.遍历文档节点.生成DOM树.
- 生成过程中可能会被css/js加载阻塞的.
- 根据CSS构建CSS树(CSSDOM)
- 浏览器解析CSS文件并生成CSS规则树,每个CSS文件都被分析成一个StyleSheet对象,每个对象都包含CSS规则。CSS规则对象包含对应于CSS语法的选择器和声明对象以及其他对象。
- 将这俩棵树合并成一棵树(Reder Tree)
- 浏览器将DOM和CSSDOM合并成"渲染树",收集页面上的所有DOM内容以及节点上的所有CSSDOM样式信息
- 渲染树构建完成后,每个节点都是可见节点并且都含有其内容和对应规则的样式。这也是渲染树与DOM树的最大区别所在。渲染树是用于显示,那些不可见的元素当然就不会在这棵树中出现了,譬如。除此之外,display等于none的也不会被显示在这棵树里头,但是visibility等于hidden的元素是会显示在这棵树里头的。
- Latout 布局 (文档流、盒模型、计算大小和位置)
- 布局阶段会从渲染树的根节点开始遍历,然后确定每个节点对象在页面上的确切大小与位置,布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。
- Paint 绘制 (把边框颜色、文字颜色、阴影等画出来)
- 在绘制阶段,浏览器会遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的。
- reflow(回流)
- 当浏览器发现布局发生了变化,这个时候就需要倒回去重新渲染,这个回退的过程叫reflow。reflow会从html这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置,以确认是渲染树的一部分发生变化还是整个渲染树。reflow几乎是无法避免的,因为只要用户进行交互操作,就势必会发生页面的一部分的重新渲染,且通常我们也无法预估浏览器到底会reflow哪一部分的代码,因为他们会相互影响。
- repaint(重绘)
- repaint则是当我们改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变。
- 需要注意的是,display:none会触发reflow,而visibility: hidden属性则并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框。所以visibility:hidden只会触发repaint,因为没有发生位置变化
- 另外有些情况下,比如修改了元素的样式,浏览器并不会立刻reflow或repaint一次,而是会把这样的操作积攒一批,然后做一次reflow,这又叫异步reflow或增量异步reflow。但是在有些情况下,比如resize窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行reflow。
- Compose 合成 (根据层叠关系展示画面)
- 渲染阻塞
- 当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行,然后继续构建DOM。每次去执行JavaScript脚本都会严重地阻塞DOM树的构建,如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM还没有下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建。
- 所以,script 标签的位置很重要。实际使用时,可以遵循下面两个原则:
- CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。
- JS置后:我们通常把JS代码放到页面底部,且JavaScript 应尽量少影响 DOM 的构建。
- 当解析html的时候,会把新来的元素插入dom树里面,同时去查找css,然后把对应的样式规则应用到元素上,查找样式表是按照从右到左的顺序去匹配的。
- div p {font-size: 16px},会先寻找所有p标签并判断它的父标签是否为div之后才会决定要不要采用这个样式进行渲染)。 所以,我们平时写CSS时,尽量用id和class,千万不要过渡层叠。
css 动画
transform
- MDN参考
- 属性允许你旋转,缩放,倾斜或平移给定元素。这是通过修改CSS视觉格式化模型的坐标空间来实现的。
- 注意:inline元素不支持 transform 需要改成block
语法
- 位移
- transform(
<length-percentage>,<length-percentage>) - transformX(
<length-percentage>); - translateY(
<length-percentage>); - translateZ(
<length>且父容器要有perspective属性); - translate3d(x,y,z)
- 使用 translate(-50%,-50%)配合定位来实现元素的水平垂直居中
- 缩放
- scale(
<number、>,<number>) - scaleX(
<number>) - scaleY(
<number>)
- scale(
- 旋转
- rotate3d(
<number>,<number>,<number>, [<angle>|<zero>] ) - rotateX( [
<angle>|<zero>] ) - rotateY( [
<angle>|<zero>] ) - rotateZ( [
<angle>|<zero>] )
- rotate3d(
transition 过渡
- MDN参考
- 属性是 transition-property,transition-duration,transition-timing-function 和 transition-delay 的一个简写属性。
- 补齐中间帧
语法
- transition: 属性名 时长 过渡方式 延迟
- transition: 属性可以被指定为一个或多个 CSS 属性的过渡效果,多个属性之间用逗号进行分隔。 eg transition:left 200ms, top 400ms
- 可以用all来代表所有属性
- 常用过渡方式有: linear | ease | ease-in | ease-out | ease-in-out 等
- 注意:不是所以属性都能过渡
- display:none =>block 没法过渡
- 一般改成 visibility:hidden => visible
- display和visibility 区别:简单说,display 隐藏了占据的空间消失,visibility 则不会
- background(背景) 颜色可以过渡.
- opacity 透明度可以过渡 但是不推荐
animation
-
CSS animation 属性是 animation-name,animation-duration, animation-timing-function,animation-delay,animation-iteration-count,animation-direction,animation-fill-mode 和 animation-play-state 属性的一个简写属性形式。
-
可以为动画变化的关键位置设置一定的顺序。它的规则是 @keyframes 名称 {...}
-
有两种写法,一种是 0% - 100%,中间可以创建多个百分比给元素加上动画效果。
-
@keyframes xxx { 0% { /* 动画代码 */ } 50% { /* 动画代码 */ } 100% { /* 动画代码 */ } } -
from - to,from 相当于 0%,to 相当于100%,中间正常添加百分比。
-
@keyframes xxx { from { /* 动画代码 */ } 50% { /* 动画代码 */ } to { /* 动画代码 */ } } -
事例:跳动红心
*{box-sizing: border-box;} #heart{ display: inline-block; margin: 100px; position: relative; animation: .5s heart infinite alternate-reverse; } @keyframes heart { 0%{ transform: scale(1); } 100%{ transform: scale(1.2); } } #heart>.left{ background: red; width: 50px; height: 50px; position: absolute; transform: rotate(45deg) translateX(31px); bottom: 50px; left: -50px; border-radius: 50% 0 0 50%; } #heart>.right{ background: red; width: 50px; height: 50px; border-radius: 50%; position: absolute; transform: rotate(45deg) translateY(31px); bottom: 50px; right: -50px; border-radius: 50% 50% 0 0; } #heart>.bottom{ background: red; width: 50px; height: 50px; transform: rotate(45deg); }