css布局方式_收藏!40 个 CSS 布局技巧

3a032c49da7013aadb2c79e808138d59.png
简介:CSS是Web开发中不可或缺的一部分,随着Web技术的不断革新,CSS也变得更加强大。CSS的众多属性你知道了多少?具体开发中该使用什么属性才最适合恰当?如今的一些CSS属性可以让我们节约更多的时间。比如在Web布局中,现代CSS特性就可以更好的帮助我们快速实现如等高布局,水平垂直居中,经典的圣杯布局、宽高比例、页脚保持在底部等效果。淘系前端技术专家大漠将详细介绍一些不同的CSS属性来实现这些效果,希望对同学们有所帮助。

99abbff90cbb847a345a98cb8349236c.png

一 水平垂直居中

如何实现水平垂直居中可以说是CSS面试题中的经典面试题,在多年前这个面试题给很多同学都带来了困惑,但Flexbxo布局模块和CSS Grid布局模块的到来,可以说实现水平垂直居中已是非常的容易。

Flexbox中实现水平垂直居中

在Flexbox布局模块中,不管是单行还是多行,要让它们在容器中水平垂直居中都是件易事,而且方法也有多种。最常见的是在Flex容器上设置对齐方式,在Flex项目上设置 margin:auto。

先来看在Flex容器上设置对齐方式。

Flex容器和Flex项目上设置对齐方式

你可能已经知道在Flex容器上设置 justify-content、align-items 的值为 center 时,可以让元素在Flex容器中达到水平垂直居中的效果。来看一个示例:

<!-- HTML -->
<div class="flex__container"><div class="flex__item"></div>
</div>/* CSS */
.flex__container {display: flex;justify-content: center;align-items: center;
}

效果如下:

67015d12addb518ebfabe9f8d6ac39d4.png

这种方式特别适应于让Icon图标在容器中水平垂直居中,不同的是在Icon图标容器上显示设置 display: inline-flex。比如下面这个示例:

<!-- HTML -->
<div class="flex__container"><svg> </svg>
</div>/* CSS */
.flex__container {display: inline-flex;align-items: center;justify-content: center;
}

效果如下:

c56116b60d842f19b8ef1878bb529044.png

在这种模式之下,如果要让多个元素实现水平垂直居中的效果,那还需要加上 flex-direction: column,比如:

<!-- HTML -->
<div class="flex__container"><div class="avatar">:)</div><div class="media__heading"></div><div class="media__content"></div><div class="action"></div>
</div>/* CSS */
.flex__container  {display: flex;flex-direction: column;justify-content: center;align-items: center;
}

效果如下:

664add9ac5cca4acc8cb9d48afdc6b22.png

在Flexbox布局中,还可以像下面这样让Flex项目在Flex容器中达到水平垂直居中的效果:

<!-- HTML -->
<div class="flex__container"><div class="flex__item"></div>
</div>/* CSS */
.flex__container {display: flex; // 或inline-flexjustify-content: center;
}.flex__item {align-self: center;
}

效果如下:

0d1b92de31dd0da16d8fb68ebc38c8a0.png

如果在Flex容器中有多个Flex项目时,该方法同样有效:

.flex__container {display: flex; // 或inline-flexjustify-content: center;
}.flex__container > * {align-self: center;
}

比如下面这个效果:

482001f2c295ab038e90c2025b9808f0.png

除此之外,还可以使用 place-content: center 让Flex项目实现水平垂直居中:

.flex__container {display: flex;place-content: center;
}.flex__item {align-self: center;
}

效果如下:

338300be9d51150aabfa193fc23e7b4b.png

或者换:

.flex__container {display: flex;place-content: center;place-items: center;
}

效果如下:

7929ff0b2e746b53b71d16e3277aab47.png

这两种方式同样适用于Flex容器中有多个Flex项目的情景:

.flex__container {display: flex;flex-direction: column;place-content: center;
}.flex__container > * {align-self: center;
}// 或.flex__container {display: flex;flex-direction: column;place-content: center;place-items: center;
}

效果如下:

2347debbf8b545c0688792e8454ca2a1.png

可能很多同学对于 place-content 和 place-items 会感到陌生。其实 place-content 是 align-content 和 justify-content 的简写属性;而 place-items 是 align-items 和 justify-items 的简写属性。即:

.flex__container {place-content: center;place-items: center;
}等效于:.flex__container {align-content: center;justify-content: center;align-items: center;justify-items: center;
}

虽然扩展出来有四个属性,但最终等效于:

.flex__container {display: flex;align-items: center;justify-content: center;
}// 多行
.flex__container {display: flex;flex-direction: column;align-items: center;justify-content: center;
}

在Flex项目上设置margin: auto

如果在Flex容器中只有一个Flex项目,还可以显式在Flex项目中显式设置 margin 的值为auto,这样也可以让Flex项目在Flex容器中水平垂直居中。例如:

.flex__container {display: flex; // 或 inline-flex
}.flex__item {margin: auto;
}

效果如下:

d7f377acae7baa787092b9851d8666fb.png

整个过程,你可以通过下面这个示例来体验。尝试着选中不同方向的 margin 值:

1f163850d9d1ee09e640dd5482199602.png

Grid中实现水平垂直居中

CSS Grid布局可以说是现代Web布局中的银弹。它也是到目前为止布局系统中唯一一个二维布局系统。

在CSS Grid布局中,只需要仅仅的几行代码也可以快速的帮助我们实现水平垂直居中的效果。比如下面这个示例:

<!-- HTML -->
<div class="grid__container"><div class="grid__item"></div>
</div>/* CSS */
.grid {display: grid; // 或 inline-gridplace-items: center
}

效果如下:

813b9d55f7c3eb7373a0c9cce0e42f8b.png

在CSS Grid布局模块中,只要显式设置了 display: grid(或 inline-grid)就会创建Grid容器和Grid项目,也会自动生成网格线,即行和列(默认为一行一列)。

09ed18c0764a85da2fa0d5359eb9fdb4.png

在没有显式地在Grid容器上设置 grid-template-columns 和 grid-template-rows,浏览器会将Grid容器默认设置为Grid内容大小:

ceb14ff841c66269a980dc544a4f2258.png

这种方法也适用于CSS Grid容器中有多个子元素(Grid项目),比如:

<!-- HTML -->
<div class="grid__container"><div class="avatar">:)</div><div class="media__heading"></div><div class="media__content"></div><div class="action"></div>
</div>

这个时候你看到的效果如下:

596ee5debd89d9bfa7069256d4fd6e25.png

而且 palce-items 适用于每个单元格。这意味着它将居中单元格的内容。比如下面这个示例:

<!-- HTML -->
<div class="grid__container"><div class="grid__item"><h3>Special title treatment</h3><p>With supporting text below as a natural lead-in to additional content.</p><div class="action">Go somewhere</div></div>
</div>/* CSS */
.grid__container {display: grid;place-items: center;grid-template-columns: repeat(2, 1fr);gap: 2vh;
}.grid__item {display: grid;place-items: center;
}

效果如下:

54d6cc6eb97b6dbc1d91e594364bb4d3.png

二 等高布局

等高布局也是Web中非常常见的一种布局方式,而且实现等高布局的方案也有很多种。这里我们主要来看Flexbox布局模块和Grid布局模块给我们带来了什么样的变化。

在Flexbox和Grid布局模块中,让我们实现等高布局已经是非常的简单了,比如:

<!-- Flexbox -->
<flex__container><flex__item></flex__item><flex__item></flex__item><flex__item></flex__item>
</flex__container>/* CSS */
.flex__container {display: flex; // 或 inline-flex
}

简单地说,在容器上显式设置了 display 的值为 flex 或 inline-flex,该容器的所有子元素的高度都相等,因为容器的 align-items 的默认值为 stretch。

这个时候你看到的效果如下:

9fccb36e40f41db11309db8b948a943c.png

这种方式特别适用于卡片组件中:

8517f5aa7da54fd8973d4a263768da55.png

在Grid布局模块中类似:

<!-- HTML -->
<grid__container><grid__item></grid__item><grid__item></grid__item><grid__item></grid__item>
</grid__container>/* CSS */
.grid__container {display: grid;grid-template-columns: 20vw 1fr 20vw; /* 根据需求调整值*/
}

效果如下:

3584fd746256746a1b68ecf87891a7c8.png

同样在一些卡片类布局中运用:

f0004e0bc0023a93a98d292def2455c0.png

如果需求有所调整,比如在Flex项目 或 Grid项目的子元素高度和容器高度相同。

<!-- HTML -->
<flex__container><flex__item><content></content></flex__item>
</flex__container>/* CSS */
.flex__container {display: flex;
}.content {height: 100%
}// 或
.grid__container {display: grid;grid-auto-flow: column;
}.content {height: 100%;
}

效果如下:

9767519111a7822c6f172cfd0dd950d0.png

三 Sticky Footer

首先用下图来描述什么是Sticky Footer布局效果:

f1419e796f30269848ae492b393c7109.png

Sticky Footer实现方案和等高、垂直居中一样,同样有很多种方案可以实现。

比如像下面这样的结构:

<!-- HTML -->
<header></header>
<main></main>
<footer></footer>

先来看Flexbox布局模块中的实现方案:

body {display: flex;flex-direction: column;
}footer {margin-top: auto;
}

270a633a6601f9ae3eac560c2287b0ef.png

可以尝试着在 main 区域右下角向下拖动,改变主内容区域的高度,你会发现“当内容不足一屏时, 会在页面的最底部,当内容超出一屏时, 会自动往后延后”。

在Flexbox布局中,还可以在 区域上设置下面的样式,达到相等的效果:

body {display: flex;flex-direction: column;
}main {flex: 1 0 auto;
}

效果如下:

d1b3e9708eb610920f67bfa9aee96363.png

中的 flex: 1 0 auto 相当于是:

main {flex-grow: 1; /*容器有剩余空间时,main区域会扩展*/flex-shrink: 0; /*容器有不足空间时,main区域不会收缩*/flex-basis: auto; /*main区域高度的基准值为main内容自动高度*/
}

如果你想省事的话,可以在 main 上显式设置 flex-grow:1,因为 flex-shrink 和 flex-basis 的默认值为 1 和 auto。

在CSS Grid布局中我们可以借助 1fr 让 区域根据Grid容器剩余空间来做计算。

.grid__container {display: grid;grid-template-rows: auto 1fr auto;
}

效果如下:

6605a1006a9cdc4bb767e885acc2fd2a.png

四 均分列

在Web布局中,很多时候会对列做均分布局,最为常见的就是在移动端的底部Bar,比如下图这样的一个效果:

19971eb84ab871bc2b04651541edff24.png

在Flexbox和Grid还没出现之前,如果希望真正的做到均分效果,可以用 100%(或 100vw)除以具体的列数。比如:

<!-- HTML -->
<container><column></column><column></column><column></column>
</container>/* CCSS */
.container {inline-size: 50vw;min-inline-size: 320px;display: flex-row;
}.column {float: left;width: calc(100% / 3);
}

效果如下:

a78ee93ff83598a3333bf3821d4b313e.png

通过浏览器调试器中可以发现,现个列的宽度都是相等的:

83719c5209bc7345861dddf8a5dec82c.png

在Flexbox和Grid布局中,实现上面的效果会变得更容易地多。先来看Flexbox中的布局:

<!-- HTML -->
<flex__container><flex__item></flex__item><flex__item></flex__item><flex__item></flex__item>
</flex__container>/* CSS */
.flex__container {inline-size: 50vw;display: flex;
}.flex__item {flex: 1;
}

效果如下:

7e02ca97ca6c42a980c6e0c29900e42b.png

在Flexbox布局模块中,当flex取的值是一个单值(无单位的数),比如示例中的 flex:1,它会当作显式的设置了 flex-grow: 1。浏览器计算出来的 flex:

b8cd24b8499546e8069352dd20845624.png

接下来看Grid中如何实现上例的效果:

<!-- HTML -->
<grid__container><grid__item></grid__item><grid__item></grid__item><grid__item></grid__item>
</grid__container>/* CSS */
.grid__container {display: grid;grid-template-columns: repeat(3, 1fr); /*这里的3表示具体的列数*/
}

最终的效果是相同的:

7d610e7694328c040cb56d846d1bf0d7.png

这样的布局方式也适用于其他的布局中。但不管是Flexbox还是Grid布局中,都存在一定的缺陷,当容器没有足够的空间容纳Flex项目(或Grid项目)时,Flex项目或Grid项目会溢出(或隐藏,如果Flex容器或Grid容器显式设置了 overflow:hidden):

bd3fca5a230ae227bbf5bb5446de06b1.png

修复这种现象最简单的方式是在Flex容器或Grid容器显式设置一个 min-width(或 min-inline-size):

.flex__container {min-inline-size: 300px;
}

不过话又说回来,比如我们的Flex项目(或Grid项目)是一个卡片,每张卡片宽度是相等之外,更希望容器没有足够空间时,Flex项目(或Grid项目)会自动断行排列。

我们继续通过示例向大家展示。先来看Flexbox实现方案:

.flex__container {display: flex;flex-wrap: wrap;
}.flex__item {flex: 0 1 calc((100vw - 18vh) / 4); /* calc(100vw -18vh) / 4 是flex-basis的基准值 */
}

70616a9f0ae36c95fea0e8e7bc649e76.png

你可以尝试着调整浏览器的视窗宽度,当浏览器的视窗越来越小时,Flex容器宽度也就会越来越小,当Flex容器小到没有足够的空间容纳四个Flex项目(就此例而言),那么Flex项目就会断行排列:

c77c7f0bfbdb6341582a0b55b4550adf.png

基于该例,如果把Flex项目的 flex 值改成:

.flex__item {flex: 0 0 400px;
}

这个时候,当Flex容器没有足够空间时,Flex项目会按 flex-basis: 400px 计算其宽度,Flex容器没有足够空间时,Flex就会断行:

c77c7f0bfbdb6341582a0b55b4550adf.png

反过来,如果Flex项目的值 flex 改成:

.flex__item {flex: 1 0 400px;
}

当Flex容器没有足够空间排列Flex项目时,Flex项目会按 flex-basis: 400px 计算其宽度,Flex会断行,并且同一行出现剩余空间时,Flex项目会扩展,占满整个Flex容器:

0af92954b979e0834f34113a1e9917c0.png

在Grid中实现类似的效果要更复杂一点。可以使用 repeat() 函数,1fr 以及 auto-fit 等特性:

.grid__container {display: grid;grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));gap: 2vh;
}

效果如下:

c5c53eb1da07eda2fa26602dc2868418.png

如果你对这方面知识感兴趣的话,还可以移步阅读《Container Query Solutions with CSS Grid and Flexbox》一文。

其实在Grid中与 auto-fit 对比的值还有一个叫 auto-fill。但两者的差异是非常地大,用下图来描述 auto-fit 和 auto-fill 的差异:

6e1697aafa3c2cf7e7e766e23eeb2290.png

另外这种方式也是到目前为止一种不需要借助CSS媒体查询就可以实现响应式布局效果。

五 圣杯布局

圣杯布局(Holy Grail Layout))是Web中典型的布局模式。看上去像下图这样:

08c94c1fd035a8e4e199077059bc932d.png

对于圣杯布局而言,HTML结构是有一定的要求,那就是内容为先:

<!-- HTML -->
<header></header>
<main><article></article> <!-- 主内容 --><nav></nav><aside></aside>
</main>
<footer></footer>

在这里主要还是和大家一起探讨,如何使用Flexbox和Grid布局模块来实现圣杯布局。先来看Flexbox实现方案:

body {width: 100vw;display: flex;flex-direction: column;
}main {flex: 1;min-height: 0;display: flex;align-items: stretch;width: 100%;
}footer {margin-top: auto;
}nav {width: 220px;order: -1;
}article {flex: 1;
}aside {width: 220px;
}

效果如下:

b767b2514ca93151e427633701bf66c7.png

通过在 nav、aside 和 article 上显式设置 order 的值,可以很好的控制这三个区域的布局顺序。比如说,希望 在 之前排列,只需要在上面的示例基础上做一点点调整:

nav {order: 0;
}aside {order: -1;
}

效果如下:

46ae2e8a89fb2686ec86dbefa762a1fe.png

注意,order的默认值为0,值越大越排在后面!

在上例的基础上,借助CSS媒体对象的特性,可以很容易实现响应式的圣杯布局效果:

@media screen and (max-width: 800px) {main {flex-direction: column;}nav, aside {width: 100%;}
}

效果如下:

84a125f6eb928b8d537c6f3abf0b5c9e.png

尝试着拖动浏览器来改变视窗大小,你可以看到如下图的效果:

32e5d500702231dda3e470d79e6f8bf9.png

在Grid布局模块中,实现圣杯布局要比Flexbox布局模块中更容易,而且更灵活。在CSS Grid布局模块中,HTML结构可以更简洁:

<!-- HTML -->
<body><header></header><main></main><nav></nav><aside></aside><footer></footer>
</body>

在CSS方面有很多种方案可以实现圣杯布局效果。我们先来看第一种:

body {display: grid;grid-template: auto 1fr auto / 220px 1fr 220px;
}header {grid-column: 1 / 4;
}main {grid-column: 2 / 3;grid-row: 2 / 3;
}nav {grid-column: 1 / 2;grid-row: 2 / 3;
}aside {grid-column: 3 / 4;grid-row: 2 / 3;
}
footer {grid-column: 1 / 4;
}

效果如下:

bd039a219a04839bbc4411aa7fd319c7.png

上面示例采用的是网格线来给每个区域进行定位的:

6cbc94ca6c5b3e73deb750f41aec10f8.png

和Flexbox布局类似,在媒体查询中可以改变每个网格区域的位置:

@media screen and (max-width: 800px) {body {grid-template-rows: auto;grid-template-columns: auto;}header,main,nav,aside,footer {grid-column: 1 / 2;min-height: auto;}main {grid-row: 3 / 4;margin: 0;}nav {grid-row: 2 / 3;}aside {grid-row: 4 / 5;}footer {grid-row: 5 / 6;}
}

11ced2ea22da7814866ab0105c2215ef.png

除了 grid-template(即 grid-template-columns 和 grid-template-rows)之外,在Grid布局中还可以使用 grid-area 和 grid-template-areas 属性的结合,也能很方便的实现CSS圣杯布局。基于上面的示例上,只需要把你的CSS调整为:

body {display: grid;grid-template-areas:"header header header""nav main aside""footer footer footer";
}header {grid-area: header;
}main {grid-area: main;
}nav {grid-area: nav;
}aside {grid-area: aside;
}footer {grid-area: footer;
}@media screen and (max-width: 800px) {body {grid-template-areas:"header""nav""main""aside""footer";}
}

效果如下:

f5c94f895d7eb25210abb91fa628c2c1.png

你可能发现了它们之间的差异性:

159aceb182159ba630ed5158b67fe514.png

后面这个示例中,、 和 区域宽度相等。这是因为我们示例中通过 grid-template-areas 来声明网格,在使用 grid-template-areas 创建网格时,其实也隐式的创建了网格线,只不过他和 grid-template 不同的是 grid-template 可以显式的指定网格轨道大小,而 grid-template-areas 在该示例中相当于网格轨道大小都是 1fr。

6164bc205e49073ec114e8dd9f8c71ad.png

如果我们希望 的区域变得更大,那么可以在 grid-template-areas 上做个调整:

body {display: grid;grid-template-areas:"header header header header header""nav main main main aside""footer footer footer footer footer";
}

效果如下:

41595444b91f87625746372c8b258fdb.png

这个时候网格区域的划分像下图这样:

de5ec40928ef5d5076a2bdb697073e7b.png

虽然在效果有所调整了,但还是均分状态。更好的解决方案是,将 grid-template-areas 和 grid-template 结合起来使用:

body {display: grid;grid-template-areas:"header header header""nav main aside""footer footer footer";grid-template-columns: 220px 1fr 220px;grid-template-rows: auto 1fr auto;
}header {grid-area: header;
}main {grid-area: main;
}nav {grid-area: nav;
}aside {grid-area: aside;
}footer {grid-area: footer;
}@media screen and (max-width: 800px) {body {grid-template-areas:"header""nav""main""aside""footer";grid-template-columns: 1fr;grid-template-rows: auto auto 1fr auto auto;}main {margin-left: 0;margin-right: 0;}
}

效果如下:

0699ae14c7466d2fb50ab7f76b58cbb2.png

你可以发现,这个时候,网格线的区域的命名像下图这样:

f1019be1ab10db4a9ff6e097b228cc5a.png

六 12列网格布局

12列网格布局最早是由960.gs提出的网格布局系统:

d5fc9d975a148f118091ba3258f223f1.png

12列网格布局在设计系统和CSS Framework中经常使用,比如业内经典的Bootstrap就采用了12列网格布局系统:

eb5f113dd409a572de06f7b2e3fe6b18.png

在社区中也有很多在线工具,帮助我们快速构建12列网格系统,比如 Free CSS Grid Tools & Resources For Developers 一文中罗列的工具。

928f15515809b2110f0fc2edb98bc173.png

不过这里主要是想和大家一起看看在Flexbox和Grid布局模块中是如何实现12列的网格布局系统。

先来看Flexbox布局模块。12列网格布局的HTMl结构一般类似于下面这样:

<!-- HTML -->
<flex__grid><flex__row><flex__item col4></flex__item col4><flex__item col4></flex__item col4><flex__item col4></flex__item col4></flex__row>
</flex__grid>

注意,12列网格中,一般同一行的列数值和刚好等于12。比如上面的HTML结构,行中有三列,每列的宽度刚好四个网格宽度加两个列间距。并且在计算的时候有一套成熟的计算公式:

84b726c00d8095e4eb11baaea7a85e4d.png

而且还设计上也会有所差异,比如说距离容器两侧有没有间距等:

2d0a0bcfab42176d16f619fe3e9eb9cc.png

这些的差异对于计算公式和样式代码的设计都略有差异。我们用其中一个为例:

:root {--gutter: 10px;--columns: 12;--span: 1;
}.flex__container {display: flex;flex-direction: column;padding-left: var(--gutter);padding-right: var(--gutter);
}.flex__row {display: flex;margin-left: calc(var(--gutter) * -1);margin-right: calc(var(--gutter) * -1);
}.flex__row + .flex__row {margin-top: 2vh;
}.flex__item {flex: 1 1calc((100% / var(--columns) - var(--gutter)) * var(--span));margin: 0 var(--gutter);
}.flex__item1 {--span: 1;
}.flex__item2 {--span: 2;
}.flex__item3 {--span: 3;
}.flex__item4 {--span: 4;
}.flex__item5 {--span: 5;
}.flex__item6 {--span: 6;
}.flex__item7 {--span: 7;
}.flex__item8 {--span: 8;
}.flex__item9 {--span: 9;
}.flex__item10 {--span: 10;
}.flex__item11 {--span: 11;
}.flex__item12 {--span: 12;
}

你会看到的效果如下:

661408f957cd63057378e59b41f90eb8.png

在该示例中采用了CSS自定义属性相关的特性,让整个计算变得更容易一些。

对于使用CSS Grid布局模块来实现12列网格布局,相对而言,不管是HTML结构还是CSS代码都会更简易一些。在使用CSS Grid布局模块实现12列网格布局,将会运用到 repeat()、minmax()、gap 和 fr 等特性。具体的来看一个示例吧。

<!-- HTML -->
<grid__container><grid__item></grid__item>
</grid__container>

我们来看CSS代码:

  • 使用 fr 将网格均分为相等的值,即每列宽度都是 1 个 fr;配合 repeat() 函数,即 repeat(12, 1fr) 创建了12列网格。
  • 使用 gap 可以用来控制网格之间的间距。
  • 配合 minmax() 还可以设置网格最小值。

具体的代码如下:

:root {--columns: 12;--gap: 10px;--span: 1;
}.grid__container {display: grid;grid-template-columns: repeat(var(--columns), 1fr);grid-template-rows: 1fr;gap: var(--gap);padding-left: calc(var(--gap) / 2);padding-right: calc(var(--gap) / 2);
}.grid__item {min-block-size: 10vh;grid-column: span var(--span);
}.col1 {--span: 1;
}.col2 {--span: 2;
}.col3 {--span: 3;
}.col4 {--span: 4;
}.col5 {--span: 5;
}.col6 {--span: 6;
}.col7 {--span: 7;
}.col8 {--span: 8;
}.col9 {--span: 9;
}.col10 {--span: 10;
}.col11 {--span: 11;
}.col12 {--span: 12;
}

你将看到的效果如下:

17d57273350a15309bfb99a9895020ea.png

就该示例而言,grid-template-columns: repeat(12, 1fr) 创建网格如下图所示:

e2fd9e57d00d5ccbf090144b5c1b0a16.png

除了上述这种粗暴的方式,还可以更灵活一些,将 auto-fit、minmax() 以及 grid-auto-flow: dense 等来创建:

.grid__container {padding: 1em;display: grid;grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));gap: 1em;grid-auto-flow: dense;
}

对于 .grid__item 可以通过 grid-column、grid-row 来控制网格项目的位置:

288bdd61cfaf417ed735b17bafe03f55.png

加上 grid-auto-flow: dense 会根据Grid容器空间,Grid项目会自动流到合适的位置:

27473cc209e9a0cb99d9c69ddd30e0e2.png

这种布局对于杂志类的布局非常的适用。有关于这方面更详细的介绍可以阅读@Keir Watson的《Responsive Grid Magazine Layout in Just 20 Lines of CSS》一文。

七 两端对齐

在Web布局中时常碰到两端对齐的需求。在Flexbox布局中,时常在Flex容器中显式设置 justify-content 的值:

.flex__container {display: flex;flex-wrap: wrap;justify-content: space-between;width: 100%;
}

但在末尾行,如果和前面行的个数不相同(Flex项目)就会出现下图这样的效果:

9ce73e7dc2295143f52e89950f5126c6.png

像上图这样的效果,并不是我们所需要的,因为我们希望在最后一行的Flex项目不足够排列满一行时,希望Flex项目一个紧挨一个的排列:

0a18ed48cdb50ae9f2b7abac7c44eeb4.png

在Flexbox要实现上图这样的效果,只需要在Flex容器中添加一个伪元素:

.flex__container::after {content: "";display: flex;flex: 0 1 32vw;
}

注意,伪元素的 flex-basis 建议设置的和卡片的 flex-basis(或宽度)等同。这个时候你将看到像下面这样的示例:

d55bc4ce4d728b2375710c82c5df78ee.png

不过这种方式也不是最佳的方式,当末尾行的个数不只少一个时,就会出现下图这样的效果:

b5008437c6a819289b9308465b7c55b2.png

面对这样的场景,我们需要给Flex容器添加额外的空标签元素:

占位符元素数量 = 每行最大的列数 - 2

但是 gap属性出现之后,要实现这样的效果就不难了:

body {padding: 1vh;
}.flex__container {display: flex;flex-wrap: wrap;gap: 2vh;width: 100%;
}.flex__item {flex: 0 1 calc((100vw - 8vh) / 4);
}

效果如下:

1a68a2ed7cf32ced64e13d4c08b9a1cb.png

注意,gap 运用在Flexbox中到目前为止,仅得到了Firefox浏览器的支持。上面的示例,使用Firefox浏览器,你看到的效果如下:

c6bcf9df95f20475459e68dae981fd6f.png

在CSS Grid布局中,就可以直接使用 gap:

body {padding: 1vh;
}.grid__container {display: grid;grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));gap: 1vh;
}

效果如下:

9dc1de204b3eba6ed4545141f6062663.png

八 选择最佳的值

很多时候,针对不同的场景,设计师会为我们提供不同的设计风格,比如元素大小:

a9050bb39a7f63b4ca9fc55d7cfb82ba.png

随着 clam() 函数的到来,这一切都变得容易地多。

clam() 函数接受三个参数,即 clam(MIN, VAL, MAX),其中 MIN 表示最小值,VAL 表示首选值,MAX 表示最大值。它们之间:

  • 如果 VAL 在 MIN 和 MAX 之间,则使用 VAL 作为函数的返回值。
  • 如果 VAL 大于 MAX,则使用 MAX 作为函数的返回值。
  • 如果 VAL 小于 MIN,则使用 MIN 作为函数的返回值。

我们来看一个示例:

.element {/*** MIN = 100px* VAL = 50vw ➜ 根据视窗的宽度计算* MAX = 500px**/width: clamp(100px, 50vw, 500px);
}

比如浏览器视窗现在所处的位置是1200px的宽度,那么 .element 渲染的结果如下:

087ee2329f1347ba76fc1df997698b98.png

这个时候 .element 元素的 width 是 500px。此时,clamp(100px, 50vw, 500px) 相当于 clamp(100px, 600px, 500px),对应的 VAL 值是 600px,大于 MAX 值,那么这个时候 clamp() 函数返回的值是 MAX,即 500px,这个时候 .element 的 width 值就是 500px(即 MAX 的值)。

如果我们把浏览器视窗缩小至 760px:

27b92d48f37b5611f27e3203eccc978f.png

这个时候 .element 元素的 width 是 50vw。此时,clamp(100px, 50vw, 500px) 相当于clamp(100px, 380px, 500px),对应的 VAL 值是 380px,该值大于 MIN 值(100px),小于 MAX 值(500px),那么这个时候 clamp() 函数返回的值是 VAL,即 50vw,这个时候 .element 的 width 值就是 50vw(即 VAL 的值)。

如果继续将浏览器的视窗缩小至 170px:

f814a5d014e0851732e8aef8d5efa261.png

这个时候 .element 元素的 width 是 100px。此时,clamp(100px, 50vw, 500px) 相当于 clamp(100px, 85px, 500px),对应的 VAL 值是 85px,该值小于 MIN 值(100px),那么这个时候 clamp() 函数返回的值是 MIN,即 100px,这个时候 .element 的 width 值就是 100px(即 MIN 的值)。

就该示例而言,clamp(100px, 50vw, 500px) 还可以这样来理解:

  • 元素 .element 的宽度不会小于 100px(有点类似于元素设置了 min-width: 100px)。
  • 元素 .element 的宽度不会大于 500px(有点类似于元素设置了 max-width: 500px)。
  • 首选值 VAL 为 50vw,只有当视窗的宽度大于 200px 且小于 1000px 时才会有效,即元素 .element 的宽度为 50vw(有点类似于元素设置了 width:50vw)。

九 Logo图标的对齐

我想你在Web开发中可能碰到过类似下图的这样的场景:

20eb466d14882324b9050c7f3adc9c69.png

正像上图所示,Logo图像的有大有小(宽度和高度都不一样)。面对这样的业务场景,很多时候都希望设计师能提供相同尺寸的图像。但这样势必会影响Logo图像的外观。

前段时间看到@Ahmad Shadeed专门写了一篇博文《Aligning Logo Images in CSS》,就是介绍如何实现上图这样的布局效果。

其实实现这样的布局效果,主要运用到的就是CSS的 object-fit 属性,而这个属性早在多年前就得到了各大主流浏览器的支持。

这里我们用一个简单的示例,来看看具体实现过程。先来看HTML结构:

<!-- HTML -->
<ul class="brands"><li class="brands__item"><a href="#"><img src="img/logo.png" alt=""></a></li><li> <!-- ... --> </li>
</ul>

居中对齐前面已经介绍过了,这里主要是看图像大小方面的处理:

.brands {display: grid;grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));grid-gap: 1rem;
}.brands__item {background: #eee;
}.brands__item a {display: flex;justify-content: center;align-items: center;height: 100%;
}.brands__item img {width: 130px;height: 75px;object-fit: contain;
}

这样就能实现上图的效果。你可能发现了,有些Logo图像带有背景颜色,如果让效果更好一些,可以把CSS混合模式相关的特性运用进来:

.brands__item img {width: 130px;height: 75px;object-fit: contain;mix-blend-mode: multiply;
}

这个时候,你看到的效果如下:

ed82a7c64ff9060871c3fd78c88a89cd.png

object-fit 除了取值 contain 之外,还有其他几个值:

ffdc6b43cdea82ef865efca8c1ff243a.png

其实这个方案也适用于产品图片,人物头像等布局。

小结

文章中主要介绍了Web中一些布局的实现思路和具体方案。其实文章提到的效果,比如水平垂直居中、等高布局、平均分布列和Sticky Footer等,在CSS中一直有多种解决方案,只不过随着CSS Flexbox布局模块和CSS Grid布局模块的到来,实现这些效果变得更为灵活和简洁。

当然,文章中提到的只是一些最为常见的一些效果,其实在Web布局中,特别是Flexbox布局和Grid布局中还存在着很多有意思的东西,只不过因为篇幅的原因没有一一罗列。如果你感兴趣可以再挖掘一些出来,如果你在这方面有更好的经验或方案,欢迎在下面的评论中分享。最后希望这篇文章对你平时的工作有所帮助。

版权声明:本文中所有内容均属于阿里云开发者社区所有,任何媒体、网站或个人未经阿里云开发者社区协议授权不得转载、链接、转贴或以其他方式复制发布/发表。申请授权请邮件developerteam@list.alibaba-inc.com,已获得阿里云开发者社区协议授权的媒体、网站,在转载使用时必须注明"稿件来源:阿里云开发者社区,原文作者姓名",违者本社区将依法追究责任。 如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/564894.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java Float类详解

Float 类的构造方法 Float 类中的构造方法有以下 3 个。 Float(double value)&#xff1a;构造一个新分配的 Float 对象&#xff0c;它表示转换为 float 类型的参数。Float(float value)&#xff1a;构造一个新分配的 Float 对象&#xff0c;它表示基本的 float 参数。Float(S…

层次分析法之python

目录 1.简介 2.算法解析 3.实例分析 3.1 构造矩阵 3.2 查看行数和列数 3.3 求特征向量 3.4 找到最大特征值和最大特征向量 3.5 计算权重 3.6 一致性检验 3.7 计算评分 完整代码 1.简介 一种主观赋权的方法&#xff0c;在数据集比较小&#xff0c;实在不好比较的时候…

c++数字金字塔_“资金管理是投资最大的秘密”(超级干货),一生死记“金字塔加仓减仓法”,最安全稳健的操盘法方式!...

仓位控制不是精确的科学。它是保证资金安全、有效规避风险、长期稳定盈利的有效手段&#xff0c;有仓位控制意识和规则是股市交易者在心理和技术上成熟的表现之一&#xff0c;仓位控制是建立在市场和个股短期具有不可预测的特性、尊重市场、保证资金安全的基础上的。对于看好的…

Java Double类详解

Double 类的构造方法 Double 类中的构造方法有如下两个。 Double(double value)&#xff1a;构造一个新分配的 Double 对象&#xff0c;它表示转换为 double 类型的参数。Double(String s)&#xff1a;构造一个新分配的 Double 对象&#xff0c;它表示 String 参数所指示的 do…

matlab设置工作路径

目录 暂时修改路径 永久修改路径 暂时修改路径 a)直接在页面的路径框里粘贴想进的路径然后 回车 即可 b) 如果只是想暂时将文件夹加入路径&#xff0c;防止函数名字空间污染的话&#xff0c;可采用本方法&#xff1a;用MATLAB运行目标文件夹下任意一个m文件&#xff0c;MATL…

Java System类详解

System 类位于 java.lang 包&#xff0c;代表当前 Java 程序的运行平台&#xff0c;系统级的很多属性和控制方法都放置在该类的内部。由于该类的构造方法是 private 的&#xff0c;所以无法创建该类的对象&#xff0c;也就是无法实例化该类。 System 类提供了一些类变量和类方…

linux入门_linux入门-常用命令的使用

linux入门-常用命令的使用对于命令行的接触&#xff0c;最开始是window下的cmd&#xff0c;比如查看电脑ip地址、进入某一个文件夹、下载npm模块等等window cmdwindow ipconfig对于习惯了window桌面操作系统的用户来说&#xff0c;其实是比较少接触到命令行的&#xff0c;而在l…

MATLAB遇到问题:错误使用eval,未定义与‘struct‘类型的输入参数相对应的函数‘workspacefunc‘

安装好什么也没干&#xff0c;就开始报错&#xff0c;命令行窗口输入什么都是错误 错误使用eval 未定义与’struct’类型的输入参数相对应的函数’workspacefunc’ 解决方法&#xff1a; 在命令行窗口分别输入下面语句&#xff0c;箭头可不是哦&#xff0c;只有加粗部分是 &…

广西壮族自治区直流充电桩说明书下载_鄂州便携式直流充电桩

安徽能通新能源科技有限公司坐落在一座美丽宜居的城市中。在我国东部地区、长江下游、巢湖之滨&#xff0c;横贯连接京台高速、沪蓉高速、沪陕高速、合徐高速、京合高铁、合宁高铁、合福高铁、合武高铁、京九铁路、宁西铁路并与世界有名的自然和文化遗产—黄山风景区毗邻&#…

三大相关性分析之matlab

目录 1.简介 2.Pearson相关系数 算法详解 程序实现 3.Kendall相关系数 算法详解 程序实现 4.Spearman相关系数 算法详解 程序实现 1.简介 相关性分析是指对两个或多个具备相关性的变量元素进行分析&#xff0c;从而衡量两个变量因素的相关密切程度。相关性的元素之…

java反编译工具_Java开发必会的反编译知识(附支持对Lambda进行反编译的工具)...

我之前推送过Java代码的编译与反编译&#xff0c;其中简单的介绍了Java编译与反编译相关的知识&#xff0c;最近给GitChat写《深入分析Java语法糖》的时候&#xff0c;又用到了很多反编译相关的知识&#xff0c;遂发现哪篇文章已有些过时。于是&#xff0c;这篇文章就这样呈现在…

Java不规则数组

多维数组被解释为是数组的数组&#xff0c;所以因此会衍生出一种不规则数组。 规则的 43 二维数组有 12 个元素&#xff0c;而不规则数组就不一定了。如下代码静态初始化了一个不规则数组。 int intArray[][] {{1,2}, {11}, {21,22,23}, {31,32,33}};**高维数组&#xff08;…

三大相关性分析之python

目录 1.简介 2.Pearson相关系数 算法详解 程序实现 3.Kendall相关系数 算法详解 程序实现 4.Spearman相关系数 算法详解 程序实现 1.简介 相关性分析是指对两个或多个具备相关性的变量元素进行分析&#xff0c;从而衡量两个变量因素的相关密切程度。相关性的元素之…

c语言实现http服务器_基于postman实现http接口测试过程解析_服务器其它

这篇文章主要介绍了基于postman实现http接口测试过程解析,文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下无意中发现了一个巨牛的人工智能教程&#xff0c;忍不住分享一下给大家。教程不仅是零基础&#xff0c;通…

组合赋权法之matlab

目录 1.简介 2.算法原理 2.1 指标正向化 2.2 数据标准化 2.3 计算主观权重 2.4 计算客观权重 2.5 计算组合权重 2.6 计算的得分 3.实例分析 3.1 读取数据 3.2 指标正向化 3.3 数据范围标准化 3.4 计算主观权重 3.5 计算客观权重 3.6 计算组合权重 3.7 计算得分 …

组合赋权法之python

目录 1.简介 2.算法原理 2.1 指标正向化 2.2 数据标准化 2.3 计算主观权重 2.4 计算客观权重 2.5 计算组合权重 2.6 计算的得分 3.实例分析 3.1 读取数据 3.2 指标正向化 3.3 数据范围标准化 3.4 计算主观权重 3.5 计算客观权重 3.6 计算组合权重 3.7 计算得分…

蒙特卡罗模拟法 —— matlab

目录 1.简介 2.实例分析 2.1 模拟求近似圆周率 2.2 估算定积分 2.3 求解整数规划 1.简介 蒙特卡洛又称随机抽样或统计试验&#xff0c;就是产生随机变量&#xff0c;带入模型算的结果&#xff0c;寻优方面&#xff0c;只要模拟次数够多&#xff0c;最终是可以找到最优解或…

浏览器打开出现证书错误_2分钟轻松解决ie证书错误

我们日常在用IE上网的时候&#xff0c;可能会出现IE证书错误的提示&#xff0c;对于电脑小白来说会很痛苦&#xff0c;不妨跟小编一起学习&#xff0c;学会了下次就知道怎么解决了&#xff0c;下面就告诉大家&#xff0c;如何解决显示IE网页证书错误最基本的方法&#xff01;其…

蒙特卡罗模拟法 —— python

目录 1.简介 2.实例分析 2.1 模拟求近似圆周率 2.2 估算定积分 2.3 求解整数规划 1.简介 蒙特卡洛又称随机抽样或统计试验&#xff0c;就是产生随机变量&#xff0c;带入模型算的结果&#xff0c;寻优方面&#xff0c;只要模拟次数够多&#xff0c;最终是可以找到最优解或…

win10推送_Win10推送更新升级Edge浏览器:用户发现电脑速度因此变慢

新Win10让电脑变慢&#xff1f;如果你有类似感觉&#xff0c;那并非首例。据外媒报道&#xff0c;不完全汇总发现&#xff0c;在打上Windows 10补丁KB4559309, KB4541301或者KB4541302(视Windows版本不同)后&#xff0c;部分用户报告了启动速度以及日常运行程序变慢的情况。上述…