|
| 1 | +# CSS包含块 |
| 2 | + |
| 3 | +元素的尺寸和位置,会受它的包含块影响。对于一些属性,例如 width, height, padding, margin,当绝对定位元素(position: absolute/fixed)的偏移值为百分比值时,由元素的包含块计算得来。 |
| 4 | + |
| 5 | +包含块分两种: |
| 6 | + |
| 7 | ++ **初始包含块(initial containing block)**,即根元素(HTML元素)所在的包含块,浏览器中等于视口 viewport 大小,定位基点在画布原点(视口左上角)。 |
| 8 | + |
| 9 | ++ **非根元素包含块**,判定方式分以下规则: |
| 10 | + |
| 11 | +1. 元素 `position: relative/static`,包含块为最近的**块容器** (block container) 的**内容区域**(content area) |
| 12 | + |
| 13 | +2. 元素 `position: fixed`,包含块为视口 |
| 14 | + |
| 15 | +3. 元素 `position: absolute`,包含块为最近的 `position` 的值非 `static` (即值为 `fixed`/`absolute`/`relative`/`sticky`) 的祖先元素的内边距区域 |
| 16 | + |
| 17 | +案例: |
| 18 | + |
| 19 | +```html |
| 20 | +<body> |
| 21 | + <div class="container" style="position: relative;"> |
| 22 | + <div class="item"> |
| 23 | + <div class="item2" style="position: absolute;"></div> |
| 24 | + </div> |
| 25 | + </div> |
| 26 | +</body> |
| 27 | +``` |
| 28 | + |
| 29 | +`div.item2` 的包含块为 `div.container` 而非 `div.item`。 |
| 30 | + |
| 31 | +此外,对于非根元素,包含块还有一种规则:元素 `position: absolute/fixed`,包含块也可能为满足以下条件的最近父级元素的内边距区域: |
| 32 | + |
| 33 | +- `transform` 或 `perspective` 值不为 `none` |
| 34 | +- `will-change: transform/perspective;` |
| 35 | +- `filter` 值不为 `none` 或 `will-change: filter;`(仅 Firefox) |
| 36 | +- `contain: paint;` |
| 37 | + |
| 38 | +案例: |
| 39 | + |
| 40 | +```html |
| 41 | +<body> |
| 42 | + <div class="container" style="position: relative;"> |
| 43 | + <div class="item" style="transform: rotate(0deg);"> |
| 44 | + <div class="item2" style="position: absolute;"></div> |
| 45 | + </div> |
| 46 | + </div> |
| 47 | +</body> |
| 48 | +``` |
| 49 | + |
| 50 | +此时,`div.item2` 的包含块为 `div.item`。 |
| 51 | + |
| 52 | + |
| 53 | + |
| 54 | +CSS 规范中所举的例子如下: |
| 55 | + |
| 56 | +```html |
| 57 | +<html> |
| 58 | + <head> |
| 59 | + <title>Illustration of containing blocks</title> |
| 60 | + </head> |
| 61 | + <body id="body"> |
| 62 | + <div id="div1"> |
| 63 | + <p id="p1">This is text in the first paragraph...</p> |
| 64 | + <p id="p2"> |
| 65 | + This is text |
| 66 | + <em id="em1"> |
| 67 | + in the |
| 68 | + <strong id="strong1">second</strong> |
| 69 | + paragraph. |
| 70 | + </em> |
| 71 | + </p> |
| 72 | + </div> |
| 73 | + </body> |
| 74 | +</html> |
| 75 | +``` |
| 76 | + |
| 77 | +在没有添加任何 CSS 代码的情况下,元素对应的包含块为: |
| 78 | + |
| 79 | +| 元素 | 包含块 | 参照规则 | 说明 | |
| 80 | +| ------- | --------------------------- | -------- | ------------------ | |
| 81 | +| html | initial C.B. (UA-dependent) | 0 | | |
| 82 | +| body | html | 1 | | |
| 83 | +| div1 | body | 1 | | |
| 84 | +| p1 | div1 | 1 | | |
| 85 | +| p2 | div1 | 1 | | |
| 86 | +| em1 | p2 | 1 | | |
| 87 | +| strong1 | **p2** | 1 | 最近块容器的内容区 | |
| 88 | + |
| 89 | +接下来添加如下 CSS: |
| 90 | + |
| 91 | +```css |
| 92 | +#div1 { |
| 93 | + position: absolute; |
| 94 | + left: 50px; |
| 95 | +} |
| 96 | +``` |
| 97 | + |
| 98 | +变化如下: |
| 99 | + |
| 100 | +| 元素 | 包含块 | 参照规则 | 说明 | |
| 101 | +| ---- | --------------------------- | -------- | -------------------------------- | |
| 102 | +| div1 | initial C.B. (UA-dependent) | 3 | 最近的非static祖先元素内边距区域 | |
| 103 | + |
| 104 | +继续修改 CSS: |
| 105 | + |
| 106 | +```css |
| 107 | +#div1 { |
| 108 | + position: absolute; |
| 109 | + left: 50px; |
| 110 | +} |
| 111 | +#em1 { |
| 112 | + position: absolute; |
| 113 | + left: 100px; |
| 114 | +} |
| 115 | +``` |
| 116 | + |
| 117 | +变化如下: |
| 118 | + |
| 119 | +| 元素 | 包含块 | 参照规则 | 说明 | |
| 120 | +| ------- | --------------------------- | -------- | -------------------------------- | |
| 121 | +| div1 | initial C.B. (UA-dependent) | | | |
| 122 | +| em1 | div1 | 3 | 最近的非static祖先元素内边距区域 | |
| 123 | +| strong1 | em1 | 1 | 最近块容器的内容区 | |
| 124 | + |
| 125 | +其他参考案例:*https://developer.mozilla.org/zh-CN/docs/Web/CSS/Containing_block* |
| 126 | + |
| 127 | + |
| 128 | + |
| 129 | + |
| 130 | + |
| 131 | + |
| 132 | + |
0 commit comments