依稀记得,某年广东语文高考作文的相关描述 -- “有时,常识虽易知而难行,有时,常识须推陈而出新”。人的想象力和创造力很容易在对常识的一贯认知中被削弱。
CSS 更新之快,只能不断鞭策自己持续学习,一直呆在舒适区中,很容易就跟不上节奏。当然,不仅仅是 CSS,对于任何技术任何行业也可以套用这句话。
回归本文的主题 -- 新时代布局。运用现有的 CSS 技术,我们是否可以大胆的跳出常规思维,不再局限于矩形框框一块一块,试着更加艺术一些?
像是下面这几个这样。
不拘一格的线条:
![](https://i-blog.csdnimg.cn/blog_migrate/e7f54f9371907a99736b99fe219f8f6f.png)
文字随图片的边缘排列:
![](https://i-blog.csdnimg.cn/blog_migrate/4de9b1fb6cd793838f9c4508cea07e1e.png)
不再是横平竖直:
又或者造型怪异的网格:
![](https://i-blog.csdnimg.cn/blog_migrate/4b9fb5a62b642cb77bc548f08db22f19.png)
是不是很有意思?不拘一格的布局能够给页面吸引更多的目光和流量,当然这也需要我对 CSS 掌握的足够好,才能在有限的属性中创造更多不同的可能性。
Grid 布局
说到新时代布局和创意布局,就不得不提到 Grid 的布局。
CSS Grid 布局的二维特性,让我们相较于传统的float布局、定位布局、flex 布局有了对页面更强大的掌控力。
利用 Grid 布局,切割页面进行分块
这里,我们利用 Grid 布局的特性,可以将页面按照我们的所想任意切割成不同的块状区域。
这里推荐一些能够方便我们进行 Grid 布局的工具:
快速进行 Grid 布局 - Grid Layoutit[1]
利用这个工具,可以快速创建得到自己想要 Grid 布局,并且拿到对应的 CSS,非常的简单便捷。
这里我利用工具,将页面切割成了 A、B、C、D、E、F 6 块区域:
![](https://i-blog.csdnimg.cn/blog_migrate/232c1bb5f0a155d6589d0862e41e4f0d.png)
复制右侧的 HTML 和 CSS,可以快速的得到这样一个布局,我把代码拷贝到了 CodePen,简单添加了一下底色,我们就可以基于这个布局再去做任何事情:
![](https://i-blog.csdnimg.cn/blog_migrate/c6b6e9339dcd46c080c8a7ae6ac512b7.png)
CodePen Demo -- Grid Layout Demo[2]
利用 Grid 布局配合 clip-path 实现 GTA5 封面
这里,我们可以利用 Grid 布局配合 clip-path 实现 GTA5 封面,像是这样:
![](https://i-blog.csdnimg.cn/blog_migrate/46610cda57dca2c75da6696937f6820d.png)
我们将一个 4x4 的 Grid 网格,分割为 9 个不同的部分:
![](https://i-blog.csdnimg.cn/blog_migrate/400c4f0be8843bcb9cd4d9e21af9c9d2.png)
再利用 clip-path,根据封面图片的的造型,对每一块 Gird item 进行二次裁剪:
![](https://i-blog.csdnimg.cn/blog_migrate/2cad5fbf651a87b310efd7f00415d59e.png)
ok,最后把里面的色块替换成具体的图片即可:
![](https://i-blog.csdnimg.cn/blog_migrate/7d9bbb2291ac19d2d2406fd9741fdcad.png)
CodePen Demo -- GTA 5 poster ( Grid and Clip Path)[3]
当然这里有一个槽点,最终还是用了 9 张图片,那为什么不一开始直接用一张图片呢?:)
Grid 是在进行复杂布局的过程中非常好的帮手,它非常适合各种不规则网格块的布局,这里再提供一个 DEMO:
![](https://i-blog.csdnimg.cn/blog_migrate/d54f0451a0b05bb4c41895d80494bb51.png)
作者是 Olivia Ng[4],Demo 的链接 -- CodePen Demo -- CSS Grid: Train Ticket[5]
瀑布流布局
瀑布流布局在现代布局中也非常常见,通常在一些照片墙中使用。像是这样:
在之前,不借助 JavaScript,我们有 3 种纯 CSS 的方式可以实现伪瀑布流布局(注意,这里是伪瀑布流),分别是:
使用 CSS column 实现瀑布流布局[6]
使用 CSS flex 实现瀑布流布局[7]
使用 CSS grid 实现瀑布流布局[8]
你可以点进 Demo 看看,利用上述三种方式实现的瀑布流布局,缺点比较明显:
对于 flex 和 column 布局而言,只能实现竖直排布的瀑布流布局,第一列填充满了填充第二列,以此类推
对于 Grid 布局而言,缺点则是无法自动适配不同的高度,需要手动指定每一个元素区块大小
而在未来,标准基于 Grid 布局实现了 grid-template-rows: masonry
,利用该标准,我们可以快速利用 Grid 实现水平排布的瀑布流布局,目前,你可以在 Firefox 体验该功能。
使用 grid-template-rows: masonry
实现水平方向排布的瀑布流布局
grid-template-rows: masonry
是 firefox 在 firefox 87 开始支持的一种基于 grid 布局快速创建瀑布流布局的方式。并且 firefox 一直在推动该属性进入标准当中。
从 firefox 87 开始,在浏览器输入网址栏输入 about:config
并且开启 layout.css.grid-template-masonry-value.enabled
配置使用。Can i use -- grid-template-rows: masonry[9]
![](https://i-blog.csdnimg.cn/blog_migrate/f787169ac8462affde71579c4f593f29.png)
正常而言,我们想要实现瀑布流布局还是需要花费一定的功夫的,即便是基于 grid 布局。在之前,我们通过 grid 布局,通过精细化控制每一个 grid item
,可以实现竖直方向的瀑布流布局:
<div class="g-container">
<div class="g-item">1</div>
<div class="g-item">2</div>
<div class="g-item">3</div>
<div class="g-item">4</div>
<div class="g-item">5</div>
<div class="g-item">6</div>
<div class="g-item">7</div>
<div class="g-item">8</div>
</div>
.g-container {
height: 100vh;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(8, 1fr);
}
.g-item {
&:nth-child(1) {
grid-column: 1;
grid-row: 1 / 3;
}
&:nth-child(2) {
grid-column: 2;
grid-row: 1 / 4;
}
&:nth-child(3) {
grid-column: 3;
grid-row: 1 / 5;
}
&:nth-child(4) {
grid-column: 4;
grid-row: 1 / 6;
}
&:nth-child(5) {
grid-column: 1;
grid-row: 3 / 9;
}
&:nth-child(6) {
grid-column: 2;
grid-row: 4 / 9;
}
&:nth-child(7) {
grid-column: 3;
grid-row: 5 / 9;
}
&:nth-child(8) {
grid-column: 4;
grid-row: 6 / 9;
}
}
效果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/1eb3749b21488dd54c9f009d4d8efd3b.png)
CodePen Demo -- CSS Grid 实现伪瀑布流布局[10]
在上述 Demo 中,使用 grid-template-columns
、grid-template-rows
分割行列,使用 grid-row
控制每个 grid item
的所占格子的大小,但是这样做的成本太高了,元素一多,计算量也非常大,并且还是在我们提前知道每个元素的高宽的前提下。
而在有了 grid-template-rows: masonry
之后,一切都会变得简单许多,对于一个不确定每个元素高度的 4 列的 grid 布局:
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
正常而言,看到的会是这样:
![](https://i-blog.csdnimg.cn/blog_migrate/aaa298ecb6a341b58560ba658156b627.png)
简单的给容器加上 grid-template-rows: masonry
,表示竖方向上,采用瀑布流布局:
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
+ grid-template-rows: masonry;
}
便可以轻松的得到这样一种水平方向顺序排布元素的瀑布流布局:
![](https://i-blog.csdnimg.cn/blog_migrate/c0d0494e88a7dee24dc63de3a27d21bf.png)
如果你在使用 firefox,并且开启了 layout.css.grid-template-masonry-value.enabled
配置,可以戳进下面的 DEMO 感受一下:
CodePen Demo -- grid-template-rows: masonry 实现瀑布流布局[11]
多栏布局
多栏布局也属于现在我们能够掌控的布局之一,利用 CSS 较为新的特性 Multiple-column Layout Properties[12]。
最简单的多栏布局,我们只需要用到 column-count
或者 column-width
。
假设我们有如下 HTML:
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit...</p>
简单的 3 列布局:
p {
width: 800px;
column-count: 3;
font-size: 16px;
line-height: 2;
}
通过 column-count: 3
指定 3 栏。
![](https://i-blog.csdnimg.cn/blog_migrate/33bff610ffa99738f61fe71e373664de.png)
column-gap 控制间距 & column-rule 控制列与列间样式
接下来,我们再了解下 column-gap
和 column-rule
column-gap:控制列与列之间的间隔,默认为关键字
normal
,数值上为1em
column-rule:控制列与列之间的样式规则,其写法与
border
类似,指定列之间的装饰线
还是如下 HTML:
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit...</p>
简单的 3 列布局:
p {
width: 800px;
column-count: 3;
font-size: 16px;
line-height: 2;
+ column: 1px solid #999;
+ column-gap: 2em;
}
![](https://i-blog.csdnimg.cn/blog_migrate/9a4987e04ab5e070f581f3730b84df35.png)
CodePen Demo -- CSS multi column Layout Demo[13]
column-span 设置跨列
接着,还有一个很有意思的属性 column-span
,用于设置元素的跨列展示。
我们首先利用多列布局,实现这样一个类似于报纸排版的布局样式。
<div class="g-container">
<p>Lorem ipsum dolor sit amet ... </p>
<h2>Title Lorem ipsum dolor sit amet consectetur adipisicing elit title</h2>
<p>Lorem ipsum dolor sit amet ... </p>
</div>
.g-container {
width: 800px;
column-count: 3;
column-rule: 1px solid #aaa;
column-gap: 2em;
}
h2 {
margin: 14px 0;
font-size: 24px;
line-height: 1.4;
}
大概就是多列布局中嵌套标题,标题的加粗并且字号大一点:
![](https://i-blog.csdnimg.cn/blog_migrate/683ab4ed199db428a128a7fa441346d5.png)
通过给 h2
设置 column-span: all
,让 h2
标题跨列多列进行展示,改动一下 CSS:
h2 {
margin: 14px 0;
font-size: 24px;
line-height: 1.4;
+ column-span: all;
+ text-align: center;
}
即可得到这样一个布局:
![](https://i-blog.csdnimg.cn/blog_migrate/18e440de53cd770ef31fddb2fa4b1757.png)
CodePen Demo -- CSS multi column Layout Demo 2[14]
多栏布局搭配其他布局实现更复杂的布局
当然,column-span
有个缺陷,就是它的取值只有 column-span: all
或者是 column-span: none
,也就是要么横跨所有的列,要么不跨列。
如果现在我有一个 3 列布局,但是只希望其中的标题横跨两列,column-span: all
就无法实现了。
但是,通过嵌套其他布局,我们可以巧妙的对多列布局再进行升华,譬如 rachelandrew[15] 就实现了这样一种嵌套布局:
<div class="container">
<article>
<p>By way of precaution ...</p>
<h2>the first that ever burst Into that silent sea;</h2>
<p>and with what ...</p>
</article>
<aside>
<img src="demo.jpg">
<figcaption>The Authoress, her Father and Mr. Spencer making an ascent</figcaption>
</aside>
</div>
通过一个 2 列的 Grid 布局,嵌套一个两列的 multi-column 布局,大致的 CSS 如下:
.container {
max-width: 800px;
display: grid;
grid-gap: 1em;
grid-template-columns: 2fr 1fr;
align-items: start;
}
h2 {
column-span: all;
text-align: center;
}
.container article {
column-count: 2;
column-gap: 2em;
column-rule: 1px solid #ccc;
}
.container aside {
border-left: 1px solid #ccc;
padding: 0 1em;
}
这样,我们就能实现视觉上的横跨任意列的标题:
![](https://i-blog.csdnimg.cn/blog_migrate/3368721d44950d99189953fbf2afd60f.png)
完整的 Demo 代码你可以戳这里:CodePen Demo -- Smashing Multicol: mixing layout methods -- By rachelandrew[16]
shape-outside 让布局插上想象的翅膀
OK,进入下一个模块,主角是 shape-outside
。
在之前,我也有写过一篇关于 shape-outside
的文章 奇妙的 CSS shapes[17],感兴趣的同学也可以先看看。
shape-outside[18] CSS 属性定义了一个可以是非矩形的形状,相邻的内联内容应围绕该形状进行包装。
利用它,我们就能够很好的实现各种非横平竖直的布局,让布局真正的活起来。
图文排列的交界处,可以是斜的,像是这样:
![](https://i-blog.csdnimg.cn/blog_migrate/2a4f41ecefea83713df20fb1428d44a7.png)
CodePen Demo -- FCC: Build a Tribute Page - Michel Thomas by Stephanie[19]
也可以是弯曲的,像是这样:
![](https://i-blog.csdnimg.cn/blog_migrate/cedb27e44bf8de89f7fd84c1e7357f83.png)
CodePen Demo -- shape-outside: circle Demo[20]
甚至,它是还可以动态变化的不规则容器:
CodePen Demo -- shape-outside animation[21]
合理使用,我们就可以如报纸版创造各种花式布局效果:
不仅如此,袁川老师[22] 甚至使用了 shape-outside
进行了一些 CSS 艺术创作,一起欣赏一下:
CodePen Demo -- shape-outside -- Face By yuanchuan[23]
以开篇的这张图为例子:
![](https://i-blog.csdnimg.cn/blog_migrate/3385fc7f32cdc416a73fd009e21e86a0.png)
就是巧妙的运用 shape-outside
的例子,它将整个布局分为了 7 块,每一块分别使用 shape-outside
进行精细化的控制,实际上完整的布局是这样的:
![](https://i-blog.csdnimg.cn/blog_migrate/c32fd1b46fa3db13d55ca658ccdc2270.png)
在这篇文章中,对这个 DEMO 进行了非常详细的阐述:A CSS Venn Diagram[24]
如果你也对 shape-outside
感兴趣,在这份收藏夹里,收藏了 CodePen 上非常多精良的 shape-outside
布局 DEMO,不妨一看学习学习 -- CSS Shapes Experiments[25]
总结一下
在今天,实现有创意的布局也需要我们掌握更多的 CSS 属性与技巧,本文粗略的介绍了几种在今天实现创意布局的有益属性:
Grid 布局全家桶以及利用 Grid 实现瀑布流布局
多栏布局 multiple-column 及多栏布局嵌套其他布局
shape-outside
的各种应用在上述布局中穿插使用
clip-path
、transform
等属性以增强各种布局
当然,CSS 能实现的远不止如此,像是滚动视差、3D 变换等等都是可以利用 CSS 实现并且再融合进布局当中的属性。当然这也需要我们有创造和发现美的眼睛和思维。
参考资料
[1]
快速进行 Grid 布局 - Grid Layoutit: https://grid.layoutit.com/
[2]CodePen Demo -- Grid Layout Demo: https://codepen.io/Chokcoco/pen/ExWWevq
[3]CodePen Demo -- GTA 5 poster ( Grid and Clip Path): https://codepen.io/Chokcoco/pen/jOVjxjo
[4]Olivia Ng: https://codepen.io/oliviale
[5]CodePen Demo -- CSS Grid: Train Ticket: https://codepen.io/oliviale/pen/MZZYyO
[6]使用 CSS column 实现瀑布流布局: https://chokcoco.github.io/CSS-Inspiration/#/./layout/masonry-layout-colum
[7]使用 CSS flex 实现瀑布流布局: https://chokcoco.github.io/CSS-Inspiration/#/./layout/masonry-layout-flex
[8]使用 CSS grid 实现瀑布流布局: https://chokcoco.github.io/CSS-Inspiration/#/./layout/masonry-layout-grid
[9]Can i use -- grid-template-rows: masonry: https://caniuse.com/?search=grid-template-rows
[10]CodePen Demo -- CSS Grid 实现伪瀑布流布局: https://codepen.io/Chokcoco/pen/KGXqyo
[11]CodePen Demo -- grid-template-rows: masonry 实现瀑布流布局: https://codepen.io/Chokcoco/pen/NWdBojd
[12]Multiple-column Layout Properties: https://drafts.csswg.org/css-multicol-1/
[13]CodePen Demo -- CSS multi column Layout Demo: https://codepen.io/Chokcoco/pen/PoppVKx
[14]CodePen Demo -- CSS multi column Layout Demo 2: https://codepen.io/Chokcoco/pen/QWpvgqK
[15]rachelandrew: https://codepen.io/rachelandrew
[16]CodePen Demo -- Smashing Multicol: mixing layout methods -- By rachelandrew: https://codepen.io/rachelandrew/pen/aPRjzL
[17]奇妙的 CSS shapes: https://github.com/chokcoco/iCSS/issues/18
[18]shape-outside: https://developer.mozilla.org/zh-CN/docs/Web/CSS/shape-outside
[19]CodePen Demo -- FCC: Build a Tribute Page - Michel Thomas by Stephanie: https://codepen.io/StuffieStephie/pen/ZLmzKG
[20]CodePen Demo -- shape-outside: circle Demo: https://codepen.io/Chokcoco/pen/LYWyOaa
[21]CodePen Demo -- shape-outside animation: https://codepen.io/Chokcoco/pen/RwpgmaK
[22]袁川老师: https://twitter.com/yuanchuan23
[23]CodePen Demo -- shape-outside -- Face By yuanchuan: https://codepen.io/yuanchuan/pen/xoKMKj
[24]A CSS Venn Diagram: https://adrianroselli.com/2018/12/a-css-venn-diagram.html
[25]CSS Shapes Experiments: https://codepen.io/collection/DYeRBR?cursor=ZD0wJm89MCZwPTEmdj00
[26]Github -- iCSS: https://github.com/chokcoco/iCSS
❤️ 顺手点个在看呗 ↓