盒子模型
盒子模型(Box Model)是网页设计 CSS 样式时的重要概念。理解盒子模型,可以让我们灵活地控制网页上的元素的显示效果。
基本概念
HTML 中的所有元素都可以看作 “盒子”。以下是一个盒子的几个要素:
- Margin(外边距) - 清除边框外的区域,外边距是透明的。
- Border(边框) - 围绕在内边距和内容外的边框。
- Padding(内边距) - 清除内容周围的区域,内边距是透明的。
- Content(内容) - 盒子的内容,显示文本和图像。注:一般来说,content 就是一个 HTML 元素的子元素
- 轮廓(outline)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。注:outline 不占额外空间。
在 CSS 中,我们可以通过属性设计盒子的 Margin、Border、Padding(及 Outline,这个不常用,此处不介绍)。下面介绍一些(笔者认为)常用的属性:
Border 的属性
Border 分为上、下、左、右四个方向的边框,即 border-top、border-bottom、border-left、border-right。我们先介绍几个简写属性,它们允许我们同时设置四个方向的边框属性:
| 简写属性 | 属性值 | 说明 | 例子 |
|---|---|---|---|
border | color_value, width_value, style(无序,至少指定一个) | 允许一次设置三个属性 | border: 2pxborder: 2px solid |
border-width | width_value | 设置宽度 | border-width: 2px |
border-style | style | 设置样式 | border-style: solid |
border-color | color_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 的属性
这二者都是 “边距”,属性比较简单。先介绍简写属性:
| 简写属性 | 属性值 | 说明 | 例子 |
|---|---|---|---|
margin | length 或 % 或 inherit | 允许同时设置四个方向的外边距 | margin: 8pxmargin: 5% |
padding | length 或 % 或 auto 或 inherit | 允许同时设置四个方向的内边距 | 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> 比较特别,虽然它是行内元素,但是可以设置 width 和 height。
相互转换
其实我们可以通过设置 CSS 的 display 属性来实现块级元素和行内元素的相互转换:
display: block;
display: inline;
display: inline-block;
其中 inline-block 为 “行内块级元素”,其以行内形式显示,但是能设置 width 和 height。
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 个值:
rowrow-reversecolumncolumn-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;
例如,则上述代码将使得子元素沿交叉轴对齐(这对于尺寸不同的子元素非常有用)。
参考
- 《HTML+CSS+JavaScript Web前端开发技术》,聂常红,人民邮电出版社
- 面向开发者的 Web 技术 | MDN