# span 标签设置 inline-block 后加 width 和 height 能起作用么,加 padding 和 margin 呢
# visible、display:none、opacity 之间的区别
两者都能把网页上某个元素隐藏起来,但两者有区别:
# display: none
- DOM 结构:浏览器不会渲染 display 属性为 none 的元素,不占据空间;
- 事件监听:无法进行 DOM 事件监听;
- 性能:动态改变此属性时会引起重排,性能较差;
- 继承:不会被子元素继承,毕竟子类也不会被渲染;
- transition:transition 不支持 display。
# visibility: hidden
- DOM 结构:元素被隐藏,但是会被渲染不会消失,占据空间;
- 事件监听:无法进行 DOM 事件监听;
- 性 能:动态改变此属性时会引起重绘,性能较高;
- 继 承:会被子元素继承,子元素可以通过设置 visibility: visible; 来取消隐藏;
- transition:visibility 会立即显示,隐藏时会延时
# opacity: 0
- DOM 结构:透明度为 100%,元素隐藏,占据空间;
- 事件监听:可以进行 DOM 事件监听;
- 性 能:提升为合成层,不会触发重绘,性能较高;
- 继 承:会被子元素继承,且,子元素并不能通过 opacity: 1 来取消隐藏;
- transition:opacity 可以延时显示和隐藏
# 盒子模型
# flex 以及如何实现响应式布局
# 清除浮动
# 垂直居中布局
# css 动画
# css 选择器
# 选择器语法
# 简单选择器
星号 —— *
- 通用选择器,可以选择任何的元素
类型选择器|type selector —— div svg|a
也叫做 type selector, 也就是说它选择的是元素中的 tagName (标签名) 属性
tagName 也是我们平常最常用的的选择器
但是因为 HTML 也是有命名空间的,它主要有三个:HTML、SVG、MathML
如果我们想选 SVG 或者 MathML 里面特定的元素,我们就必须要用到单竖线 | ,CSS选择器里面单竖线是一个命名空间的分隔符,而HTML 里面命名空间分隔符是 冒号 : 。然后前面说到的命名空间是需要 @namespace 来声明的,他们是配合使用的,但是这个命名空间的使用不是很频繁,它的存在只是为了一个完备性考虑,HTML 和 SVG当中唯一一个重叠的元素名就只有一个 a
所以我们可以认为,类型选择器就是一个简单的文本字符串即可
类选择器|class selector —— .class-name
- 以 . 开头的选择器就是 class 选择器,也是最经典之一
- 它会选择一个 class,我们也可以用空格做分隔符来制定多个 class 的
- 这个 .class 只要匹配中其中一个就可以了
ID 选择器|id selector —— #id
- 以 # 开头加上 ID 名选中一个 ID
- 这个是严格匹配的
- ID 里面是可以加减号或者是其他符号的
属性选择器|attribute selector ——
[attr=value]
- 它包括了 class 属性选择器和 id 选择器
- 这个选择器的完整语法就是 attr=value,等于前面是属性名,后面是属性值
- 这里面的等号前面可以加 ~ 就表示像 class 一样,可以支持拿空格分隔的值的序列:attr~=value
- 如果在等号前面加单竖线,表示这个属性以这个值开头即可:attr|=value
- 如果我们对优先级没有特殊要求的话,我们理论上是可以用属性选择器来代替 class 选择器和 id 选择器的
伪类 —— :hover
- 以 : 开头的,它主要是一些属性的特殊状态
- 这个跟我们写的 HTML 没有关系,多半来自于交互和效果
- 一些伪类选择器是带有函数的伪类选择器,这些我们都是可以去使用伪类来解决的
伪元素选择器 —— ::before
- 一般来说是以 :: 双冒号开头的
- 实际上是支持使用单冒号的,但是我们提倡双冒号这个写法
- 因为我们可以一眼就看出这个是伪元素选择器,和伪类区分开来
- 伪元素属于选中一些原本不存在的元素
- 如果我们不选择它们,这个地方就不存在这个元素了,选择后就会多了一个元素
# 复合选择器
- <简单选择器><简单选择器><简单选择器>
*
或则 div 必须写在最前面
首先复合选择器是以多个简单选择器构成的,只要把简单选择器挨着写就变成一个复合选择器了。它的语义就是我们选中的元素必须同时 match 几个简单选择器,形成了 “与” 的关系。
# 复杂选择器
复合选择器中间用连接符就可以变成复杂选择器了,复杂选择器是针对一个元素的结构来进行选择的。
- <复合选择器> <复合选择器> —— 子孙选择器,单个元素必须要有空格左边的一个父级节点或者祖先节点
- 复合选择器> ">" <复合选择器> —— 父子选择器,必须是元素直接的上级父元素
- <复合选择器> "~" <复合选择器> —— 邻接关系选择器
- <复合选择器> "+" <复合选择器> —— 邻接关系选择器
- <复合选择器> "||" <复合选择器> —— 双竖线是 Selector Level 4 才有的,当我们做表格的时候可以选中每一个列
# 选择器优先级
- 在属性后面使用 !important 会覆盖页面内任何位置定义的元素样式。
- 作为 style 属性写在元素内的样式
- id 选择器
- 类选择器 (例如,.example),属性选择器(例如,
[type="radio"]
)和伪类(例如,:hover) - 类型选择器(例如,h1)和伪元素(例如,::before)
- 通配符选择器
- 浏览器自定义或继承
优先级是由 A 、B、C、D 的值来决定的,其中它们的值计算规则如下:
- 如果存在内联样式,那么 A = 1, 否则 A = 0;
- B 的值等于 ID选择器 出现的次数;
- C 的值等于 类选择器 和 属性选择器 和 伪类 出现的总次数;
- D 的值等于 标签选择器 和 伪元素 出现的总次数 。
这样子直接看好像也还是很明白 ,那先上个例子:
#nav-global > ul > li > a.nav-link
套用上面的算法,依次求出 A B C D 的值:
- 因为没有内联样式 ,所以 A = 0;
- ID选择器总共出现了1次, B = 1;
- 类选择器出现了1次, 属性选择器出现了0次,伪类选择器出现0次,所以 C = (1 + 0 + 0) = 1;
- 标签选择器出现了3次, 伪元素出现了0次,所以 D = (3 + 0) = 3;
上面算出的 A 、B、C、D 可以简记作:(0, 1, 1, 3)。
比较规则是: 从左往右依次进行比较 ,较大者胜出,如果相等,则继续往右移动一位进行比较 。如果4位全部相等,则后面的会覆盖前面的
参考:https://juejin.cn/post/6873672592947937294
# 重绘和重排
DOM 的修改会导致重绘和重排。
- 重绘是指一些样式的修改,元素的位置和大小都没有改变;
- 重排是指元素的位置或尺寸发生了变化,浏览器需要重新计算渲染树,而新的渲染树建立后,浏览器会重新绘制受影响的元素;
- 重排一定会导致重绘;
页面重绘的速度要比页面重排的速度快,在页面交互中要尽量避免页面的重排操作。浏览器不会在 js 执行的时候更新 DOM,而是会把这些DOM 操作存放在一个队列中,在 js 执行完之后按顺序一次性执行完毕,因此在 js 执行过程中用户一直在被阻塞。
# 导致页面重排的一些操作
- 内容改变
- 文本改变或图片尺寸改变
- DOM 元素的几何属性的变化
- 例如改变 DOM 元素的宽高值时,原渲染树中的相关节点会失效,浏览器会根据变化后的 DOM 重新排建渲染树中的相关节点。如果父节点的几何属性变化时,还会使其子节点及后续兄弟节点重新计算位置等,造成一系列的重排。
- DOM 树的结构变化
- 添加 DOM 节点、修改 DOM 节点位置及删除某个节点都是对 DOM 树的更改,会造成页面的重排。浏览器布局是从上到下的过程,修改当前元素不会对其前边已经遍历过的元素造成影响,但是如果在所有的节点前添加一个新的元素,则后续的所有元素都要进行重排。
- 获取某些属性
- 除了渲染树的直接变化,当获取一些属性值时,浏览器为取得正确的值也会发生重排,这些属性包括:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle()。
- 浏览器窗口尺寸改变
- 窗口尺寸的改变会影响整个网页内元素的尺寸的改变,即 DOM 元素的集合属性变化,因此会造成重排。
# 导致页面重绘的操作
- 应用新的样式或者修改任何影响元素外观的属性
- 只改变了元素的样式,并未改变元素大小、位置,此时只涉及到重绘操作。
- 重排一定会导致重绘
- 一个元素的重排一定会影响到渲染树的变化,因此也一定会涉及到页面的重绘。
# 浏览器分析
主要是通过浏览器的 timeline 记录来分析重拍以及重绘;
timeline 分析:
- FPS:最上面一栏为绿色柱形为帧率(FPS),顶点值为 60fps,上方红色方块表示长帧,这些长帧被 Chrome 称为 jank (卡顿)。
- CPU:第二栏为 CPU,蓝色表示 loading(网络通信和 HTML 解析),黄色表示 scripting(js执行时间),紫色表示 rendering(样式计算和布局,即重排), 绿色为 painting(即重绘)。
更多timeline使用方法可参考:https://www.jianshu.com/p/4da0f0bda768
# css 有哪些属性是可以继承的
- color(颜色,a元素除外)
- direction(方向)
- font(字体)
- font-family(字体系列)
- font-size(字体大小)
- font-style(用于设置斜体)
- font-variant(用于设置小型大写字母)
- font-weight(用于设置粗体)
- letter-spacing(字母间距)
- line-height(行高)
- text-align(用于设置对齐方式)
- text-indent(用于设置首航缩进)
- text-transform(用于修改大小写)
- visibility(可见性)
- white-space(用于指定如何处理空格)
- word-spacing(字间距)
- 列表
- list-style(列表样式)
- list-style-image(用于为列表指定定制的标记)
- list-style-position(用于确定列表标记的位置)
- list-style-type(用于设置列表的标记)
- 表格
- border-collapse(用于控制表格相邻单元格的边框是否合并为单一边框)
- border-spacing(用于指定表格边框之间的空隙大小)
- caption-side(用于设置表格标题的位置)
- empty-cells(用于设置是否显示表格中的空单元格)
- 页面设置(对于印刷物)
- orphans(用于设置当元素内部发生分页时在页面底部需要保留的最少行数)
- page-break-inside(用于设置元素内部的分页方式)
- widows(用于设置当元素内部发生分也是在页面顶部需要保留的最少行数)
- 其他
- cursor(鼠标指针)
- quotes(用于指定引号样式)