CSS 盒模型

最后更新: 2023-05-18 19:50:50 +0800 +0800
tags: Css | Design | Web
原文以英文撰写。您正在阅读AI翻译版本。

CSS 会将每个元素布局为一个或多个盒子。基本盒子从内到外依次包含内容、内边距、边框和外边距。只有确定声明的尺寸控制哪个边缘后,宽度计算才会变得可预测。

内容和边框尺寸 #

初始的 box-sizing 值为 content-box:

css
.card {
  box-sizing: content-box;
  width: 20rem;
  padding: 1rem;
  border: 0.25rem solid;
}

渲染后的边框盒宽度为 22.5rem:内容宽度为 20 rem,水平内边距为 2 rem,边框为 0.5 rem。

border-box 会将内边距和边框计入声明的尺寸:

css
.card {
  box-sizing: border-box;
  width: 20rem;
  padding: 1rem;
  border: 0.25rem solid;
}

内容宽度变为 17.5rem,而边框盒仍为 20 rem。border-box 对组件很有用,因为添加内边距不会使声明的百分比或固定宽度超出其分配的空间。 外边距在两种尺寸模型中都位于外部,仍可能使占用区域宽于声明的尺寸。

统一应用边框盒尺寸 #

box-sizing 默认不会被继承。使用继承式重置,可以在必要时让组件覆盖根元素的值:

css
html {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

包含伪元素很重要,因为装饰性边框和生成的内容也会创建盒子。

外边距、内边距和溢出 #

内边距属于元素,并会接收元素的背景。外边距位于边框外部,保持透明。在正常流中,块级元素之间的垂直外边距可能会发生折叠;内边距、边框、弹性布局、网格布局以及新的块格式化上下文会改变这种行为。

弹性或网格项目之间、浮动元素之间、绝对定位盒子之间,或跨越块格式化上下文边界时,外边距不会折叠。当没有边框、内边距、行内内容、清除浮动或新的格式化上下文将其分隔时,父元素与第一个或最后一个子元素的外边距可能会折叠。

百分比内边距和外边距会根据包含块的行向尺寸进行解析,在水平书写模式下,垂直内边距也遵循此规则。当间距属于布局而非单个项目时,优先在弹性和网格容器中使用 gap。

overflow 控制超出内边距盒的内容:

css
.panel {
  max-block-size: 24rem;
  overflow: auto;
}

经典滚动条会占用边框盒内部的空间。覆盖式滚动条不会占用空间,因此应避免硬编码滚动条宽度。

css
.panel {
  scrollbar-gutter: stable;
}

scrollbar-gutter 可以为经典滚动条预留空间,并防止溢出开始时发生布局偏移。对于覆盖式滚动条,它不会产生可见的滚动条槽效果。

固有尺寸和最小尺寸 #

弹性和网格项目具有自动最小尺寸,该尺寸可以根据其最小内容贡献值推导。 因此,即使轨道或弹性项目看起来具有伸缩性,较长且不可断行的令牌仍可能使布局溢出。显式允许其收缩:

css
.content {
  min-inline-size: 0;
  overflow-wrap: anywhere;
}

图像等可替换元素具有固有尺寸和宽高比。应在不造成变形的情况下约束它们:

css
img,
video {
  display: block;
  max-inline-size: 100%;
  block-size: auto;
}

逻辑属性 #

逻辑属性描述相对于书写模式的尺寸:

css
.notice {
  inline-size: min(100%, 40rem);
  padding-block: 1rem;
  padding-inline: 1.5rem;
  border-inline-start: 0.25rem solid currentColor;
}

inline-size 在水平书写模式下对应宽度,而 block-size 对应高度。逻辑属性可以在从右到左的文本和垂直书写模式下保留布局意图。

浏览器测量 API 会公开不同的边缘:clientWidth 包含内边距,offsetWidth 包含边框,而 getBoundingClientRect() 返回经过变换的边框盒。应选择与讨论中的盒子相匹配的 API,而不是使用固定常量进行补偿。

评论

在 GitHub 上阅读或评论(发表评论需要登录)