2. CSS 盒模型和布局的基本概念

82 阅读6分钟

CSS 盒模型和布局的基本概念

1 CSS 盒模型

CSS 盒模型 描述了 网页元素 在页面中 所占空间结构每个元素 都被看作是 一个矩形盒子

这个盒子由 四个部分 组成:

  • 内容(content)
  • 内边距(padding)
  • 边框(border)
  • 外边距(margin)

box-model-1.png

1.1 内容(content)

内容(content)是盒子的 核心部分,用于放置 文本、图像 等 实际内容。其 大小 可以通过 widthheight 属性 来设置。

width: 200px; height: 100px;

定义了一个 内容区域 宽为 200 像素、高为 100 像素的 盒子

1.2 内边距(padding)

内边距(padding)位于 内容边框 之间,用于控制 内容 与 边框 之间的 距离。可以分别使用 padding - toppadding - bottompadding - leftpadding - right 属性 来设置 上、下、左、右 内边距,也可以使用 padding 属性 一次性设置 四个方向 的 内边距。

padding: 10px;

表示 四个方向的 内边距 都是 10px。内边距 会增加 盒子的 整体尺寸,因为它是在 内容区域之外 添加的 空间

1.3 边框(border)

边框(border)围绕在 内边距外侧,用于定义 盒子的 边界。边框的样式 可以通过 border-style(如 实线 solid、虚线 dashed、点线 dotted 等)、border-width(边框宽度)和 border-color(边框颜色)来设置,也可以使用 border 属性 一次性设置 这三个属性。

border: 1px solid black;

表示 设置一个 1 像素宽的 黑色 实线 边框。

1.4 外边距(margin)

外边距(margin)是 盒子相邻元素 之间的 空白区域。同样可以 分别使用 margin-topmargin-bottommargin-leftmargin-right属性 来设置上、下、左、右 外边距,或者使用 margin 属性 一次性设置。

margin: 20px;

表示 四个方向的 外边距 都是 20px。外边距 用于控制 元素之间的 间距不会影响 盒子 自身的尺寸,但会影响盒子 在页面布局中的 位置

2 CSS 布局

2.1 文档流布局(默认布局)

它是 HTML 文档 默认的 布局方式。在这种布局中,元素 按照 它们在 HTML 文档中的 出现顺序 依次排列

  • 块级元素(如 <div><p> 等)会 独占一行从上到下 排列;
  • 内联元素(如 <span><a> 等)则在 一行内 从左到右 排列,当一行排不下时 会 自动换行

2.2 浮动布局(float)

通过 float 属性 可以使元素 向左向右 浮动。当一个元素 被设置为 浮动时,它会 脱离正常文档流,向左 或 向右移动,直到碰到 父元素的边界 或者 另一个 浮动元素。其他 非浮动元素环绕浮动元素 的 周围。常用于布局中,如 文本环绕图片 的效果。

float 在现代布局中已被 flexboxgrid 等技术替代。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Float Layout Example</title>
  <style>
    .container {
      width: 100%;
      background-color: lightgray;
    }
    .box {
      width: 45%;
      margin: 10px;
      padding: 20px;
      background-color: #4CAF50;
      color: white;
    }
    .left {
      float: left;
    }
    .right {
      float: right;
    }
  </style>
</head>
<body>

<div class="container">
  <div class="box left">Left Box</div>
  <div class="box right">Right Box</div>
</div>

</body>
</html>
父容器高度塌陷

当使用 浮动布局时,父容器 往往会 塌陷无法包含 浮动的元素。也就是 容器的高度 没有正确计算,导致其 高度变为零 或 不包含 所有浮动子元素 的高度。为了解决这个问题,可以使用 clearfix 方法清除浮动。即给 父容器 添加 overflow: hidden; 属性 来清除浮动 并 避免容器塌陷。

2.3 定位布局(position)

position 属性 用于指定 元素的 定位方式,有 static(默认,按照正常文档流排列)、relative(相对定位)、absolute(绝对定位)和fixed(固定定位)四种。

相对定位(relative)

元素 相对于 自身 原来的 位置 进行定位。通过 topbottomleftright 属性 可以调整 元素的 位置。

position: relative; top: 10px; left: 20px;

元素 相对于它 原来的位置 向下移动 10 像素、向右移动 20 像素。

绝对定位(absolute)

元素 相对于 最近的 已定位 祖先元素(即 position 属性 不是 static 的祖先元素)进行定位,如果没有这样的祖先元素,则相对于文档 根元素 定位。同样可以使用 topbottomleftright 属性 来 确定位置。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Absolute Position Example</title>
  <style>
    .container {
      position: relative; /* 使得绝对定位的元素相对于此容器定位 */
      width: 500px;
      height: 300px;
      background-color: lightgray;
      border: 2px solid black;
    }

    .box {
      position: absolute; /* 绝对定位 */
      top: 50px;
      left: 100px;
      width: 200px;
      height: 100px;
      background-color: #4CAF50;
      color: white;
      padding: 20px;
    }
  </style>
</head>
<body>

  <div class="container">
    <div class="box">I am absolutely positioned!</div>
  </div>

</body>
</html>
固定定位(fixed)

元素 相对于 浏览器窗口 进行定位,无论页面如何滚动,固定定位的 元素 始终保持在 窗口中的 相同位置。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Fixed Header Example</title>
  <style>
    body {
      font-family: Arial, sans-serif;
    }

    /* 固定的头部 */
    .header {
      position: fixed; /* 使用 fixed 定位 */
      top: 0; /* 距离页面顶部 0 像素 */
      left: 0; /* 距离页面左侧 0 像素 */
      width: 100%; /* 宽度 100% */
      background-color: #333;
      color: white;
      text-align: center;
      padding: 15px;
      z-index: 1000; /* 确保头部在其他内容之上 */
    }

    /* 内容区 */
    .content {
      margin-top: 70px; /* 给内容区留出头部的空间 */
      padding: 20px;
      height: 2000px; /* 高度足够长以便页面可以滚动 */
    }
  </style>
</head>
<body>

  <div class="header">Fixed Header</div>

  <div class="content">
    <p>This is some content that will scroll under the fixed header. Scroll down to see the effect.</p>
  </div>

</body>
</html>

固定定位 常用于 固定头部底部侧边栏 等元素。

3 弹性布局(flex)

flex 布局 是一种 一维 布局模型,用于 在容器中 排列 子元素。通过设置 父元素的 display: flex;,可以将其 转换为一个 弹性容器,子元素 会成为 弹性项目

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Basic Flexbox Example</title>
  <style>
    .container {
      display: flex; /* 启用弹性布局 */
      justify-content: space-between; /* 子元素均匀分布在主轴方向 */
      align-items: center; /* 子元素在交叉轴方向居中对齐 */
      height: 200px;
      background-color: lightgray;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: #4CAF50;
      color: white;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 18px;
    }
  </style>
</head>
<body>

  <div class="container">
    <div class="box">Box 1</div>
    <div class="box">Box 2</div>
    <div class="box">Box 3</div>
  </div>

</body>
</html>

4 网格布局(grid)

grid 布局 是一种 二维 布局模型,它将容器 划分为 行 和 列 的网格,子元素 可以放置在 这些网格单元格中。通过设置 父元素的 display: grid;,可以将其 转换为一个 网格容器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Basic Grid Layout</title>
  <style>
    .container {
      display: grid; /* 启用 Grid 布局 */
      grid-template-columns: repeat(3, 1fr); /* 创建 3 列,每列占据 1 的比例 */
      grid-gap: 10px; /* 设置网格项之间的间隙 */
      background-color: lightgray;
      padding: 10px;
    }

    .box {
      background-color: #4CAF50;
      color: white;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 20px;
      height: 100px;
    }
  </style>
</head>
<body>

  <div class="container">
    <div class="box">Box 1</div>
    <div class="box">Box 2</div>
    <div class="box">Box 3</div>
    <div class="box">Box 4</div>
    <div class="box">Box 5</div>
    <div class="box">Box 6</div>
  </div>

</body>
</html>