β

CSS布局指南

W3CPlus 3 阅读

特别声明,本文根据@Rachel Andrew的《 Getting Started With CSS Layout 》一文整理。

在过去几年中,CSS布局已经发生了巨大的变化,现在我们开发网站的方式也发生了巨大变化。现在我们有需要可选的CSS布局方式来开发我们的网站,这也就要求我们对这些方式能作出正确而双合适的选择。在这篇文章中,将会介绍各种CSS布局的基本使用方式以及使用的目的。

如果你还是CSS方面的新手并且又想了解什么才是最好的布局方式,那么这篇文章正是你所需要的。如果你是一位比较有经验的开发者,想要了解一些关于CSS布局的最新知识,那么这篇文章值得你花费一点时间去阅读。当然,这篇文章并没有涉及CSS布局相关技术的细节,不然,围绕这个主题都可以写一本书了。不过,文章会对各种CSS布局做一个基本的概述,同时会给大家提供相关链接来进一步加强相关技术的学习。

正常文档流

如果你选择没有用任何CSS来改变页面布局的网页,那么HTML元素就会排列在一个 正常流(Normal Flow) 之中。在正常流中,元素盒子(任何一个HTML元素其实就是一个盒子)会基于文档的写作模式一个接一个地排列(根据不同的文档写作模式,排列方向不一样)。这就意味着,如果你的写作模式是水平的(句子是从左到右或从右到左写),正常流会垂直地一个接一个排列页面的块级元素。如果你是在一个垂直方向的写作模式下,句子是垂直方向书写的,那么块级元素会水平方向排列。

正常流是一种最苦的布局:当你的文档应用了CSS、创建了某些CSS布局,这些块就做了一个正常文档流之外的事。

通过页面结构来发挥正常文档流的优势

通过确保书写的页面具有良好的结构(HTML结构),如此一来就可以最大程度复用正常文档流所带来的优势。试想一下,如果浏览器中没有正常流,那么你创建的HTML元素都会堆积在浏览器的右上角。这就意味着,你必须指定所有的HTML元素的布局方式。

有了正常流,哪怕是CSS加载失败了,用户仍然能阅读你的页面内容;同时,一些不使用CSS的工具(例如屏幕阅读器)会按照元素在文档中的位置来读取页面内容。另外从可用性角度来看,这无疑是非常有帮助的,同时也让开发者轻松了一些。如果你的内容顺序和用户预期的阅读顺序一致,那就不需要为了将元素调整到正确的位置而做大量的布局调整。当你继续往下阅读,将会发现,使用新的布局方式是如何让页面布局达到事半功倍的。

因此,在思考如何布局之前,你需要认真思考你的文档结构,以及你希望用户以何种顺序来阅读文档中的内容。

脱离正常文档流

一旦页面有一个良好的结构,你就需要去决定如何利用它并将它变为我们需要的布局结构。这会涉及到脱离正常文档流(后续会详细阐述这部分)。我们有许多布局的“神器”可用,其中第一个要介绍的就是 float ,它是一个描述什么是脱离正常文档流的非常好的例子。

扩展阅读

浮动

浮动被用来将元素盒子向左或向右移动,同时让内容环绕其展示。

要让一个元素进行浮动,需要给该元素的 flaot 属性设置为 left right float 的默认值为 none

.item {
    float: left
}

值得注意的是,当你使某个元素浮动并让文字环绕它时,内容的行框(Line Box)被缩短。如果你让一个元素浮动,同时为紧跟着的包含文本的元素设置一个背景颜色,你会发现背景色会出在浮动元素下方。

如果想要在浮动元素和环绕的文本之间有一定的间距,需要给浮动元素设置 margin 。在文本元素上设置 margin 只会让其相对于容器缩进。例如在下面这个例子中,你就需要为左侧浮动的图片设置右边距和下边距。

清除浮动

一旦对一个元素进行了浮动,所有接下来的元素都会环绕它,直到内容处理它下方且开始应用正常文档流。如果想要避免这种情形,可以手动清除浮动。

如果不想要在某个元素受到其之前的浮动元素影响时,可以为其添加 clear 属性。 left 值表示清除左边的浮动, right 值表示清除右浮动, both 值表示清除左右两边的浮动。

.clear {
    clear: both;
}

如果希望元素在浮动元素之后开始排列,那么上面的代码可以达到你的需求。如果你发现在容器内有一个浮动元素,同时容器内文本内容过短时,就会出现问题。文本盒子会被绘制在浮动元素下,然后接下来的部分会以正常流方式绘制在其后。

为了避免这种情况,我们需要为容器中某个元素应用 clear 属性。我们可以在容器中最后添加一个空元素并设置 clear 属性。但是在某些情况之下可能无法使用这种方式(例如一些CMS系统生成的页面,HTML结构是很难重构)。因此,最常见的清除浮动的方案是:在容器内添加一个CSS伪元素,并将其 clear 的值设置为 both

块级格式化上下文

清除浮动的另一个方法是在容器内创建BFC(块格式化上下文,Block Formatting Context)。一个BFC元素完全包裹住了它内部的所有元素,包括内部的浮动元素,保证浮动元素不会超出其底部。创建BFC方式有很多种,其中最常见的方法是给其 overflow 属性设置为 visible 之外的值。

.container {
    overflow: auto;
}

像上面这样使用 overflow ,一般情况下是有效的,可以清除浮动。但是在某些情况下,可能会裁掉一些 box-shadow 或是出现滚动条(事实上你并不想滚动条出现)。同时,它在样式表中看起来也有点混乱:设置 overflow 其实是想要滚动条的出现,而此处却仅仅是用来清除浮动。那么设置 overflow 到底是想要滚动条出现,还是清除浮动呢?

为了使用清除浮动的意图更加直观,并且避免BFC的负面影响,可以使用 display flow-root 来清除浮动。 display: flow-root 做的唯一的一件事就是去创建BFC,因此可以避免其他创建BFC方法带来的副作用。

.container {
    display: flow-root;
}

浮动的一些遗留用法

在新的布局方式出现以前, float 经常用来创建多列布局。我们会给一系列元素设置 width 并且将它们一个接一个的进行浮动。通过为浮动元素设置一些精细的百分比大小可以创建类似网格的效果。

我不建议在当下仍然过渡的使用浮动来布局。但是,在现有的网站中,这种布局方式仍然会存在许多年。因此,当你碰到一个页面到处是 float 的时候,可以确定它就是用的浮动布局。

扩展阅读

定位

想要把一个元素脱离正常文档流或者改变其在正常文档流中的位置,可以使用CSS的 position 属性。在正常文档流中,元素的 position 的值为 static (也是 position 的默认值)。在块级维度上元素会一个接一个排列下去,当你滚动页面时,元素也会随着滚动。

当改变元素 position 属性时,通常也会设置一些偏移量来使元素相对于参照物进行一定的移动。不同的 position 值会产生不同的参照物。

相对定位

如果一个元素设置了 position 属性的值为 relative ,那么它偏移的参照位是其自身原先在正常文档流中的位置。可以使用 top right bottom left 属性将元素相对其正常文档流位置进行移动。

.item {
    position: relative;
    bottom: 50px;
}

请注意,页面上的其他元素并不会因该元素的位置变化而受到影响。该元素在正常文档流中的位置会被保留,因此你需要自己去处理一些元素内容覆盖的情况。

绝对定位

元素的 position 属性值为 absolute 可以将其完全脱离正常文档流。其原本占据的空间也会被移除。该元素定位会相对于视窗容器,除非其某个祖先元素的 position 值设置了非 static

因此,当你为某个元素设置 position: absolute 时,首先发生的变化是该元素会定位在视窗的左上角。你可以通过 top right bottom left 属性设置偏移量,将元素移动到你想要的位置。

.item {
    position: absolute;
    top: 20px;
    right: 20px;
}

通常情况下,你并不希望元素相对于视窗进行定位,而是相对于容器元素。在这种情况下,需要为容器元素设置一个除了默认值 static 之外的其他值。

由于给元素设置 position:relative 并不会将其从正常文档流中移除,所以一般情况之下是一个很好的选择。给你想要相对的容器元素设置 position:relative ,就可以让绝对定位的元素相对其进行偏移。

固定定位

大多数情况下, position:fixed 的元素会相对于视窗定位,并且会脱离正常文档流,同样也不会保留该元素所点点据的空间。当页面滚动时,固定的元素会留在相对于视窗的位置,而其他正常文档流中的内容则和往常一样滚动。

.item {
    position: fixed;
    top: 20px;
    left: 100px;
}

当你想要一个固定导航栏一直停留在屏幕上时,这种做法非常有效。和其他 position 值(除 static 之外)一样,也可能会造成一些元素被遮盖,需要小心保证页面内容的可读而不会被固定元素遮挡。

如果需要使一个固定元素不是相对于视窗进行定位,那么需要为容器元素设置 transform perspective filter 三个属性之一(不能取其默认值 none )。这样固定的元素就会相对于该块元素偏移,而不是相对于视窗。

黏贴定位(Sticky)

设置 position: sticky 会让元素在页面滚动时如同在正常流中,但当其滚动到相对于视口的某个特定位置时就会固定在屏幕上,如同 fixed 一般。这个属性值是 position 属性的一个新值,在浏览器兼容性上会差一些,但在不兼容的浏览器中会被忽略并会退到正常的滚动情况。

.item {
    position: sticky;
    top: 0;
}

下面的代码展示了如何创建一个非常流行导航栏效果:导航栏会随着页面滚动,而当导航栏滚动到页面顶部时则会固定在顶部位置。

扩展阅读

Flex布局

Flexbox布局是一种用于一维布局而设计的布局方法。一维的意思是你希望内容是按照行或者列来布局。你可以在元素上将 display 设置为 flex 值,把该元素为变弹性布局。

.container {
    display: flex;
}

该容器的直接子元素会变为弹性项(Flex Item),并按行排列。

Flexbox的轴

在上面的示例中,弹性项在行内是从起始位置开始排列,而不是说它们是左对齐。这些元素会按行排列是因为 flex-direction 的默认值为 row row 代表了文本的行文方向。由于我们的工作环境是英文,一种自左向右的语言,行的开始位置就在左边,因此我们的弹性项也是从左边开始的。因此, flex-direction 的值被定义为Flexbox的主轴(Main Axis)。

交叉轴(Cross Axis)则是和主轴相互垂直的一条Flexbox轴。如果 flex-direction row ,并且弹性项是按照内方向排列的,那么交叉轴就是块级元素的排列方向。如果 flex-direction column ,那么弹性项就会以块级元素排列的方向排列,然后交叉轴就会变为 row

如果你习惯于从主轴与交叉轴的角度来使用Flexbox盒子,那么一切会变得非常简单。

方向和顺序

Flexbox允许我们通过 flex-direction 属性设置为 row-reverse column-reverse 值来改变主轴上弹性荐的方向。

当然,也可以通过 order 属性来改变某一个弹性项的顺序。但是要特别注意,这可能会给那些通过键盘(而非鼠标或触屏)访问你的网站的用户带来一些麻烦,因为 tab 的顺序是页面内元素在源码中的顺序而非显示顺序。你可以阅读之后的“显示和文档顺序”部分来了解更多相关内容。

flex属性

flex 的属性是用来控制弹性项在主轴上空间大小的。他是下面三个属性的简写方式:

  • flex-grow
  • flex-shrink
  • flex-basis

简写的 flex 属性会有三个值,第一个值是 flex-grow ,第二个是 flex-shrink ,第三个是 flex-basis

.item {
    flex: 1 1 200px;
}

flex-basis 会为弹性项设置未拉伸和压缩时的初始大小。在上面的例子中,大小是 200px ,因此我们会给每个项 200px 的空间大小。但是大多数情况下容器元素大小不会正好被分为许多 200px 大小的项,而是可能有一些不足或剩余空间。 flex-grow flow-shrink 属性允许我们在容器大小不足或有空余时控制各个弹性项的大小。

如果 flex-grow 的值是任意的正数,那么弹性项会被允许拉伸来占据更多的空间。因此,在上面的例子中,当各项被设为 200px 后,所有多余的空间会被每个弹性项平分并填满。

如果 flex-shrink 的值为任意的正数,那么当弹性项被设置了 flex-basis 后,元素溢出容器时会进行收缩。在上面这个CSS的例子中,如果容器空间不足,每个弹性项会等比例缩放以适应容器的大小。

flex-grow flex-shrink 的值可以是任意的正数。一个具有较大 flex-grow 值的弹性项会在容器有剩余空间时拉伸更大的比例;而一个具有更大 flex-shrink 值的项则会在容器空间不足时被压缩的更多。

理解这些属性是理解如何使用弹性布局的关键,下面列出的一些资源会帮助我们进一步学习其中的细节。当你需要在容器的一个维度上拉伸或者压缩一些元素时,你可以考虑使用弹性盒子模型。如果你发现你正尝试在行和列两个维度上排列你的内容,你需要的是网格模型(grid),这时弹性盒子模型很可能不是最合适的工具了。

扩展阅读

Grid布局

CSS Grid布局是一种用来进行二维布局的技术。二维意味着你希望按照行和列来排布你的内容。和Flexbox类似,Grid布局也需要设置一个 display 值。你可以为容器元素设置 display: grid ,并且使用 grid-template-columns grid-template-rows 属性来控制网格中的行与列。

.container {
    display: grid;
    grid-template-columns: 200px 200px 200px;
    grid-template-rows: 200px 200px;
}

上面这段CSS会创建一个行列元素大小固定的网格。不过这也许并不是你希望的。默认值为 auto ,你可以认为这代表了“让格子尽可能的大”。如果你每没有指定行的大小,所有添加进来的行内容大小都会被置为 auto 。一种常用的模式是为网格制定列宽度,但是允许网格按需添加行。

你可以使用任意的长度单位或时百分比来设置行与列,同时你可以使用为网格系统所创造的新的单位—— fr fr 是一种弹性单位,它可以指定网格容器内的空间被如何划分。

网格会替你计算与分配空间,你不需要去计算元素的百分比去适应容器大小。在下面这个例子中,我们使用 fr 来创建网格的列,这使得网格的列可以自适应。同时我们还使用了 grid-gap 来保证元素间的间距(关于网格内元素与的间距会在“对齐”这一部分详细介绍)。

这个就像Flexbox布局中的 flex-grow flex-shrink 一样, fr 会根根Grid容器的空间给Grid项目分配可用空间。如果 fr 的值较大,这意味着对应的网格轨道可以获得更多可用空间。你也可以将 fr 和固定长度混合在一起使用。在计算 fr 之前,长度所需的空间将从可用空间中减去。

网格术语

网格系统总是有两个轴:行内轴(Inline Axis)表示页面中文字的文字排列的方向,块轴(Block Axis)表示页面中块级元素的排列方向。

一个被设置为 display: grid 的元素就是所谓的网格容器。在网格容器中会有网格线(Grid Line),网格线就是你在指定 grid-template-columns grid-template-rows 时网格中行列所生成的。网格中的最小单位(也就是被四条网格线截取生成的区域)被成为网格单元格(Grid Cell),进一步的,由若干个单元格组成的矩形区域被成为网格区域(Grid Area)。

上图中的虚线是网格线

两条网格线之间的区域是网格轨道(网格的行或列)

网格单元格和网格区域

网格的自动排列规则

一旦你创建了网格,那么网格容器的直接子元素就会开始将它们自己一个一个地放置在网格的单元格中。子元素的放置是依据网格的自动排列规则。这些规则确保了网格内元素是被安排在各个空的单元格中,而不会彼此遮盖。

网格中任何没有被进行定位的直接子元素都会根据自动排列规则进行放置。在下面这个列子中,我让每三个元素中的第一个占据两行,但仍然从起始行开始去自动排列。

基于行或列的定位

定位网格元素最简单的方式是使用基于行或列网格的定位方法,只需告诉浏览器从哪一排到哪一排来进行合并。例如,如果你需要一个 2 x 2 的网格区域,你可以将指定元素从第一行开始到第三行、从第一列开始到第三列,这样就可以覆盖到四个单元格。

.item {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 3;
}

这些属性可以用缩写来表示: grid-column grid-row ,其中起一个值代表起始值,第二个值代表结束值。

.item {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
}

你也可以让网格项占据同一个单元格。支持一些内容间会覆盖的设计。网格项会像通常网页中的元素那样叠起来,在 html 源码中下面的网格项会叠在其他元素上面。你仍然可以用 z-index 来控制它的堆叠顺序。

通过命名区域来定位元素

你可以通过命名网格区域来定位网格中的元素。要是用这种方式,你需要给每个元素一个名字,然后通过 grid-template-areas 属性的值来描述布局方式。

.item1 {
    grid-area: a;
}
.item2 {
    grid-area: b;
}
.item3 {
    grid-area: c;
}
.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
    "a a b b"
    "a a c c";
}

使用这种方式有几个需要注意的点。如果你想要合并一些单元格作为你的网格项,你需要重复元素的名字。网格区域需要能形成一个完整的矩形 —— 每个单元格都需要被填入一个值。如果你想要空出某些单元格,那就需要使用 . 这个值。例如在下面的CSS里我将最右下角的单元格留空。

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
    "a a b b"
    "a a c .";
}

你也可以通过下面这个Demo的代码来看看实际的布局效果。

这篇文章只包括了CSS Grid布局的一些初级内容,其中还有非常多的内容值得学习,下面的一些资料可以帮助你进一步学习。一些组件或整个页面的布局都可以使用网格。如果你需要在两个维度进行布局,网格布局是一个不错的选择 —— 不论需要布局的区域的大小。

扩展阅读

显示顺序 vs 文档顺序

在文章的最开始,我建议你以从上到下的阅读顺序来组织你的文档顺序,这样会有助于可读性和CSS的布局方式。从我们关于Flexbox和CSS Grid 布局的简短介绍来看,你可能发现用这些布局方法可能会极大地改变页面元素在文档中展示的顺序。这可能会导致一个隐含的问题。

在一些非可视化的应用场景中,浏览器会遵循文档源码来进行使用。因此,屏幕阅读器会读取文档的顺序,此外使用键盘 tab 键来浏览的用户访问文档的顺序是基于源码的顺序,而不是元素展示的顺序。许多屏幕阅读器的用户并非完全失明,他们可能在使用屏幕阅读器的同时也能够看到这些元素在文档的哪个部分。在这些情况下,当与源码进行对比时,这种混乱的页面展现可能会令人充满迷惑。

当你改变了元素在文档中原来的顺序时,一定确保知道自己在做什么。如果你发现你自己正在CSS中重新排序你的元素,你应该去回头看看是否要重新组织你的页面元素。你可以通过使用 tab 访问来测试一下你的页面。

扩展阅读

盒模型的生成

你写在网页里的任何东西都会生成一个盒子(HTML每一个元素都是个盒子),这篇文章讨论的所有东西其实都是如何能够使用CSS来按照你的设计布局这些盒子。然而,在某些情况下,你可能根本不想创建一个盒子。 display 属性有两个值会帮你处理这种情况。

不生成盒子或内容(display: none)

如果你希望元素以及它所有的内容(包括所有子元素)都不会生成,你可以使用 display: none 。这样元素就不会被展示,并且不会保留其本该占有的空间。

.item {
    display: none;
}

不生成该元素,但是生成其所有子元素( display: contents

display: content display 的一个新的属性值。为一个元素应用 display: content 属性会导致其自身的盒子不生成但所有的子元素都会照常生成。这有什么用呢?试想一下,如果你希望一个弹性布局或网格布局中的非直接子元素能应用这些布局,这就会非常有用。

在下面这个例子里,第一个弹性项包含了两个子元素,由于它被设为 display: contents ,它的盒子不会生成并且它的两个子元素会成为弹性项,并被当作弹性盒子容器的直接子元素来布局。

扩展阅读

对齐方式

直到现在,对齐在Web上一直是一个棘手的问题,并且能够使用的方法也非常有限。随着CSS盒模型对齐的出现,这一切都发生了变化。你将会使用它来控制Grid容器与Flexbox容器中的对齐。未来其他的各种布局方法都会应用这些对齐属性。盒模型对齐规范中的一系列详细属性如下:

  • justify-content
  • align-content
  • place-content
  • justify-items
  • align-items
  • place-items
  • justify-self
  • align-self
  • place-self
  • row-gap
  • column-gap
  • gap

由于不同的布局模型有不同的特性,因此用于不同布局模型的对齐属性会有一些表现上的差异。让我们来看看在一些简单的网格与弹性布局中对齐是如何工作的。

align-items justify-items 属性相对是 align-self justify-self 属性的一种批量形式。这些属性会控制与元素在其网格区域中的对齐情况。

align-content justify-content 属性则会对网格中的行或列进行对齐控制(网格容器中需要在排列完行或列元素后有多余的空间)。

在Flexbox 布局中, align-items align-self 用来解决交叉轴上的对齐问题,而 justify-content 则用于解决主轴上空间的分配。

在交叉轴上,把弹性行(Flex Line)和额外空间包裹在Flexbox容器中之后,你就可以使用 align-content 了。

下面的一些链接更细节地讨论了各类布局方法中的盒模型对齐。花些时间去理解对齐的工作原理是非常值得的,它对理解弹性盒子、网格布局以及未来的一些布局方法都会很有帮助。

行或列的间隔

一个多栏布局具有 column-gap 属性,到目前位置,网格布局具有 grid-column-gap grid-row-gap grid-grid 。这些现在都被从 grid 标准中删除而被添加进盒模型对齐中了。与此同时, grid- 的前缀属性被重命名为 column-gap row-gap gap 。浏览器会将带有前缀的属性换为新的重命名属性,所以如果你在目前的代码中使用兼容性更好的老名字也不用担心。

重命名意味着这些属性也能被应用于其他布局方法,一个明显的备选就是弹性盒子。虽然目前没有浏览器支持盒子模型中的 gap 属性,但是在未来我们应该可以使用 column-gap row-gap 来创建弹性项目元素间的间距。

扩展阅读

多列布局

多列布局是一种支持创建多列的布局类型,如同报纸上那样。每一块都被分割成列,你会按照块方向在列中往下读然后会在回到下一列的顶部。然而用这种方式阅读在网页内容中并不总是有效,因为人们并不想去让滚动条滚动来、滚动去地去阅读。当需要展示少部分内容、折叠一组复选框或者其他一些小的UI组件时会非常有用。

当展示一组高度不同的卡片或产品时多列布局也非常有用。

设置列的宽度

要设置一个最优的列宽,并通知浏览器依此宽度展示尽可能多的列可以使用下面的CSS:

.container {
    column-width: 300px;
}

这会创建尽可能多的 300px 宽的列,所有剩下的空间会被所有列共享。因此,除非空间被划分为 300px 时没有剩余,否则你的列会比 300px 稍多一些。

设置列的数目

除了设置宽度,你可以使用 column-count 来设置列的数目。在这种情况下,浏览器会将空间均分给你需要的数目的列。

.container {
    column-count: 3;
}

如果你同时添加了 column-width column-count ,那么 column-count 属性会作为一个最大值限制。在下面的代码里,列会被添加直到达到三个,此时任何额外的空间都会被分给三列,即使空间足够成为一个额外的新列。

.container {
    column-width: 300px;
    column-count: 3;
}

间距和列规则

你无法为单个列盒子添加 margin padding ,需要用 column-gap 属性来设置间距。如果你不具体指定 column-gap 的值,它会默认为 1em 来防止列间碰撞。这和其他布局方法中 column-gap 的行为不一样,其他布局中默认为 0 。你可以在间距上使用任意的长度单元,包括 0 (如果你不希望有列间距)。

column-rule 属性让你有能力向两列间添加规则。它是 column-rule-width column-rule-color column-rule-style 的简写形式,和 border 行为类似。注意,一个规则自身不会占用任何空间。它会占据在间距的顶部,从而增加或减少那些你设置 column-gap 的规则与内容间的空间。

允许元素横跨多列

你可以使用 column-span 属性让多列容器内的元素横跨多列,类似通列。

h3 {
    column-span: all;
}

column-span 出现时,多列容器分列会在这个元素上停止,因此,容器里的内容会在元素上方形成多列样式,然后在横跨元素的下方形成一组新的列盒子(Column Box)。

你只可以使用 column-span: all column-span: none ,并不能让元素横跨某几个列(非通列)。在文章写作时,Firefox还不支持 column-span 属性。

扩展阅读

碎片化

多列布局是碎片化的一个例子,页面内容会被拆分成列。这和打印时内容被分到不同页非常类似。这个过程是碎片化规范(Fragmentation specification)处理的。这个规范包括了一些帮助控制内容切分的属性。

例如,如果你有一组置于多列中的卡片,并且你想确保卡片不会被截为两半分到不同的列,你可以使用 break-inside 属性的 avoid 值。考虑浏览器兼容性的因素,你也可能会想使用遗留的 page-break-inside 属性。

.card {
    page-break-inside: avoid;
    break-inside: avoid;
}

如果你想在标题元素后禁止断行,你可以使用 break-after 属性。

.container h2 {
    page-break-after: avoid;
    break-after: avoid;
}

这些属性可以被用在打印样式或多列样式中。在下面的例子里,在多列容器中的三个段落被拆分到了三列之中。我为 p 元素设置了 break-inside: avoid ,这意味着每个多列会在自己的列中结束(即使这会使各列长度不同)。

扩展阅读

如何选择布局类型?

大多数的网页会混合使用多种布局类型。各布局规范都准确定义了它们之间是如何相互作用的。例如,你可能会在网格布局的网格项中使用弹性布局。一些弹性容器可能具有定位属性或浮动。这些规范根据最优的布局方式已经包含了布局模型的混合使用。在这篇指南中,我尝试概述了这种布局类型的基本使用方式,来帮助你了解实现一个效果可能的最好方法。

然而,别害怕去运用多种方式来实现布局设计。担心你的选择会不会造成实际问题的情况比你想象中要少很多。所以请在开始就组织好你的文档结构,并且注意你文档内容的可视展示顺序。剩下的大部分工作就是在浏览器中试试你的布局方式是否符合预期。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。

如需转载,烦请注明出处: https://www.w3cplus.com/css/guide-css-layout.html

作者:W3CPlus
原文地址:CSS布局指南, 感谢原作者分享。

发表评论