CSS 布局
简介
CSS 中有多种布局方法,实现页面布局的主要方法是设定 display 属性的值,该属性可以控制元素在页面上的显示方式。文档流中所有的内容都有一个 display 的值,用作元素的默认行为方式。这里列举几种常见的方法
- 正常流
- 弹性盒
- 网格
- 多列布局
- 浮动
- 定位
- 响应式设计
正常流
正常流(Normal flow,又称文档流)是 CSS 布局的基础,即当没有对元素应用浮动(floats)、定位(positioning)或者现代布局技术(如 Flexbox 或 Grid)时,浏览器默认的布局方式。正常流分为两个方面:块级元素(block-level elements)布局和行内元素(inline-level elements)布局。
- 块级元素布局:
块级元素在正常流中独占一行,并在其上下生成新行。它们沿着垂直方向一个接一个地排列,按照它们在 HTML 文档中出现的顺序。宽度默认填满其父元素的剩余水平空间,但可以通过设置
width或max-width来修改。高度由内容、内边距(padding)和边框(border)决定,可以使用height或min-height进行调整。常见的块级元素有<div>、<p>、<h1>-<h6>、<ul>、<ol>、<li>等。
- 行内元素布局:
行内元素在正常流中与其他行内元素一起排列在同一行上,从左到右。如果容器的宽度不足以容纳所有行内元素,那么它们会自动换行。行内元素的宽度和高度由内容、内边距和边框决定,不能直接设置
width和height属性。常见的行内元素有<span>、<a>、<img>、<em>、<strong>等。
对于网页内的大部分元素,正常流完全可以创建所需要的布局,因此一个结构良好的 HTML 文档是非常必要的。当遇到复杂布局问题时,也可以通过下列布局技术覆盖默认的布局行为:
- Display
使用
display属性可以控制元素的显示类型。如:block, inline, inline-block 或其他新增的布局方式(如:CSS Grid 和 Flexbox)。
- Float
使用
float属性设置元素向左 (float: left) 或向右 (float: right) 浮动,浮动元素会脱离正常文档流,并根据空间自动调整位置。然后,其他元素将沿着被浮动元素的边缘排列。 然而,当一个父元素包含浮动的子元素时,通常会发生高度塌陷现象,这意味着父元素不会自动扩展其高度以适应浮动子元素。结果就是页面布局出现错误,可能导致相邻的元素发生重叠,这时就需要清除浮动。清除浮动 (Clearfix) 是一个常用技术,用于消除浮动元素对其父元素和其他元素的影响。以下是一个经典的
clearfix解决方案:
.clearfix::after {
content: "";
display: table;
clear: both;
}
要使用
clearfix,只需将它添加到包含浮动元素的父元素的类(class)上,父元素的高度将自动扩展以适应浮动的子元素,从而解决高度塌陷问题。
<div class="parent clearfix">
<div class="child" style="float: left;"></div>
<div class="child" style="float: left;"></div>
</div>
- Positioning
使用
position属性,允许你精准设置盒子中的盒子的位置;可以将元素定位到相对于其正常位置、相对于其最近的定位祖先元素或相对于视口的特定位置;有四个值:static(默认值)、relative、absolute和fixed,使用top、right、bottom和left属性设置具体的偏移。
- Table
表格的布局方式可以用在非表格内容上,使用
display: table可以将元素布局为表格,这在某些场景下非常实用。table、table-row和table-cell分别对应 HTML 的<table>、<tr>和<td>元素。
- Multi-column layout
使用多列布局方法,可以将内容分为多个列,就像报纸或杂志上的文本那样。将
column-count和column-gap属性分别设置为所需的列数和列间距。
弹性盒
弹性盒子(Flexible Box,简称 Flexbox)是一种 CSS 布局模型,用于在一维空间(即行或列)内更灵活地对齐和分布元素,Flexbox 能够自动调整元素的大小和顺序,使其适应不同屏幕尺寸和分辨率。Flexbox 是一个强大且灵活的布局工具,特别适用于响应式设计和对齐方式复杂的场景。要使用 Flexbox,需要将 display 属性设置为 flex 或 inline-flex(行内弹性盒子)。
.container {
display: flex;
}
Flexbox 模型分为 弹性盒(flex container)、 弹性子项(flex item)、主轴(main axis)和 交叉轴(cross axis);
设置了 display: flex 的父元素称为弹性盒,而在弹性盒中表现为弹性盒子的元素称之为弹性子项;主轴是沿着 flex 元素放置的方向延伸的轴(如页面上的横向的行、纵向的列);交叉轴是垂直于 flex 元素放置方向的轴。
在布局时可以使用以下 Flexbox 属性来进行控制:
-
flex-direction指定主轴的方向,决定了弹性子项如何排列。可选值有row(默认值,水平排列)、row-reverse、column(垂直排列)和column-reverse。 -
justify-content:控制沿主轴的对齐方式。可选值有flex-start(起点对齐,这是默认值)、flex-end(终点对齐)、center(居中对齐)、space-between(两侧对齐,子项之间间距相等)、space-around(每个子项两侧间距相等)和space-evenly(子项之间和两边边界的间距相等)。 -
align-items:控制沿交叉轴的对齐方式。可选值有stretch(默认值,拉伸占满容器高度)、flex-start(起点对齐)、flex-end(终点对齐)、center(居中对齐)和baseline(基线对齐)。 -
flex-wrap:控制是否以多行(或多列)方式排列子项。可选值有nowrap(默认值,不换行)和wrap(换行)。 -
align-content:当存在多行(或多列)时,控制行(或列)之间的对齐方式。可选值有stretch(默认值,拉伸占满容器高度)、flex-start(起点对齐)、flex-end(终点对齐)、center(居中对齐)、space-between(两侧对齐,行之间间距相等)、space-around(每行两侧间距相等)和space-evenly(行之间和容器边界的间距相等)。
对于每个弹性子项,还可以设置以下属性:
-
order:控制子项的排列顺序。默认值为 0,数字越小,排列越靠前。 -
flex-grow:设置子项的扩展比例。默认值为 0,表示不扩展。若所有子项的flex-grow相同,则它们将平均分配剩余空间;若值不同,则按照比例分配剩余空间。 -
flex-shrink:设置子项的收缩比例。默认值为 1,表示子项会根据比例收缩以适应容器。若值为 0,则表示子项不收缩。 -
flex-basis:设置子项的基础尺寸,在此基础上进行扩展和收缩。默认值为auto,表示使用子项的实际尺寸。 -
align-self:允许单独设置某个子项在交叉轴上的对齐方式,覆盖容器的align-items设置。可选值与align-items相同。
网格
CSS 网格布局(CSS Grid Layout)是一个用于 web 的二维布局系统,可以把内容按照行与列的格式进行排版。这种布局方式有助于简化复杂的页面设计,轻松地实现一些复杂的布局,并提高响应式设计效率。
网格是由一系列水平及垂直的线构成的一种布局模式。一个网格通常具有许多的列(column)与行(row),以及行与行、列与列之间的间隙,这个间隙一般被称为沟槽(gutter);根据网格,我们能够将设计元素进行排列,帮助我们设计一系列具有固定位置以及宽度的元素的页面,使我们的网站页面更加统一。
创建一个 CSS 网格布局,需要先将一个父容器元素的 display 属性设置为 grid:
.container {
display: grid;
}
同时可以使用一些关键的 CSS 属性来定义网格布局
-
grid-template-columns和grid-template-rows: 用于定义网格的列和行大小。可以用像素、百分比或者fr(用于描述剩余空间的单位)来设置网格轨道(grid track)的尺寸。例如:grid-template-columns: 1fr 200px 3fr;定义了一个三列网格,第一列和第三列分别占据剩余空间的 1/4 和 3/4,而第二列宽度固定为 200px。 -
grid-column-gap和grid-row-gap: 用于设置网格间距。例如:grid-column-gap: 16px; grid-row-gap: 16px;。还可以用grid-gap这个简化属性同时设置行和列的间距,如:grid-gap: 16px 24px;(这里,16px 为行间距,24px 为列间距)。 -
grid-template-areas: 这个属性用于为网格项定义区域名称并映射到网格布局中。例如:
.container {
grid-template-areas:
"header header header"
"sidebar content content"
"footer footer footer";
}
可以利用 grid-area 属性将网格项目分配给相应的区域:
.header {
grid-area: header;
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.footer {
grid-area: footer;
}
-
justify-items和align-items:控制所有网格项沿水平轴(主轴)和垂直轴(交叉轴)的对齐方式。可用值包括start、end、center和stretch(默认值,使元素填满整个网格单元)。 -
justify-content和align-content:当网格容器的大小大于网格内容时,这两个属性用于控制整个网格在容器里的位置。
针对单个网格项,可以使用以下属性进行布局:
-
grid-column-start、grid-column-end、grid-row-start和grid-row-end:这些属性定义了网格项的起始和结束位置。例如:grid-column-start: 2; grid-column-end: 4;表示该项从第二列开始,并延伸至第四列。 -
grid-column和grid-row:这是简化属性,它们分别用于设置网格项的列起始/结束位置和行起始/结束位置。例如:grid-column: 2 / 4;(与上述示例等效)。 -
grid-area:用于设置网格项的行和列起始/结束位置,或将网格项分配到grid-template-areas中定义的区域。
多列布局
CSS 多列布局(Multi-column Layout)是一种让文本或其他内容自动流动并跨越多列的布局方法,这种布局方式类似于报纸或杂志中的排版,使得阅读长篇文字更加舒适
可以使用以下 CSS 属性来实现多列布局:
column-count:指定布局中的列数。例如,设置column-count: 3;将文本分为三列。
.container {
column-count: 3;
}
column-width:定义每一列的理想宽度。浏览器将尽量满足这个要求,但具体宽度可能会有所调整以适应容器的宽度。例如,设置column-width: 200px;将尝试确保每列宽度至少为 200px。
.container {
column-width: 200px;
}
注意:
column-count和column-width可以同时使用,但如果它们产生冲突(即给定的宽度和数量无法适应容器大小),浏览器将优先考虑column-count。
column-gap:定义相邻列之间的间距。可以使用像素、百分比等单位。例如,设置column-gap: 20px;将在列之间保持 20px 的间距。
.container {
column-gap: 20px;
}
column-rule:在相邻列之间绘制一条分隔线。这个属性是一个简写,可设置分隔线的宽度、样式和颜色。例如:column-rule: 1px solid #ccc;将添加一条 1px 宽且颜色为灰色的实线。
.container {
column-rule: 1px solid #ccc;
}
columns:这是一个简写属性,用于同时设置column-count和column-width。例如:columns: 3 200px;将尝试创建三列,每列宽度至少为 200px。
.container {
columns: 3 200px;
}
创建一个多列布局,只需将上述属性应用到包含文本或内容的父容器上。示例:
<div class="container">
<p>只需将上述属性应用到父容器上</p>
</div>
.container {
columns: 3 200px;
column-gap: 20px;
column-rule: 1px solid #ccc;
}
上面用例将把段落文本分成三列,每列至少宽 200px,列间距为 20px,并在列之间添加一个分隔线。