跳到主要内容

基础概念✅

什么是CSS盒模型?

答案

CSS盒模型用于描述文档树中元素生成的矩形框,并根据视觉格式化模型进行布局。它定义了每个元素的内容区、内边距、边框和外边距,决定了页面元素的实际显示和排列方式。 盒模型的结构如下

  1. 内容盒(Content Box)
    • 包含元素的实际内容,如文本或图像。
    • 通过 widthheight 等属性设置。
  2. 内边距(Padding Box)
    • 包围内容盒的空间,用于增加内容与边框之间的距离。
    • 通过 padding 等属性设置。
  3. 边框(Border Box)
    • 包围内边距盒的线条,用于定义元素的边界。
    • 通过 border 等属性设置。
  4. 外边距(Margin Box)
    • 包围边框盒的空间,用于增加元素与其他元素之间的距离。
    • 通过 margin 等属性设置。
提示

参考 google css 盒模型讲解 初学者可以把盒模型理解为相框。

  1. 内容盒就是照片本身
  2. 内边距盒 照片+相框之间的空间
  3. 边框盒就是整个相框
  4. 外边距盒就是相框+其他物体之间的空间

这种关联方式就能更好地理解为什么边距可以合并,outline 不会影响盒模型的大小等概念。

可以通过 box-sizing 属性来控制盒模型的计算方式。

  1. content-box(默认):widthheight 只包含内容区域。

  2. border-boxwidthheight 包含内容、内边距和边框。一般推荐使用这种方式,行为更可控,在代理样式重置中,会采用如下方式重置

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

延伸阅读

什么是视觉格式化模型(View formatting model) ?

答案

视觉格式化模型(View formatting model) 定义了用户代理(一般为浏览器)如何在可视化设备(电脑、手机、打印机等)上渲染文档树。简单理解可以认为,盒模型定义单个元素的渲染行为,视觉格式化模型则定义了整个文档树如何铺排和渲染的机制。核心概念包括

  1. 通过 display 属性控制盒模型的生成常见的盒类型包括
    1. display:block 块级盒,垂直堆叠铺排
    2. display:inline 内联盒,水平堆叠铺排
    3. display:inline-block 内容区按照块级盒处理,自身按照内联盒铺排
    4. display:flex flex 铺排
    5. display: grid 网格铺排
    6. display:table
    7. 匿名盒(anonymous block),用户代理在铺排的时候会生成匿名盒包含块级、内联两种,比如没有标签包裹的文字会生成内联匿名盒等,具体规则详见 匿名块级盒匿名行内盒
  2. 格式化模型存在三种定位策略(position schemes) 控制元素如何铺排
    1. 正常流(Normal Flow)
      1. 块级格式化上下文(Block formatting context BFC) 内容垂直堆叠,同一个块级上下文内部的垂直 margin 会出现合并
      2. 内联格式化上下文(Inline formatting context IFC) 内容水平堆叠, 注意铺排方式还和 writing-mode 属性相关
      3. 相对定位(Relative positioning) 内容会在正常流布局的基础上发生偏移,但是原始盒模型不会改动,所以可能出现显示重叠现象
    2. 浮动布局(Float) 元素会相对正常流对应的包含块边缘对齐
    3. 绝对定位(Absolute position) 元素会脱离正常流,相对关联的包含块对齐

延伸阅读

什么是 BFC 有哪些作用?

答案

块级格式化上下文(Block formatting context BFC) 是属于格式化模型(View formatting model) 中,正常流布局(Normal flow)的一种。

BFC 的核心特性

  1. 包含浮动元素:BFC 会包含其内部的所有浮动元素,解决高度塌陷问题
  2. 阻止外边距合并:BFC 内的外边距不会与外部元素的外边距合并
  3. 阻止文字环绕:BFC 会阻止浮动元素与 BFC 内的文字重叠
  4. 独立布局:BFC 内的元素布局不受外部影响

对于块级格式上下文内布局规则如下

  • 盒子从块级格式化上下文的顶层包含块从上到下垂直堆叠
  • 对于相邻的盒子,垂直 margin 会出现折叠
  • 块级格式化上下文的盒子会相对包含块左对齐(注意对于 direction: rtl 则右对齐)

如下方式会产生块级格式化上下文:

  1. 文档的根元素(<html>
  2. display: flow-root 的元素(推荐使用)
  3. 浮动元素(float 属性不为 none 的元素)
  4. 绝对定位元素(position 属性为 absolutefixed 的元素)
  5. 行内块元素(display: inline-block 的元素)
  6. 表格单元格(display: table-cell 的元素,HTML 表格单元格默认如此)
  7. 表格标题(display: table-caption 的元素,HTML 表格标题默认如此)
  8. display: tabletable-rowtable-row-grouptable-header-grouptable-footer-groupinline-table 的元素隐式创建的匿名表格单元格
  9. overflow 属性值不是 visibleclip 的块级元素
  10. <button> 元素和默认 display: flow-root 的按钮类型 <input> 元素
  11. contain 属性为 layoutcontentpaint 的元素
  12. 弹性盒子项目(display: flexinline-flex 的直接子元素)
  13. 网格项目(display: gridinline-grid 的直接子元素)
  14. 多列容器(column-countcolumn-width 不为 auto 的元素)
  15. column-span: all 的元素

示例说明

<style>
  .box {
    background-color: #f0f0f0;
    padding: 10px;
  }

  .float-box {
    float: left;
    border: 1px solid #000;
  }

  input[type="checkbox"]:checked ~ .box {
    display: flow-root;
  }
</style>
<div class="container">
  清除浮动
  <input type="checkbox" />
  <div class="box">
    <div class="float-box">浮动元素</div>
  </div>
</div>

延伸阅读

什么是 IFC ,和 BFC 有哪些区别?

答案

内联格式化上下文(Inline Formatting Context IFC) 是视觉格式化模型中的一种布局模式,用于处理内联元素的排列。与 BFC 不同,IFC 主要处理水平方向的布局。

IFC 的核心特性:

  1. 水平排列:IFC 内的元素按照水平方向从左到右排列(在 LTR 语言环境下)
  2. 基线对齐:内联元素默认按照基线对齐,可以通过 vertical-align 属性调整
  3. 行框(Line Box):IFC 会创建行框来包含每一行的内联元素
  4. 自动换行:当内容超出容器宽度时,会自动换行创建新的行框

IFC 的布局规则:

  • 内联元素在 IFC 中水平排列,从包含块的顶部开始
  • 行框的高度由该行内最高元素的高度决定
  • 内联元素的垂直对齐通过 vertical-align 属性控制
  • 当内联元素包含块级元素时,会创建匿名块级盒

IFC 与 BFC 的主要是 IFC 主要用于文本内容的排版,如段落、标题等。 BFC 用于块级布局。

示例说明

<style>
  .container {
    border: 1px solid #ccc;
    padding: 10px;
    margin: 10px 0;
    width: 300px;
  }
  
  .normal-text {
    font-size: 16px;
    background: lightblue;
  }
  
  .tall-text {
    font-size: 32px;
    background: lightgreen;
    line-height: 1.2;
  }
  
  .image {
    width: 50px;
    height: 50px;
    background: lightcoral;
    display: inline-block;
    vertical-align: middle;
  }
  
  .highlight {
    background: yellow;
    padding: 2px;
  }
</style>

行框高度由最高元素决定:
<div class="container">
  <span class="normal-text">普通文本</span>
  <span class="tall-text">高文本</span>
  <span class="normal-text">普通文本</span>
</div>

包含图片的行框:
<div class="container">
  <span class="normal-text">文本内容</span>
  <div class="image"></div>
  <span class="normal-text">更多文本</span>
</div>

多行文本的行框:
<div class="container">
  <span class="normal-text">第一行文本</span>
  <span class="tall-text">第二行高文本</span>
  <span class="normal-text">第三行文本</span>
  <span class="highlight">高亮文本</span>
</div>

延伸阅读

什么是 Cascade?

答案

层叠(cascade) 用来处理一个元素的 css 属性上匹配多条规则时,如何计算最终的属性值。这最终通过层叠计算出来的属性值叫做层叠值(cascaded value)

核心规则如下

  1. 默认顺序,从低到高
    1. 用户代理设置的默认样式
    2. 用户设置的默认样式,通过插件或者配置实现
    3. @layer 规则
    4. 开发者设置的样式
      1. 内联样式 > ID 选择器 > 类属性选择器 > 标签选择器 > 通配符
      2. 选择器优先级相同,则后面的样式覆盖前面的
  2. 如果设置了 !important 会导致优先级权重提升,但是和默认顺序相反即从低到高依次为
    1. !important 开发者设置样式
    2. !important @layer 规则
    3. !important 用户设置样式
    4. !important 代理设置样式

延伸阅读

什么是层叠上下文(Stacking Context)?

答案

层叠上下文(Stacking Contexts) 决定了文档树中的元素在可视化设备上的叠放规则,可以类比为 PhotoShop 中图层堆叠的概念。默认层叠上下文的核心包括

  1. 正常流布局中,同级元素层叠优先级,靠后的元素高于靠前的元素,不同级的子元素层叠规则由最终同级的父元素决定。这也是为什么单纯设置某个子元素的 z-index 不生效的原因,因为同级的父元素可能层叠靠前导致无法覆盖后面的元素
  2. 对于 position 不等于 static 值的定位元素, z-index 的值越大层叠越靠上。注意对于 flex、grid 这些容器的子元素不依赖 position 限制,可以直接设置 z-index 控制层叠
  3. 如下方式会创建层叠上下文
    1. 文档根元素 <html>
    2. position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;
    3. position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
    4. flex (flex) 容器的子元素,且 z-index 值不为 auto;
    5. grid (grid) 容器的子元素,且 z-index 值不为 auto;
    6. opacity 属性值小于 1 的元素(参见 the specification for opacity);
    7. mix-blend-mode 属性值不为 normal 的元素;
    8. 以下任意属性值不为 none 的元素:
      • transform
      • filter
      • backdrop-filter
      • perspective
      • clip-path
      • mask / mask-image / mask-border
      • isolation 属性值为 isolate 的元素;
    9. will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);
    10. contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 contain: strict、contain: content)的元素。

延伸阅读

55%