直接跳到内容

布局与响应式

一般布局

文档流 (正常流)

文档流是浏览器默认的 HTML 元素排列方式,遵循以下规则:

  • 块级元素从上到下排列
  • 行内元素从左到右排列
  • 元素按照在 HTML 中的出现顺序显示
css
/* 块级元素示例 */
div {
  display: block; /* 默认值 */
  width: 100%; /* 默认占满父容器宽度 */
}

/* 行内元素示例 */
span {
  display: inline; /* 默认值 */
  width: auto; /* 宽度由内容决定 */
}
+-----------------------------------+
|           块级元素1                |
+-----------------------------------+
|           块级元素2                |
+-----------------------------------+
| 行内元素1 | 行内元素2 | 行内元素3 ... |
+-----------------------------------+

浮动 (float) 和清除浮动

浮动:使元素脱离正常文档流,向左或向右移动

css
/* 浮动示例 */
.float-left {
  float: left;
  width: 200px;
}

.float-right {
  float: right;
  width: 200px;
}

/* 清除浮动方法 */
.clearfix::after {
  content: '';
  display: table;
  clear: both;
}

.container {
  overflow: auto; /* 另一种清除浮动方式 */
}
+-----------------------------------+
|            container              |
| +-----+ +----------------------+  |
| |left | |       right          |  |
| |     | |                      |  |
| +-----+ +----------------------+  |
|                                   |
+-----------------------------------+

定位

相对定位:相对于元素正常位置进行偏移

css
.relative {
  position: relative;
  top: 10px;
  left: 20px;
}
+-----------------------------------+
| 元素原位置                         |
|    +--------+                     |
|    |相对定位|                     |
|    | 元素   |                     |
|    +--------+                     |
+-----------------------------------+

绝对定位:相对于最近的非 static 定位祖先元素

css
.absolute {
  position: absolute;
  top: 0;
  right: 0;
}
+-----------------------------------+
| 父容器(非 static)                  |
| +-------------------------------+ |
| |      +--------+               | |
| |      | 绝对定位 |              | |
| |      |   元素  |               | |
| |      +--------+               | |
| +-------------------------------+ |
+-----------------------------------+

固定定位:相对于浏览器窗口定位

css
.fixed {
  position: fixed;
  bottom: 20px;
  right: 20px;
}
+-----------------------------------+
| 浏览器窗口                         |
| +-------------------------------+ |
| |      +--------+               | |
| |      | 绝对定位 |              | |
| |      |   元素  |              | |
| |      +--------+               | |
| +-------------------------------+ |
+-----------------------------------+

粘滞定位:超出设定的边界条件时,相对于滚动容器进行定位

css
.sticky {
  position: sticky;
  top: 20px; /* 当相对于滚动容器的top小于 20时,则固定到20 */
  bottom: 20px; /* 当相对于滚动容器的bottom小于 20时,则固定到20 */
  left: 20px; /* 当相对于滚动容器的left小于 20时,则固定到20 */
  right: 20px; /* 当相对于滚动容器的right小于 20时,则固定到20 */
}
  ┌───────────────────────────────┐
  │ 内容顶部 (已超出容器)           │
  | (sticky元素原位置)            |
+-|-----------------------------──|---+
| |      +--------+               |   |
| |      | sticky |               |   |
| |      |   元素  |               |   |
| |      +--------+               |   |
| |                               |   |
| |                               |   |
| +-------------------------------+   |
|       滚动容器                       |
+-------------------------------------+

Flexbox 弹性布局

基本概念

  • 主轴 (Main Axis) flex 布局元素的
  • 交叉轴 (Cross Axis)

默认情况

                    主轴 (Main Axis) --->
交叉轴 (Cross Axis)  |   +---------------------------+  ←  start
         |          |   |    Flex 容器 (Container)   |
         |          |   | +----+  +----+  +----+    |
         |          |   | |项目1|  |项目2| |项目3|   |
         |          |   | +----+  +----+  +----+    |
         |          |   |                           |
         V          |   +---------------------------+  ←  end
                    |
                    +--- start                      +---  end

容器属性

css
.container {
  display: flex;
  flex-direction: row;
  /* 主轴方向:row | row-reverse | column | column-reverse */
  flex-wrap: nowrap; /* 换行 */
  gap: 10px; /* 项目间距 */
}

项目属性

css
.item {
  flex-grow: 0; /* 放大比例 */
  flex-shrink: 1; /* 缩小比例 */
  flex-basis: auto; /* 初始大小 */
  align-self: auto; /* 单独对齐 */
  order: 0; /* 排列顺序 */
}

常用布局示例

水平居中

+-----------------------------------+
|          +-------------+          |
|          |  居中内容    |          |
|          +-------------+          |
+-----------------------------------+

圣杯布局

+-----------------------------------+
|              header               |
+----------+-------------+----------+
| sidebar  |    main     | sidebar2 |
|          |             |          |
+----------+-------------+----------+
|              footer               |
+-----------------------------------+

Grid 布局

基本网格

+----------+----------+----------+
|  单元格  |  单元格   |  单元格   |
+----------+----------+----------+
|  单元格  |  单元格   |  单元格   |
+----------+----------+----------+
|  单元格  |  单元格   |  单元格   |
+----------+----------+----------+

容器属性

css
.container {
  display: grid;
  /*  fr(fraction),表示剩余空间的分配系数 */
  grid-template-columns: 200px 1fr 200px; /* 列定义 */
  grid-template-rows: 100px 1fr 100px; /* 行定义 */
  grid-template-areas:
    'header header header'
    'sidebar main aside'
    'footer footer footer';
  gap: 20px; /* 网格间距 */
  grid-column: 1 / 3; /* 列范围 */
  grid-row: 1; /* 行位置 */
  grid-area: header; /* 区域名称 */
}

常见布局模式

12 列网格系统

+--+--+--+--+--+--+--+--+--+--+--+--+
|1 |2 |3 |4 |5 |6 |7 |8 |9 |10|11|12|
+--+--+--+--+--+--+--+--+--+--+--+--+

杂志布局

+-----------+-----------------------+
|           |                       |
|  特色内容  |        头条新闻        |
|           |                       |
+-----------+-----------+-----------+
|    新闻1   |   新闻2    |   新闻3   |
+-----------+-----------+-----------+
|           |                       |
|  侧边栏    |        主要内容         |
|           |                       |
+-----------+-----------------------+

瀑布流布局

┌───────┼───────┼───────┐
│ ┌───┐ │ ┌───┐ │ ┌───┐ │
│ │ 1 │ │ │ 2 │ │ │ 3 │ │
│ │   │ │ │   │ │ │   │ │
│ │   │ │ │   │ │ │   │ │
│ |   | │ └───┘ │ └───┘ │
│ └───┘ │ ┌───┐ │ ┌───┐ │
│ ┌───┐ │ | 5 | │ |   | │
│ │ 4 │ │ │   │ │ │ 6 │ │
│ │   │ │ └───┘ │ │   │ │
│ │   │ │ ┌───┐ | │   | │
│ └───┘ │ │   │ │ └───┘ │
│ ┌───┐ │ │   │ │ ┌───┐ │
│ |   | │ │ 8 │ │ │ 9 │ │
│ │ 7 │ │ │   │ │ │   │ │
│ │   │ │ │   │ │ │   │ │
│ └───┘ │ │   │ │ │   │ │
└───────┴───────┴───────┴

响应式布局

使用相对单位

由于各种尺寸的设备都有,使用 px 这一固定单位不能在每种尺寸上适用,因此需要使用相对单位。

css
body {
  font-size: 16px; /* 基准字体大小 */
}

p {
  /* 使用相对单位 */
  font-size: 1rem; /* 16px */
}

@media (max-width: 768px) {
  body {
    font-size: 14px; /* 移动端调整基准字体 */
  }
}

图片

css
/* 图片自适应容器 */
img {
  max-width: 100%; /* 宽度为容器的宽度 */
  height: auto; /* 高度自动 */
}

/**
 * object-fit: fill
 * 默认值,强行拉伸图片填满容器,可能会导致图片变形
 */
img {
  object-fit: fill;
}

/**
 * object-fit: contain
 * 保持图片比例缩放,完整显示在容器内
 * 如果比例不一致,会在容器内留空白(上下或左右)
 */
img {
  object-fit: contain;
}

/**
 * object-fit: cover
 * 保持图片比例缩放,填满整个容器
 * 如果比例不一致,图片会被裁剪掉一部分
 */
img {
  object-fit: cover;
}

/**
 * object-fit: none
 * 不缩放,保持图片原始大小
 * 如果图片比容器大,会溢出容器边界
 */
img {
  object-fit: none;
}

/**
 * object-fit: scale-down
 * 在 none 和 contain 之间取较小的效果
 * - 如果原图比容器小 → 等同 none(不缩放)
 * - 如果原图比容器大 → 等同 contain(缩放以适应容器)
 */
img {
  object-fit: scale-down;
}

媒体查询

在不同分辨率、宽度、高度的设备上使用不同的布局方式,实现最好的展示

css
/* 移动设备 */
.container {
  display: block;
}

/* 平板 */
@media (min-width: 768px) {
  .container {
    display: flex;
  }
}

/* 桌面 */
@media (min-width: 1024px) {
  .container {
    display: grid;
    /*  fr(fraction),表示剩余空间的分配系数 */
    grid-template-columns: 1fr 2fr 1fr;
  }
}

.high-dpi-image {
  background-image: url('image@1x.jpg');
}

/* 根据DPI提供不同图片 */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .high-dpi-image {
    background-image: url('image@2x.jpg');
    background-size: contain;
  }
}

响应式网格

移动设备:
+-----------+
|    1     |
+-----------+
|    2     |
+-----------+
|    3     |
+-----------+

平板:
+-----------+-----------+
|     1     |     2     |
+-----------+-----------+
|     3     |           |
+-----------+-----------+

桌面:
+-----+-----------+-----+
|  1  |     2     |  3  |
+-----+-----------+-----+
布局与响应式已经加载完毕