AI 摘要

文章从传统固定宽度布局的缺陷切入,系统讲解响应式三大技术:浮动百分比、Flex 弹性盒与媒体查询。先以代码对比展示百分比浮动如何实现“弹性”伸缩;再完整梳理 Flex 容器与项目的 12 组属性,结合图示与示例演示主轴、交叉轴对齐、换行、排序、放大缩小等细节;最后引入 CSS3 媒体查询,通过 @media 根据屏宽切换样式,实现一套代码多终端适配,为后续 Bootstrap 框架学习奠定理论与实践基础。

浮动 + 百分比布局

传统网页布局存在的问题

传统的网页布局,网页宽度被设置为一个固定值,不具备 "弹性" 效果。


示例:传统网页布局存在的问题

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            /** 父盒子固定宽度900px **/
            width: 900px;
            border: black 2px solid;
        }
        .left {
            border: green 2px solid;
            height: 300px;
            /** 左侧子盒子固定宽度200px **/
            width: 200px;
            /** 设置浮动 **/
            float: left;
        }
        .right {
            border: red 2px solid;
            height: 500px;
            /** 右侧子盒子固定宽度500px **/
            width: 500px;
            /** 设置浮动 **/
            float: left;
        }
        .clear {
            /** 子盒子浮动的情况下,清除父盒子塌陷问题 **/
            clear: both;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="left">
        left
    </div>
    <div class="right">
        right
    </div>
    <div class="clear"></div>
</div>
</body>
</html>

示例效果:


使用浮动 + 百分比适应屏幕大小

实现网页 "弹性" 效果,可以使用浮动 + 百分比的布局方式,网页显示的内容不再受浏览器宽度的影响,此时的网页会随着浏览器的伸展而伸展,随着浏览器的收缩而收缩。


示例:使用浮动 + 百分比适应屏幕大小

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            /** 父盒子弹性宽度100% **/
            width: 100%;
            border: black 2px solid;
        }
        .left {
            border: green 2px solid;
            height: 300px;
            /** 左侧子盒子弹性宽度20% **/
            width: 20%;
            /** 设置浮动 **/
            float: left;
        }
        .right {
            border: red 2px solid;
            height: 500px;
            /** 右侧子盒子弹性宽度50% **/
            width: 50%;
            /** 设置浮动 **/
            float: left;
        }
        .clear {
            /** 子盒子浮动的情况下,清除父盒子塌陷问题 **/
            clear: both;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="left">
        left
    </div>
    <div class="right">
        right
    </div>
    <div class="clear"></div>
</div>
</body>
</html>

示例效果:


Flex 弹性盒布局

Flex 简介

Flex 弹性盒布局(伸缩布局/伸缩盒布局/ Flex 布局)是一种布局方式,常用于当页面需要适应不同的屏幕大小以及设备类型时能够确保元素拥有恰当的行为。

Flex 弹性盒布局的作用:

  • 能够更加高效方便地控制元素的对齐、排列,可以让子元素排在一行,且高度一致。
  • 无论元素的尺寸是固定的还是动态的,都可以自动计算布局内元素的尺寸。
  • 控制元素在页面中的布局方向。
  • 按照不同于 DOM 所指定排序方式对屏幕上的元素重新排序。

Flex 弹性盒布局的描述图:

Flex 弹性盒布局的相关术语:

  • 容器(container):采用 Flex 布局的元素被称为容器。
  • 项目(item):容器内的子元素被称为项目。
  • 主轴(main axis):容器内的子元素的排列方向。
  • 交叉轴/侧轴(cross axis):垂直于主轴的轴。
  • 起始线:轴开始的位置。
  • 终止线:轴结束的位置。

弹性盒布局的基本用法:

display: flex;
display: inline-flex;

Flex 弹性盒布局的特点:

  • 任何容器都可以指定 Flex 弹性盒布局,包括块级元素、行内块元素、行内元素。
  • 容器设为 Flex 弹性盒布局以后,项目的 float(浮动)、clear(解决塌陷)、vertical-align(垂直对齐方式)属性失效。
  • Flex 弹性盒布局的核心就是通过设置容器的属性,来影响项目的布局和排列方式。

示例:Flex 弹性盒布局

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            /** 设置为Flex容器 **/
            display: flex;
            border: black 2px solid;
        }
        .left {
            border: green 2px solid;
            height: 300px;
        }
        .right {
            border: red 2px solid;
            height: 500px;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="left">
        left:这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本。
    </div>
    <div class="right">
        right:这是一段文本,这是一段文本,这是一段文本,这是一段文本。
    </div>
</div>
</body>
</html>

示例效果:


Flex 属性

Flex 弹性盒布局分为容器属性和项目属性。

容器属性:设置给弹性盒子(父元素)的属性。

名称描述
flex-direction定义主轴的方向,即项目的排列方向
flex-wrap定义项目在一条轴线排不下时如何换行
flex-flow复合属性,是 flex-direction、flex-wrap 的简写形式
justify-content定义项目在主轴上的对齐方式
align-items定义项目在交叉轴上的对齐方式
align-content定义当弹性盒子里有多个弹性行时,这些行在交叉轴上的对齐方式和分布

项目属性:设置给弹性盒子内的子元素的属性。

名称描述
order设置项目的排列顺序
flex-grow设置项目的放大比例
flex-shrink设置项目的缩小比例
flex-basis设置弹性盒伸缩基准值
flex复合属性,是 flex-grow、flex-shrink、flex-basis 的简写形式
align-self设置子元素在交叉轴方向上的对齐方式

容器属性 flex-direction

flex-direction 属性用于定义主轴的方向,即项目的排列方向,主轴是项目在容器中的排列方向,可能是水平的也可能是垂直的,取决于 flex-direction 属性的设置。

flex-direction 属性的基本用法:

flex-direction: 主轴方向;

主轴方向的可选值:

名称描述
row(默认值)主轴为水平方向,项目从左到右排列
row-reverse主轴为水平方向,项目从右到左排列
column主轴为垂直方向,项目从上到下排列
column-reverse主轴为垂直方向,项目从下到上排列

示例:flex-direction

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            flex-direction: row-reverse;
            border: black 2px solid;
        }
        .left {
            border: green 2px solid;
            height: 300px;
        }
        .right {
            border: red 2px solid;
            height: 500px;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="left">
        left:这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本。
    </div>
    <div class="right">
        right:这是一段文本,这是一段文本,这是一段文本,这是一段文本。
    </div>
</div>
</body>
</html>

示例效果:


容器属性 flex-wrap

默认情况下,容器中的项目都排在一条轴线上。flex-wrap 属性用于定义项目在一条轴线上排不下时应该如何换行。

flex-wrap 属性的基本用法:

flex-wrap: 换行方式;

换行方式的可选值:

名称描述
nowrap(默认值)项目不拆行或不换行
wrap项目在必要时拆行或拆列
wrap-reserve项目在必要时拆行或拆列,但是以相反的顺序排列

示例:flex-wrap

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            flex-wrap: wrap;
            border: black 2px solid;
        }
        .left {
            border: green 2px solid;
            height: 300px;
        }
        .right {
            border: red 2px solid;
            height: 500px;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="left">
        left:这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本,这是一段文本。
    </div>
    <div class="right">
        right:这是一段文本,这是一段文本,这是一段文本,这是一段文本。
    </div>
</div>
</body>
</html>

示例效果:


容器属性 flex-flow

flex-flow 是一个复合属性,是 flex-direction、flex-wrap 的简写形式。

flex-flow 属性的基本用法:

flex-flow: 主轴方向 换行方式;

容器属性 justify-content

justify-content 属性用于设置项目在主轴方向上的对齐方式。

justify-content 属性的基本用法:

justify-content: 对齐方式;

对齐方式的可选值:

名称描述
flex-start(默认值)项目在主轴中起点对齐
flex-end项目在主轴中终点对齐
center项目在主轴中居中对齐
space-between项目在主轴中两端对齐,剩余空间在头尾项目之外的项目间平均分配
space-around项目在主轴中分散对齐,剩余空间在每个项目两侧平均分配
space-evenly项目在主轴中平均对齐,剩余空间在每个项目之间平均分配

示例:justify-content

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            border: black 2px solid;
            width: 50%;
            height: 90px;
        }
        .item {
            background-color: green;
            width: 90px;
            height: 90px;
            border: black 1px solid;
        }
        .box:nth-of-type(1) {
            justify-content: flex-start;
        }
        .box:nth-of-type(2) {
            justify-content: flex-end;
        }
        .box:nth-of-type(3) {
            justify-content: center;
        }
        .box:nth-of-type(4) {
            justify-content: space-between;
        }
        .box:nth-of-type(5) {
            justify-content: space-around;
        }
        .box:nth-of-type(6) {
            justify-content: space-evenly;
        }
    </style>
</head>
<body>
    <h3>flex-start:起点对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>flex-end:终点对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>center:居中对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>space-between:两端对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>space-around:分散对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>space-evenly:平均对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
</body>
</html>

示例效果:


容器属性 align-items

align-items 属性用于设置项目在交叉轴方向上的对齐方式。

align-items 属性的基本用法:

align-items: 对齐方式;

对齐方式的可选值:

名称描述
stretch(默认值)如果项目未设置高度或 auto,项目会被拉伸以适应容器高度
flex-start项目在交叉轴中起点对齐
flex-end项目在交叉轴中终点对齐
baseline项目在交叉轴中基线对齐

示例:align-items

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            border: black 2px solid;
            width: 50%;
            height: 150px;
        }
        .item {
            background-color: green;
            width: 90px;
            height: 45px;
            border: black 1px solid;
        }
        .box:nth-of-type(1) {
            align-items: stretch;
        }
        .box:nth-of-type(2) {
            align-items: flex-start;
        }
        .box:nth-of-type(3) {
            align-items: flex-end;
        }
        .box:nth-of-type(4) {
            align-items: baseline;
        }
    </style>
</head>
<body>
    <h3>stretch:项目拉伸适应容器</h3>
    <div class="box">
        <div class="item" style="height: auto">item1</div>
        <div class="item" style="height: auto">item2</div>
        <div class="item" style="height: auto">item3</div>
        <div class="item" style="height: auto">item4</div>
    </div>
    <h3>flex-start:起点对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>flex-end:终点对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>baseline:基线对齐</h3>
    <div class="box">
        <div class="item"></div>
        <div class="item" style="height: 50px"></div>
        <div class="item" style="height: 60px"></div>
        <div class="item" style="height: 70px"></div>
    </div>
</body>
</html>

示例效果:


容器属性 align-content

align-content 属性用于控制当容器里有多个弹性行时,这些行在交叉上的对齐方式和分布,align-content 属性对单行容器没有影响,它只在有多个行(即容器内的项目有换行)且容器在交叉轴方向上有额外的空间时才适用。

align-content 属性的基本用法:

align-content: 对齐方式;

对齐方式的常见可选值:

名称描述
flex-start(默认值)项目在交叉轴中起点对齐
flex-end项目在在交叉轴中终点对齐
center项目在在交叉轴中居中对齐
space-between项目在交叉轴中两端对齐,剩余空间在头尾项目之外的项目见平均分配
space-around项目在交叉轴中分散对齐,剩余空间在每个项目两侧平均分配
space-evenly项目在主轴中平均对齐,剩余空间在每个项目之间平均分配

示例:align-content

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            flex-wrap: wrap;
            border: black 2px solid;
            width: 50%;
            height: 300px;
        }
        .item {
            background-color: green;
            width: 50%;
            height: 50px;
            border: black 1px solid;
        }
        .box:nth-of-type(1) {
            align-content: flex-start;
        }
        .box:nth-of-type(2) {
            align-content: flex-end;
        }
        .box:nth-of-type(3) {
            align-content: center;
        }
        .box:nth-of-type(4) {
            align-content: space-between;
        }
        .box:nth-of-type(5) {
            align-content: space-around;
        }
        .box:nth-of-type(6) {
            align-content: space-evenly;
        }
    </style>
</head>
<body>
    <h3>flex-start:起点对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>flex-end:终点对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>center:居中对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>space-between:两端对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>space-around:分散对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
    <h3>space-evenly:平均对齐</h3>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
</body>
</html>

示例效果:


项目属性 order

order 属性用于设置项目的排列顺序,顺序数值越小,排列越靠前,顺序数值可以是正数也可以是负数,默认为 0。

order 属性的基本用法:

order: 排序数值;

示例:order

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            border: black 2px solid;
            width: 50%;
            height: 90px;
        }
        .item {
            background-color: green;
            width: 90px;
            height: 90px;
            border: black 1px solid;
        }
        .item:nth-of-type(1) {
            order: 2;
        }
        .item:nth-of-type(2) {
            order: 4;
        }
        .item:nth-of-type(3) {
            order: 3;
        }
        .item:nth-of-type(4) {
            order: 1;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
</body>
</html>

示例效果:


项目属性 flex-grow

flex-grow 属性用于设置项目的放大比例,主要用于分配项目的剩余空间,其属性值不能是负数,默认值为 0。

flex-grow 属性的基本用法:

flex-grow: 放大数值;

示例:flex-grow

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            border: black 2px solid;
            width: 450px;
            height: 90px;
        }
        .item {
            background-color: green;
            width: 90px;
            height: 90px;
            border: black 1px solid;
        }
        .item:nth-of-type(1) {
            flex-grow: 0.5;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
</body>
</html>

示例效果:


项目属性 flex-shrink

flex-shrink 属性用于设置项目的缩小比例,即如果空间不足,项目将会缩小,其属性值不能是负数,默认值为 1。

flex-shrink 属性的基本用法:

flex-grow: 缩小数值;

示例:flex-shrink

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            border: black 2px solid;
            width: 300px;
            height: 90px;
        }
        .item {
            background-color: green;
            width: 90px;
            height: 90px;
            border: black 1px solid;
        }
        .item:nth-of-type(1) {
            flex-shrink: 3;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
</body>
</html>

示例效果:


项目属性 flex-basis

flex-basis 属性用于设置项目伸缩基准值,其默认值为 auto,即项目本身的大小。

flex-basis 属性的基本用法:

flex-basis: 伸缩基准值;

示例:flex-basis

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            border: black 2px solid;
            width: 300px;
            height: 90px;
        }
        .item {
            background-color: green;
            height: 90px;
            border: black 1px solid;
        }
        .item:nth-of-type(1) {
            flex-basis: 100px;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item">item4</div>
    </div>
</body>
</html>

示例效果:


项目属性 flex

flex 属性是一个复合属性,是 flex-grow、flex-shrink、flex-basis 的简写形式。

flex 属性的基本用法:

flex: 放大比例 缩小比例 伸缩基准值;

项目属性 align-self

align-self 属性用于设置项目在交叉轴方向上的对齐方式。

align-self 属性的基本用法;

align-self: 对齐方式;

对齐方式的常见可选值:

名称描述
auto(默认值)项目继承其父容器的 align-items 属性
stretch如果项目未设置高度或 auto,项目会被拉伸以适应容器高度
flex-start项目在交叉轴中起点对齐
flex-end项目在交叉轴中终点对齐
center项目在交叉轴中居中对齐
baseline项目在交叉轴中基线对齐

示例:align-self

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            display: flex;
            border: black 2px solid;
            width: 50%;
            height: 360px;
        }
        .item {
            background-color: green;
            width: 90px;
            height: 90px;
            border: black 1px solid;
        }
        .item:nth-of-type(1) {
            align-self: flex-start;
        }
        .item:nth-of-type(2) {
            align-self: flex-end;
        }
        .item:nth-of-type(3) {
            align-self: center;
        }
        .item:nth-of-type(4) {
            align-self: stretch;
        }
        .item:nth-of-type(5) {
            align-self: baseline;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="item">item1</div>
        <div class="item">item2</div>
        <div class="item">item3</div>
        <div class="item" style="height: auto">item4</div>
        <div class="item">item5</div>
    </div>
</body>
</html>

示例效果:


媒体查询

响应式布局

响应式布局主要目的是为不同终端的用户提供更加舒适的界面和更好的用户体验,响应式布局即写一套页面就能适应不同的终端。

响应式布局的优点:

  • 面对不同分辨率设备灵活性强,快捷的解决多设备显示适应问题。
  • 更少维护,开发一个网站,多终端使用。

响应式布局的缺点:

  • 兼容各种设备工作量大,效率低下。
  • 代码累赘,会出现隐藏无用的元素,加载时间较长。

响应式布局的原理:CSS3 媒体查询。

媒体查询

媒体查询可以针对不同的屏幕尺寸设置不同的样式,使页面在不同终端设备下达到不同的渲染效果。

媒体查询的引用方式:@media 和 link。

媒体查询的基本用法:

@media mediaType and|not|only (mediaQuery) {

}
<link rel="stylesheet" media="mediaType and|not|only (mediaQuery)"/>

媒体查询基本关键字:

名称描述
mediaType媒体类型
all:用于所有设备
screen:用于计算机屏幕、平板、手机等
print:用于打印机和打印机预览
mediaQuery媒体特性
width:宽度
height:高度
max-width:最大宽度
max-height:最大高度
min-width:最小宽度
min-height:最小高度
and当媒体特性出现多条并存时,需要使用关键词连接
and:同时满足条件时生效
only:指定某种特定的媒体类型
not:排除某种特定的媒体类型

示例:媒体查询

入口页面(index.html):

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            border: black 2px solid;
            width: 360px;
            height: 360px;
            background-color: red;
        }

        @media screen and (max-width: 1024px) and (min-width: 768px) {
            .box {
                border: black 2px solid;
                width: 240px;
                height: 240px;
                background-color: blue;
            }
        }

        @media screen and (max-width: 768px) {
            .box {
                border: black 2px solid;
                width: 180px;
                height: 180px;
                background-color: green;
            }
        }
    </style>
</head>
<body>
    <div class="box">

    </div>
</body>
</html>

示例效果: