常见问题
提示
- 布局谨记三个上下文:
- containing block - 位置 - 影响 paint, relayout
- stacking context - z-index
- block formatting context - flow, float
- border 不支持渐变
-webkit-user-modify
- BEM - Block Element Modifier
- by Yandex 2007
.block
-.block--mod
.block__elem
-.block__elem--mod
- 目前已不太推荐,以前全局 CSS 容易冲突,现在很容易用 css module 和控制 scope
- CSS Reference
.style {
/* 对齐数字 */
font-variant-numeric: tabular-nums;
}
border 渐变
- border 不支持渐变
- https://css-tricks.com/gradient-borders-in-css/
- wrapper - 额外元素
- border-image+border-image-slice - 不支持 radius
- https://codepen.io/AlexOverbeck/pen/axGQyv
- by wrapper
- https://codepen.io/fabianmichael/pen/yLPyRry
- by svg
- 不支持 input 因为 input 不支持
::before
pure selector
- 能够被 prefix 的 selector
- 用于 css module
/* 不是 pure selector */
:global(body) {
}
/* 是 pure selector - 会变成 .xyz body */
body {
}
浏览器兼容问题
- aspect-ratio - Chrom 88, Safari 15
- 不支持的时候可能导致 height/width 为 0
- 使用 padding hack
- @supports - Chrome 28, Safari 9
- @supports selector - Chrome 83, Safari 14.1
@supports (aspect-ratio: 1/1) {
aspect-ratio: 1/1;
}
@supports not (aspect-ratio: 1/1) {
/* 补偿 */
}
/* 检测 selector 是否支持 */
@supports selector(:nth-child(1n of a, b)) {
}
// 当前环境版本信息
navigator.userAgent;
// Chrome 61, Safari 9
CSS.supports('aspect-ratio: 1/1');
CSS.supports('aspect-ratio', '1/1');
backdrop-filter
- Chrome 76+ 正式支持,之前加前缀
- Chrome 对 backdrop filter 支持不太好
- 如果页面使用了 mix-blend 会导致 blur 有问题 #1254774
- Safari 加前缀支持 - 效果正常
- FF 尚不支持
- tailwindcss backdrop-filter 可能没有 prefix
- 使用 autoprefixer https://tailwindcss.com/docs/browser-support
- 确保 browserslist 正确
通过 before 和 after 来补偿
Optimize
- contain
- 声明包含关系,渲染不受 dom tree 影响,提效
- strict -> size layout paint
- content -> layout paint
- size
- 不依赖子节点 size
- 不遍历子节点
- 子节点变化不需要向上遍历重新布局
- 需要为元素指定大小
- 容器不会被子元素撑开
- 子元素可以被渲染到容器外
- 不依赖子节点 size
- layout
- 内外元素布局互不影响
- 例如 z-index
- style
- 样式隔离 - 例如 counter-increment, counter-set
- 该规范 可能会 被移除
- paint
- 内容不会渲染到容器之外 - 类似 overflow: hidden
- 影响上下文
- 新的 containing block - position = absolute/fixed
- 新的 stacking context
- 新的 block formatting context
- 参考
- content-visibility - 配合 contain 使用
- visible
- hidden
- 隐藏,但保留渲染状态
- display: none - 销毁渲染状态,再次显示重新渲染
- visibility: hidden - 会保留在 DOM
- 例如 用于多窗口 SPA,隐藏窗口用,再次显示不需要从新渲染
- auto
- 简单易用
- 允许 user-agent 操作,例如 find-in-page, tab order navigation
- contain 为 layout, style, paint
- contain-intrinsic-size - 控制看不见时的 size
- 参考
- Chrome 85+
- https://web.dev/content-visibility/
- will-change
- 当真的有性能问题时在用
- background-color 为透明时影响 scroll 性能 - 因为需要计算后面
- 参考
- DevTool Rendering 面板支持显示 Layer borders
- https://csstriggers.com/
- What forces layout / reflow
- 尽可能减少浏览器重排
visibility vs display
Containing Block
- Containing Block 组成
- Content area
- Padding area
- Border area
- Margin area
- 基于 Containing Block 计算的属性
- 百分比 width, height, padding, margin
- 位置偏移 - 当 position 为 absolute 或 fixed 时
- html 为 initial containing block
- 形成 Containing Block 的场景
- 受 positon 影响
- position 为 absolute 或 fixed
stacking context
- The stacking context
- 影响 z-index
- 形成场景
- position = absolute or relative 且 z-index != auto
- position = fixed or sticky
- child of flex 且 z-index != auto
- child of grid 且 z-index != auto
- opacity < 1
- mix-blend-mode != normal
- isolate
- contain = layout or paint
- Compositing and Blending Level 2
- isolation
- 强制创建 stacking context
- 用于配合 mix-blend
- isolation
避免 z-index 混淆
- 建立新的 z-index 栈 - isolation: isolate
block formatting context
- Block formatting context
- 影响 float, flow 布局
- 形成场景
- float != none
- position = absolute or relative
- display: inline-block
- display: table-cell
- display: table-caption
- overflow != visible or clip
- contain: layout, content, or paint
- flex items
- grid items
Layout mode
- Layout mode
- Normal flow
- Table
- Positioned
- Multi-column - 内容多列 - 类似 报纸
- Flexible
- Grid
Boxing
Box type | Composition |
---|---|
Margin box | margin + border + padding + content |
Border box | border + padding + content |
Padding box | padding + content |
Content box | content |
inline vs block
影响 Layout
- inline
- 只能影响 tag 内 - 例如没有 margin
- 不会影响 layout flow - 不换行
- 只能包含 数据 和 inline 元素
- block
- 通常开启新行
- 可包含 inline 和 block
元素直接支持 resize
.container {
overflow: hidden; /* required by resize:both */
resize: both;
}
overflow + absolute
- https://stackoverflow.com/a/5513717/1870054
- https://front-back.com/how-to-make-absolute-positioned-elements-overlap-their-overflow-hidden-parent/
重置元素所有属性
.container {
/* 重置除了 unicode-bidi 和 direction 之外的所有属性 */
all: initial;
}
只有键盘控制时才添加焦点外边框,鼠标点击无外边框
- :focus-visible - 键盘控制产生的 focus
button:not(:focus-visible) {
outline: none;
}
子节点有焦点时父节点添加样式
- :focus-within
匹配空节点
- :empty
避免 flex 容器溢出
- 添加 min-width: 0
- Why
- 默认
min-width: auto
允许元素占用更多空间
- 默认
播放 png 精灵图
display: table 不支持 max-height 和 overflow
- 建议使用 flex 模拟 table
- thead 和 tbody 可能不同步
overflow-x: hidden
确保两个同步
width: 100%
可能显示不完整 - 滚动出的内容背景不完整- max-content 显示完整
- 如果 width 不够会导致右侧滚动条看不到
- thead 和 tbody 可能不同步
- CSS3 display:table, overflow-y:scroll doesn't work