跳到主要内容

盒子模型

盒子模型(Box Model)是网页设计 CSS 样式时的重要概念。理解盒子模型,可以让我们灵活地控制网页上的元素的显示效果。

基本概念

HTML 中的所有元素都可以看作 “盒子”。以下是一个盒子的几个要素:

Margin
 
Border
Padding
Content
常见的盒子模型
Margin
Outline
Border
Padding
Content
带 outline 的盒子模型

  • Margin(外边距) - 清除边框外的区域,外边距是透明的。
  • Border(边框) - 围绕在内边距和内容外的边框。
  • Padding(内边距) - 清除内容周围的区域,内边距是透明的。
  • Content(内容) - 盒子的内容,显示文本和图像。注:一般来说,content 就是一个 HTML 元素的子元素
  • 轮廓(outline)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。注:outline 不占额外空间。

摘自:CSS 盒子模型 | 菜鸟教程

在 CSS 中,我们可以通过属性设计盒子的 Margin、Border、Padding(及 Outline,这个不常用,此处不介绍)。下面介绍一些(笔者认为)常用的属性:

Border 的属性

Border 分为上、下、左、右四个方向的边框,即 border-topborder-bottomborder-leftborder-right。我们先介绍几个简写属性,它们允许我们同时设置四个方向的边框属性:

简写属性属性值说明例子
bordercolor_value, width_value, style
(无序,至少指定一个)
允许一次设置三个属性border: 2px
border: 2px solid
border-widthwidth_value设置宽度border-width: 2px
border-stylestyle设置样式border-style: solid
border-colorcolor_value设置颜色border-color: #2e5b85

style 属性值:常用的有 none(无边框)、solid(实心边框)、inherit(从父元素继承)。

此外,我们还可以单独设置某个方向的边框的属性,比如对上边框有:

border-top, border-top-width, border-top-style, border-top-color

这里不对每个属性分别展开了。

圆角 Border

可以使用以下 CSS 设置圆角边框:

border-radius: 8px;
border-radius: 8px 8px 0 0;

在第二个例子中,我们分别指定的是 左上、右上、右下、左下 的圆角半径。

Margin、Padding 的属性

这二者都是 “边距”,属性比较简单。先介绍简写属性:

简写属性属性值说明例子
marginlength%inherit允许同时设置四个方向的外边距margin: 8px
margin: 5%
paddinglength%autoinherit允许同时设置四个方向的内边距padding: 8px

% 指的是基于父元素的宽度百分比;auto 表示由浏览器计算外边距。

当然,我们可以单独设置各个边距的属性,以 Margin 为例:

margin-top, margin-bottom, margin-left, margin-right

HTML 元素的分类

HTML 元素可以分为以下几类,它们在布局中的行为不同:

块级元素 block

块级元素独占一行,其宽度会自动填满父元素宽度,并和相邻的块级元素依次垂直排列,可以设置元素的宽度(width)和高度(width)以及四个方向的内、外边距。块级元素一般是其他元素的容器,可容纳块级元素和行内元素。

摘自:《HTML+CSS+JavaScript Web前端开发技术》

常见的块级元素:

<div> <li> <p> <h1>...<h6>

行内元素 inline

行内元素不会独占一行,相邻的行内元素会自动排列在同一行里,直到一行排不下才会换行。行内元素可以设置四个方向的内边距以及左、右方向的外边距,但不可以设置宽度(width)、高度(height)和上、下方向的外边距,行内元素的高度由元素高度决定,宽度由内容的长度控制。行内元素一般不可以包含块级元素。

摘自:《HTML+CSS+JavaScript Web前端开发技术》

常见的行内元素:

<span> <a> <strong> <img>

注意 <img> 比较特别,虽然它是行内元素,但是可以设置 widthheight

相互转换

其实我们可以通过设置 CSS 的 display 属性来实现块级元素和行内元素的相互转换:

display: block;
display: inline;
display: inline-block;

其中 inline-block 为 “行内块级元素”,其以行内形式显示,但是能设置 widthheight

Flexbox

本小节的引用、引图摘自:flex 布局的基本概念 - CSS:层叠样式表 | MDN

上面讲的是 “普通流排版”,即最一般的布局方式。然而这样的排版方式不太适合复杂的页面设计。

Flexible Box 模型,通常被称为 Flexbox,是一种一维的布局模型。它给 Flexbox 的子元素之间提供了强大的空间分布和对齐能力。

我们说 Flexbox 是一种一维的布局,是因为一个 Flexbox 一次只能处理一个维度上的元素布局,一行或者一列。作为对比的是另外一个二维布局 CSS Grid Layout,可以同时处理行和列上的布局。

为了使用 Flexbox 布局,我们需要指定元素的 display 属性。

文档中采用了 Flexbox 的区域就叫做 Flex 容器。为了创建 Flex 容器,我们把一个容器的 display 属性值改为 flex 或者 inline-flex。完成这一步之后,容器中的直系子元素就会变为 Flex 元素。由于所有 CSS 属性都会有一个初始值,所以 Flex 容器中的所有 Flex 元素都会有下列行为:

  • 元素排列为一行(flex-direction 属性的初始值是 row)。
  • 元素从主轴的起始线开始。
  • 元素不会在主维度方向拉伸,但是可以缩小。
  • 元素被拉伸来填充交叉轴大小。
  • flex-basis 属性为 auto
  • flex-wrap 属性为 nowrap

两条轴线

Flexbox 概念中,有两条轴线:主轴(Main Axis)和交叉轴(Cross Axis),二者互相垂直。默认来说,主轴是 row

主轴由 flex-direction 定义,可以取 4 个值:

  • row
  • row-reverse
  • column
  • column-reverse

Flex 容器中的元素会沿着主轴方向延伸排列。

多行布局

虽然 Flexbox 是一维模型,但可以使我们的 flex 项目应用到多行中。在这样做的时候,你应该把每一行看作一个新的 Flex 容器。任何空间分布都将在该行上发生,而不影响该空间分布的其他行。

为了实现多行效果,请为属性 flex-wrap 添加一个属性值 wrap。现在,如果你的项目太大而无法全部显示在一行中,则会换行显示。下面的实时例子包含已给出宽度的项目,对于flex容器,项目的子元素总宽度大于容器最大宽度。由于 flex-wrap 的值设置为 wrap,所以项目的子元素换行显示。若将其设置为 nowrap,这也是初始值,它们将会缩小以适应容器,因为它们使用的是允许缩小的初始 Flexbox 值。如果项目的子元素无法缩小,使用 nowrap 会导致溢出,或者缩小程度还不够小。

也就是为 Flex 容器设置以下 CSS:

flex-wrap: wrap;

对齐

可以使用以下 CSS 使得子元素沿着主轴在 Flex 容器中对齐:

justify-content: center;

例如,则上述代码将使得子元素排列在 Flex 容器的主轴中央。


类似地,我们也可以使得子元素沿交叉轴对齐:

align-items: center;

例如,则上述代码将使得子元素沿交叉轴对齐(这对于尺寸不同的子元素非常有用)。

参考