布局

CSS 播客 - 009:布局

假设您是一名开发者 一位设计师同事为你提供一个全新网站的设计方案 设计包含各种有趣的布局和构图: 考虑视口宽度和高度的二维布局, 以及需要流畅、灵活的布局 如何使用 CSS 确定样式的最佳方式?

CSS 为我们提供了多种方法来解决布局问题 或同时设置纵轴和/或横轴 为上下文选择正确的布局方法可能很困难, 通常,您可能需要多种布局方法来解决问题。 为帮助理解这一点,在以下单元中 您将了解每种 CSS 布局机制的独特功能,以便做出明智的决策。

布局:简史

在网络发展的早期阶段 比简单文档更复杂一些的设计则使用 <table> 元素进行布局。 20 世纪 90 年代末,当 CSS 被浏览器广泛采用后,让 HTML 与视觉样式的分离变得更加简单。 CSS 让开发者无需更改 HTML 即可完全改变网站的外观和风格。 这一新功能为 CSS Zen Garden 等项目提供了灵感, 它展示了 CSS 的强大功能,可以鼓励更多开发者学习。

随着我们对网页设计和浏览器技术需求的演变,CSS 也在不断发展。 您可以了解到 CSS 布局是如何发展的,以及我们布局方法的演变过程 作者:Rachel Andrew。

显示 CSS 从 1996 年到 2021 年这些年来演变的时间轴

布局:现在和未来

现代 CSS 具有极其强大的布局工具。 我们有专门的布局系统,接下来我们将大致了解可供我们使用的内容, 我们会在下一单元中详细介绍 Flexbox 和 Grid。

了解 display 属性

display 属性会执行两项操作。 它首先会确定应用此框的框是作为 inline 还是 block。

.my-element {
  display: inline;
}

内嵌元素的行为类似于句子中的字词。 它们按内嵌方向并排排列。 <span> 和 <strong> 等元素, 通常用于为包含元素(例如 <p>、段落)中的文本设置样式, 都采用内联形式 它们还会保留周围的空白。

一张示意图,显示了所有不同大小的盒子以及每个大小调整部分的开始和结束

您无法为内嵌元素设置明确的宽度和高度。 周围的元素将忽略任何块级外边距和内边距。

.my-element {
    display: block;
}

Block 元素不并排放置。 为自己创造了新的界限。除非被其他 CSS 代码更改 一个 block 元素会展开为 inline 尺寸, 因此在水平书写模式下跨越整个宽度。 将遵循块元素四周的外边距。

.my-element {
    display: flex;
}

display 属性还可确定元素的子项的行为方式。 例如: 将 display 属性设置为 display: flex 会使 Box 成为块级框, 并将其子项转换为 flex 项。 这将启用用于控制对齐、排序和流畅的 flex 属性。

Flexbox 和网格

有两种主要的布局机制可以为多个元素创建布局规则:flexbox 和 grid。 它们有相似之处,但旨在解决不同的布局问题。

Flexbox

.my-element {
    display: flex;
}

Flexbox 是一种一维布局的布局机制。 沿单轴布局(水平或垂直)。 默认情况下,Flexbox 会并排对齐元素的子元素, 在内联方向上 沿砌块方向拉伸,使其高度相同。

项在空间用尽后将保持在同一轴上且不换行。 相反,它们会尝试彼此挤压到同一行。 您可以使用 align-items、justify-content 和 flex-wrap 属性更改此行为。

Flexbox 还会将子元素转换为 flex 项, 这意味着您可以编写规则,指定它们在 Flex 容器内的行为方式。 您可以更改单个项的对齐方式、顺序和对齐方式。 您还可以使用 flex 属性更改缩放方式。

.my-element div {
    flex: 1 0 auto;
}

flex 属性是 flex-grow、flex-shrink 和 flex-basis 的简写形式。 您可以按如下方式展开上面的示例:

.my-element div {
 flex-grow: 1;
 flex-shrink: 0;
 flex-basis: auto;
}

开发者提供这些低级规则,以提示浏览器布局的行为方式 当内容和视口尺寸有挑战时。 这使其成为一种非常实用的响应式网页设计机制。

网格

.my-element {
    display: grid;
}

网格在很多方面与 flexbox 相似, 但它旨在控制多轴布局,而不是单轴布局(垂直或水平空间)。

借助网格,您可以在具有 display: grid 的元素上编写布局规则, 并引入了一些用于布局样式的新基元, 例如 repeat() 和 minmax() 函数。 fr 单元是剩余空间的一部分,这是一种非常实用的网格单元。您可以构建传统的 12 列网格, 并在每一项之间留出间隙,使用 3 个 CSS 属性:

.my-element {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

上面的示例展示了单轴布局。 Flexbox 大多将列表项视为一个组, 网格,可让您精确控制其在两个维度中的位置。 我们可以定义此网格中的第一项占据 2 行 3 列:

.my-element :first-child {
  grid-row: 1/3;
  grid-column: 1/4;
}

grid-row 和 grid-column 属性用于指示网格中的第一个元素跨越到第四列的开头, 从第一列开始,然后跨越到第三行(即从第一行开始)。

流布局

如果不使用网格或 Flexbox 您的元素会以正常流程显示。 有许多布局方法可用于调整项在正常流动时的行为和位置。

内嵌块

还记得吗,周围元素是如何不遵循内嵌元素的块外边距和内边距的? 使用 inline-block,您可以导致这种情况。

p span {
    display: inline-block;
}

使用 inline-block 会得到一个具有块级元素某些特征的框, 但仍与文字浑然一体

p span {
    margin-top: 0.5rem;
}

浮点数

如果您有一张图片包含在一段文字中, 用文字环绕在图片周围,就像在报纸中看到的那样,是不是很方便? 您可以使用浮点数做到这一点。

img {
    float: left;
    margin-right: 1em;
}

float 属性指示元素“浮动”向指定方向行驶 此示例中的图片指示其向左浮动, 然后允许同级元素“封装”。 您可以指示元素浮动 left、right 或 inherit。

。

多列布局

如果您的元素列表非常长 例如,列出世界上所有国家/地区 否则可能会为用户带来大量的滚动浏览和时间。 它还会在网页上产生多余的空白。 借助 CSS 多列功能 您可以将其拆分为多个列,以帮助解决这两个问题。

<h1>All countries</h1>
<ul class="countries">
  <li>Argentina</li>
  <li>Aland Islands</li>
  <li>Albania</li>
  <li>Algeria</li>
  <li>American Samoa</li>
  <li>Andorra</li>
  …
</ul>
.countries {
    column-count: 2;
    column-gap: 1em;
}

这会自动将这个长列表拆分为两列,并在两列之间添加间隙。

.countries {
    width: 100%;
    column-width: 260px;
    column-gap: 1em;
}

您不必设置将内容拆分到多少列, 您还可以使用 column-width 定义所需的最小宽度。 随着视口中的可用空间越来越多 随着空间的减少,系统会自动创建更多列 列也会减少。 这在响应式网页设计环境中非常有用。

定位

下面我们要简单介绍一下布局机制,即定位。 position 属性可更改元素在文档正常流程中的行为方式, 以及它与其他元素之间的关系 可用选项包括 relative、absolute、fixed 和 sticky,默认值为 static。

.my-element {
  position: relative;
  top: 10px;
}

根据该元素在文档中的当前位置,将它下移 10 像素。 与自身为相对位置 向元素添加 position: relative 也会使其成为具有 position: absolute 的所有子元素的包含块。 这意味着其子项现在将被重新放置到这个特定元素上, 而不是最顶层的相对父项,则它会应用绝对位置。

.my-element {
  position: relative;
  width: 100px;
  height: 100px;
}

.another-element {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 50px;
    height: 50px;
}

将 position 设置为 absolute 时, 它会将相应元素从当前文档流中分离开来 这意味着有两点:

  1. 您可以使用 top、right、bottom 和 left 在其最接近的相对父项中随意定位此元素。
  2. 绝对元素周围的所有内容都会重排以填充该元素剩余的剩余空间。

position 值为 fixed 的元素的行为方式与 absolute 类似, 其父项是根 <html> 元素。 固定位置元素会根据您设置的 top、right、bottom 和 left 值从左上角锚定。

您可以实现锚定、 通过使用 sticky,修复了 fixed 的方面以及 relative 中可预测的文档流程执行方面的更加可预测性。 使用此值时,当视口滚动越过该元素时, 它会固定在您设置的 top、right、bottom 和 left 值上。

小结

CSS 布局具有丰富的选择和灵活性。 要深入了解 CSS Flexbox 和 Grid 的强大功能,请继续学习接下来的几个单元。

检查您的理解情况

测试您对布局知识的掌握情况

display 属性有哪两项作用?

确定 inline、block 或 none。
布局引擎需要知道此框是否为全宽,以及是否需要换行。
确定网格布局帧。
display 属性可以将 display 设置为 grid,但与布局框架无关。
确定子元素的行为方式。
Flexbox 和网格可为孩子提供观点和新功能。
确定是否应滚动该框。
也就是 overflow 属性。

将多个段落拆分成多个列,哪个 CSS 属性最适合 任务?

display: grid
虽然网格可以将多个段落放入多个列中,但这些列将是各自的列,而不是从一个列指向下一个列。
column-count
段落将从一列的末尾移动到下一列的开头,就像杂志或报纸一样。
display: flex
虽然 flex 可以将多个段落放入列中,但这些列将是自己的列,不需要像以前一样从一个列流向下一个列。
float
再试一次!

如果某个块不在流程下方,这意味着什么?

它卡在河边了。
这里的上下文是 CSS,而不是地理位置。
已指定 top 或 left 位置值。
仅具有这些属性并不会使流程脱离流程。
系统不再根据同级元素的位置来确定合适的位置。
例如,具有 position: absolute 的框现在的位置是 x 和 y 坐标(基于包含块,而不是其与其他同级元素的顺序)确定的。

Flexbox 和 Grid 是否默认封装其子项?

正确
必须通过 flex-wrap: wrap 或 repeat(auto-fit, 30ch) 选择启用。
错误
Flexbox 和网格具有特殊的环绕功能,需要其他样式才能应用。