Containing Block

 

Containing Block

hanlray@gmail.com
Reversion:1.0 Date:2006/08/19

稍微复习一下CSS的Visual Formatting Model:display property控制着box的产生,none值不产生box,block等值使element产生一个block box,inline等值使elment产生一个或多个inline box;normal flow里的每个box都参与一个formatting context,具有相同containing block的boxes参与同一个formatting context,block boxes参与block formatting context,inline boxes参与inline formatting context;在一个block formatting context里,boxes(block boxes)从containing block的顶部开始,一个接一个垂直排列,在一个inline formatting context里,boxes(inline boxes)从containing block的顶部开始,一个接一个水平排列。

一个element的containing block是该element产生的box(es)在计算位置和大小时参考的一个矩形。通常在一个html(xhtml)文档中,大多数element的containing block都由一个block box来担当,为该block box的content area,因此我们常直接说这些element的containing block是某个block box,实际指的是该block box的content area。不过并不是所有element的containing block都是由一个containing block来担当的,比如root element的containg block,对continous media来说是anchor在canvas的原点、大小是viewport的矩形,对page media来说是page box的page area,大小也是viewport。一个block box为其descendant boxes建立了一个containing block,对其normal flow里的boxes建立了一个formatting context,该containing block包含的boxes按照这个formatting context的规则进行布局。

如果把一个element的containing block简单地理解为该element的parent element产生的box,在某些情况下你将无法解释浏览器的布局行为,下面是CSS 2.1 Specification上的一个例子:

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>

      <meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
      <title></title>
      <script type="text/css">
      body {
      display: inline;
      }
      </script>
    </head>

  
    <body>
      This is anonymous text before the p.
      <p>This is the content of p.</p>
      This is anonymous text after the p.
    </body>
  </html>

这里用CSS把body变成了一个inline-level element,但p仍然是一个block-level element,这样body就被p打断而产生两个inline box,分别对应第一句话和第三句话,这时p产生的block box应该以哪个矩形为参考进行放置呢?无论选择第一个inline box或第二个inline box,还是由这两个inline box计算出的矩形,都无法解释其在一个符合CSS2.1的浏览器上的表现。事实上,这里p的containing block由html产生的block box来担当的,其产生的block box应该以html产生的block box的content area为参考进行放置,因为CSS2.1是这么说的:对root element以外的element,如果该element的position为relative或static,其containg block是离该element最近的、block-level或table cell或inline-block的ancestor box的content area。有了这个认识,再来解释这段代码在浏览器上的表现:p的containing block是html产生的block box,因此紧挨页面的左边缘,body产生的两个inline box的containg block也是html的box,但是由于一个containing box只能包含一种box,要么全是block boxes,要么全是inline boxes,因此会产生两个匿名block box,分别包着这两个inline boxes,这样这三个block box都参与到一个block formatting context中,从containing box的顶部,按照文档中出现的次序,从上到下垂直排列;由于在html的default style sheet里,body的margin值为8pt,这个margin应用到两个inline box上,从而使第一句话和第三句话离页面左边缘有了一段8pt的距离。

在default style sheet下,试图仅仅通过把一个block-level element变成inline-level element来把该element的box(es)放置在其上一个element的box的右边,必须满足两个条件: 1.和该element属于同一个containing block的element必须都是inline-level的,否则inline-level element产生的inline box(es)都将被包在一个匿名block box里,从而垂直排列 2.该element的子女也必须是inline-level的,原因上面已经解释过了。

### CSS Containing Block 定义 Containing block 是用于确定定位方案中的坐标系以及尺寸参照的对象。对于不同类型的定位,containing block 的定义有所不同: - 对于普通流中的块级盒子或行内盒子,如果该元素不是根元素,则其 containing block 由包含它的块的内容边框(content edge)建立[^1]。 - 当 `position` 属性设置为 `absolute` 或者 `fixed` 时,containing block 可能会变化。对于绝对定位的元素而言,containing block 是最近的已定位祖先元素(即设置了 `position` 不为 `static` 的祖先),如果没有这样的祖先则取初始包含块(initial containing block, ICB)。而对于固定定位元素来说,containing block 总是指向视窗(viewport)][^[^23]。 ### 解决与 Containing Block 相关的 CSS 布局问题实例 假设有一个需求是要创建一个侧边栏,在页面滚动过程中始终保持可见状态,但是又希望这个侧边栏能够跟随某个特定容器移动而不是整个窗口。此时可以利用 sticky 和 relative positioning 来实现这一效果而不必依赖 JavaScript 编程逻辑。 ```css /* 设置外层容器 */ .container { width: 80%; margin-left: auto; margin-right: auto; } /* 给定内部项目相对定位使其成为潜在的 containing block */ .inner-container { position: relative; } /* 应用粘性定位给目标元素 */ .sidebar { position: -webkit-sticky; /* Safari */ position: sticky; top: 1em; /* 设定顶部偏移量 */ } ``` 上述代码片段展示了如何通过调整 HTML 结构并适当应用 CSS 样式来控制元素的行为,从而达到预期的效果。这里的关键在于理解各个定位模式下 containing block 的作用范围及其影响因素。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值