# 布局

返回:UI

# flex

进入:仔细学习flex

# grid

进入:仔细学习grid

# CSS 盒模型、布局和包含块

返回:顶部

# CSS基础盒模型

CSS 盒模型是页面布局的基础

每个盒子由四个部分(或称区域)组成,分别为:

  • 内容区域 content area
  • 内边距区域 padding area
  • 边框区域 border area
  • 外边距区域 margin area

分别对应 width、height、padding、border、margin

# 注意box-sizing这个CSS属性

  • content-box (W3C 盒模型)是默认值。如果你设置一个元素的宽为 100px,那么这个元素的内容区会有 100px 宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。也就是说,最终盒子的宽高 >= 设置的宽高
  • border-box (IE 盒模型)告诉浏览器:你想要设置的边框和内边距的值是包含在 width 内的。也就是说,如果你将一个元素的 width 设为 100px,那么这 100px 会包含它的 border 和 padding,内容区的实际宽度是 width 减去(border + padding)的值。大多数情况下,这使得我们更容易地设定一个元素的宽高。
<div class="content-box">Content box</div>
<br>
<div class="border-box">Border box</div>
1
2
3
div {
  width: 160px;
  height: 80px;
  padding: 20px;
  border: 8px solid red;
  background: yellow;
}

.content-box {
  box-sizing: content-box;
  /* Total width: 160px + (2 * 20px) + (2 * 8px) = 216px
     Total height: 80px + (2 * 20px) + (2 * 8px) = 136px
     Content box width: 160px
     Content box height: 80px */
}

.border-box {
  box-sizing: border-box;
  /* Total width: 160px
     Total height: 80px
     Content box width: 160px - (2 * 20px) - (2 * 8px) = 104px
     Content box height: 80px - (2 * 20px) - (2 * 8px) = 24px */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

WARNING

border-box 的总宽高不会超过设定的 width 和 height,而 content-box 的大小是不确定的,会受到 border 和 padding 影响

# 布局和包含块

TIP

元素的尺寸及位置,常常会受它的包含块所影响
对于一些属性,例如 width, height, padding, margin,绝对定位元素的偏移值 (比如 position 被设置为 absolute 或 fixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。

# position

  • static 该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, left 和 z-index 属性无效
  • relative 该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。position:relative 对 table-*-group, table-row, table-column, table-cell, table-caption 元素无效
  • absolute 不为元素预留空间,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。
  • fixed 不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed 属性会创建新的层叠上下文。当元素祖先的 transform 属性非 none 时,容器由视口改为该祖先。
  • sticky 盒位置根据正常流计算(这称为正常流动中的位置),然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位。在所有情况下(即便被定位元素为 table 时),该元素定位均不对后续元素造成影响。当元素 B 被粘性定位时,后续元素的位置仍按照 B 未定位时的位置来确定。position: sticky 对 table 元素的效果与 position: relative 相同。 粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。 它可以很方便的实现 IOS 中的列表 title 吸顶效果
<head>
    <style>
      #box {
        height: 5000px;
      }
      #sti {
        position: sticky;
        top: 100px;
      }
      p {
        height: 1000px;
      }
    </style>
  </head>
  <body>
    <div id="box" class="box1" name="lxfriday">
      <p>hello div</p>
      <div id="sti">sti</div>
    </div>
  </body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

当sti距离顶部达到100px时,则不会移动,固定在该位置

# 确定包含块

确定包含块

确定一个元素的包含块的过程完全依赖于这个元素的 position 属性

  • 如果 position 属性为 static 或 relative ,包含块就是由它的最近的祖先块元素(inline-block、block、list-item),或者 BFC(table、flex、grid) 的内容区的边缘组成的。
  • 如果 position 属性为 absolute ,包含块就是由它的最近的 position 的值不是 static (也就是值为fixed, absolute, relative 或 sticky)的祖先元素的内边距区的边缘组成。
  • 如果 position 属性是 fixed,可以认为包含块就是视口 viewport

根元素(<html>)所在的包含块是一个被称为初始包含块的矩形,可认为是视口 viewport。

# 根据包含块计算百分值

如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性

  • 要计算 height top 及 bottom 中的百分值,是通过包含块的 height 的值
    如果包含块的 height 值会根据它的内容变化,而且包含块的 position 属性的值被赋予 relative 或 static ,那么,这些值的计算值为 0,也就是说包含块自身能先确定高度才可以让子元素的百分比计算生效
<head>
<style>
    .con {
      background-color: red;
    }
    .c1 {
      background-color: cyan;
      height: 500px;
    }
    .c2 {
      background-color: green;
      height: 100%;
    }
  </style>
  </head>
  <body>
    <div class="con">
      <div class="c1"></div>
      <div class="c2"></div>
    </div>
  </body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

.con 这个父元素没有设置高度
.c1 子元素设置了高度 500px,
.c2 设置的是百分比高度,
根据上面的规则, 由于父元素 .con 的 position 为 static,所以子元素设置百分比高度将会无效

  • 要计算 width, left, right, padding, margin 这些属性由包含块的 width 属性的值来计算它的百分值