CSS 零基础教程

CSS 百分比布局

CSS 中的 百分比(Percentages)提供了一种灵活的方式来创建响应式布局,使其能够适应不同的屏幕尺寸。

与像素(px)等固定单位不同,百分比是相对于其父元素(包含块)的尺寸计算的。这使得元素可以按比例缩放,从而在各种设备上保持预期的外观。

本章将探讨如何有效地使用百分比来构建基础的响应式布局。

1. 理解基于百分比的宽度

在响应式设计中,百分比最常见的用途是设置元素的 width 属性。当你将元素的宽度设置为百分比时,它是根据其父容器的宽度来计算的。

1.1 基础示例:两栏布局

假设我们需要一个简单的两栏布局,两个 <div> 元素各占父容器宽度的 50%。

HTML 代码:

<div class="container">
  <div class="column">Column 1</div>
  <div class="column">Column 2</div>
</div>

CSS 代码:

.container {
  width: 80%; /* 容器占据其父元素宽度的 80% */
  margin: 0 auto; /* 水平居中容器 */
}
.column {
  width: 50%; /* 每个列占据容器宽度的 50% */
  float: left; /* 让列并排浮动 */
  box-sizing: border-box; /* 关键:将内边距和边框包含在总宽度内 */
  padding: 20px;
  border: 1px solid #ccc;
}

在这个例子中:

  • .container 设置为 80% 宽度,这意味着它将占据 <body> 元素(假设 <body> 是其包含块)宽度的 80%。margin: 0 auto; 用于将其水平居中。
  • .column 元素设置为 50% 宽度,因此每个列将占据 .container 宽度的一半。
  • float: left; 用于让两列并排显示。(我们将在后续模块中学习像 Flexbox 这样更现代的布局技术)。
  • box-sizing: border-box; 非常关键。如果没有它,内边距(padding)和边框(border)会额外增加到 50% 的宽度之上,导致总宽度超过 100%,从而迫使列换行。

2. 解决 Padding 和 Border 带来的问题

如上所示,在使用百分比宽度并同时使用 padding 或 border 时,必须加上 box-sizing: border-box;。否则,布局可能会崩坏。

错误示例(未使用 box-sizing):

.column {
  width: 50%;
  float: left;
  padding: 20px;
  border: 1px solid #ccc;
}

在这种情况下,每个 .column 的实际宽度将是:50% + 20px (左内边距) + 20px (右内边距) + 1px (左边框) + 1px (右边框)。这显然超过了 50%,会导致布局错乱。

3. 嵌套百分比 (Nested Percentages)

百分比是可以嵌套使用的。如果一个设置了百分比宽度的元素位于另一个同样设置了百分比宽度的元素内部,那么它的宽度是相对于直接父元素计算的。

示例:HTML:

<div class="outer">
  <div class="inner">内部内容</div>
</div>

CSS:

.outer {
  width: 75%; /* 外层 div 占据其父元素的 75% */
  background-color: #eee;
  padding: 20px;
}
.inner {
  width: 80%; /* 内层 div 占据外层 div 的 80% */
  background-color: #ddd;
  margin: 0 auto; /* 居中内层 div */
  padding: 10px;
}

在这里,.outer 是其父元素的 75%,而 .inner.outer 的 80%。因此,.inner 的实际绝对宽度是“祖父”元素宽度的 75% 的 80%。

4. 基于百分比的高度

虽然不如宽度常用,但你也可以对 height 属性使用百分比。但是,百分比高度只有在包含块(父元素)具有明确定义的高度时才有效。

如果父元素的高度是由其内容决定的(默认行为),那么子元素的百分比高度将被解析为 auto(无效)。

4.1 示例 1:父元素有明确高度(有效)

HTML:

<div class="container">
  <div class="content">这个内容将占据容器高度的 50%。</div>
</div>

CSS:

.container {
  width: 300px;
  height: 400px; /* 明确的高度 */
  background-color: #f0f0f0;
}
.content {
  width: 100%;
  height: 50%; /* 容器高度 (400px) 的 50% */
  background-color: #ddd;
}

在这个例子中,.content 的高度是 200px。

4.2 示例 2:父元素高度未定义(无效)

CSS:

.container {
  width: 300px;
  /* height: 400px; 没有设置明确高度 */
  background-color: #f0f0f0;
}
.content {
  width: 100%;
  height: 50%; /* 容器高度为 auto,因此这里也是 auto */
  background-color: #ddd;
}

这种情况下,.content 的高度将由其文本内容决定,而不是容器高度的 50%。

5. 使用 vh 和 vw 设置视口相关高度

如果想让元素的高度相对于浏览器视口(Viewport),可以使用 vh(视口高度)单位。1vh 等于视口高度的 1%。

示例:

.container {
  width: 100%;
  height: 100vh; /* 占据整个视口高度 */
  background-color: #f0f0f0;
}
.content {
  width: 50%;
  height: 50vh; /* 占据视口高度的一半 */
  background-color: #ddd;
}

同理,vw 代表视口宽度。

6. 基于百分比的 Margin 和 Padding

你也可以对边距(margin)和内边距(padding)使用百分比。

重点记住:基于百分比的 margin 和 padding 永远是相对于包含块的“宽度”计算的,即使是 margin-top(上外边距)、margin-bottompadding-toppadding-bottom 也是如此。

6.1 示例 1:相等的上下内边距

.box {
  width: 200px;
  padding: 10%; /* 四个方向都是宽度的 10% (即 20px) */
  background-color: #f0f0f0;
}

这里,.box 四周的 padding 都是 20px(200px 的 10%)。

6.2 示例 2:垂直外边距

.element {
  width: 300px;
  margin-top: 5%; /* 宽度的 5% (即 15px) */
  margin-bottom: 5%; /* 宽度的 5% (即 15px) */
  background-color: #ddd;
}

这里,.element 的上下外边距都是 15px。

7. 综合应用:响应式布局

百分比的真正威力在于组合使用,从而创建灵活的布局。

7.1 示例 1:响应式图片画廊

HTML:

<div class="gallery">
  <img src="image1.jpg" alt="Image 1">
  <img src="image2.jpg" alt="Image 2">
  <img src="image3.jpg" alt="Image 3">
</div>

CSS:

.gallery {
  width: 90%;
  margin: 0 auto;
}
.gallery img {
  width: 30%;
  margin: 1%;
  float: left;
}

在这个例子中,.gallery 占据屏幕宽度的 90% 并居中。每张图片占据画廊宽度的 30%,并带有 1% 的边距。这创建了一个响应式画廊,图片会随着屏幕大小变化按比例缩放。

注意:此示例使用了 float:left; 进行布局。在后续模块中,我们将学习 Flexbox 和 Grid 等更现代的技术。