关于前端:收藏40-个-CSS-布局技巧

40次阅读

共计 16284 个字符,预计需要花费 41 分钟才能阅读完成。

简介: CSS 是 Web 开发中不可或缺的一部分,随着 Web 技术的一直变革,CSS 也变得更加弱小。CSS 的泛滥属性你晓得了多少?具体开发中该应用什么属性才最适宜失当?现在的一些 CSS 属性能够让咱们节约更多的工夫。比方在 Web 布局中,古代 CSS 个性就能够更好的帮忙咱们疾速实现如等高布局,程度垂直居中,经典的圣杯布局、宽高比例、页脚放弃在底部等成果。淘系前端技术专家大漠将具体介绍一些不同的 CSS 属性来实现这些成果,心愿对同学们有所帮忙。

一 程度垂直居中

如何实现程度垂直居中能够说是 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;
}

成果如下:

这种形式特地适应于让 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;
}

成果如下:

在这种模式之下,如果要让多个元素实现程度垂直居中的成果,那还须要加上 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;
}

成果如下:

在 Flexbox 布局中,还能够像上面这样让 Flex 我的项目在 Flex 容器中达到程度垂直居中的成果:

<!-- HTML -->
<div class="flex__container">
    <div class="flex__item"></div>
</div>

/* CSS */
.flex__container {
    display: flex; // 或 inline-flex
    justify-content: center;
}

.flex__item {align-self: center;}

成果如下:

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

.flex__container {
    display: flex; // 或 inline-flex
    justify-content: center;
}

.flex__container > * {align-self: center;}

比方上面这个成果:

除此之外,还能够应用 place-content: center 让 Flex 我的项目实现程度垂直居中:

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

.flex__item {align-self: center;}

成果如下:

或者换:

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

成果如下:

这两种形式同样实用于 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;
}

成果如下:

可能很多同学对于 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;}

成果如下:

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

Grid 中实现程度垂直居中

CSS Grid 布局能够说是古代 Web 布局中的银弹。它也是到目前为止布局零碎中惟一一个二维布局零碎。

在 CSS Grid 布局中,只须要仅仅的几行代码也能够疾速的帮忙咱们实现程度垂直居中的成果。比方上面这个示例:

<!-- HTML -->
<div class="grid__container">
    <div class="grid__item"></div>
</div>

/* CSS */
.grid {
    display: grid; // 或 inline-grid
    place-items: center
}

成果如下:

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

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

这种办法也实用于 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>

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

而且 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;
}

成果如下:

二 等高布局

等高布局也是 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。

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

这种形式特地实用于卡片组件中:

在 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; /* 依据需要调整值 */
}

成果如下:

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

如果需要有所调整,比方在 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%;}

成果如下:

三 Sticky Footer

首先用下图来形容什么是 Sticky Footer 布局成果:

Sticky Footer 实现计划和等高、垂直居中一样,同样有很多种计划能够实现。

比方像上面这样的构造:

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

先来看 Flexbox 布局模块中的实现计划:

body {
    display: flex;
    flex-direction: column;
}

footer {margin-top: auto;}

能够尝试着在 main 区域右下角向下拖动,扭转主内容区域的高度,你会发现“当内容有余一屏时,会在页面的最底部,当内容超出一屏时,会主动往后延后”。

在 Flexbox 布局中,还能够在 区域上设置上面的款式,达到相等的成果:

body {
    display: flex;
    flex-direction: column;
}

main {flex: 1 0 auto;}

成果如下:

中的 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;
}

成果如下:

四 均分列

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

在 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);
}

成果如下:

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

在 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;}

成果如下:

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

接下来看 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 示意具体的列数 */
}

最终的成果是雷同的:

这样的布局形式也实用于其余的布局中。但不论是 Flexbox 还是 Grid 布局中,都存在肯定的缺点,当容器没有足够的空间包容 Flex 我的项目(或 Grid 我的项目)时,Flex 我的项目或 Grid 我的项目会溢出(或暗藏,如果 Flex 容器或 Grid 容器显式设置了 overflow:hidden):

修复这种景象最简略的形式是在 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 的基准值 */
}

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

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

.flex__item {flex: 0 0 400px;}

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

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

.flex__item {flex: 1 0 400px;}

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

在 Grid 中实现相似的成果要更简单一点。能够应用 repeat() 函数,1fr 以及 auto-fit 等个性:

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

成果如下:

如果你对这方面常识感兴趣的话,还能够移步浏览《Container Query Solutions with CSS Grid and Flexbox》一文。

其实在 Grid 中与 auto-fit 比照的值还有一个叫 auto-fill。但两者的差别是十分地大,用下图来形容 auto-fit 和 auto-fill 的差别:

另外这种形式也是到目前为止一种不须要借助 CSS 媒体查问就能够实现响应式布局成果。

五 圣杯布局

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

对于圣杯布局而言,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;}

成果如下:

通过在 nav、aside 和 article 上显式设置 order 的值,能够很好的管制这三个区域的布局程序。比如说,心愿 在 之前排列,只须要在下面的示例根底上做一点点调整:

nav {order: 0;}

aside {order: -1;}

成果如下:

留神,order 的默认值为 0,值越大越排在前面!

在上例的根底上,借助 CSS 媒体对象的个性,能够很容易实现响应式的圣杯布局成果:

@media screen and (max-width: 800px) {
    main {flex-direction: column;}

    nav, aside {width: 100%;}
}

成果如下:

尝试着拖动浏览器来扭转视窗大小,你能够看到如下图的成果:

在 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;}

成果如下:

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

和 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;}
}

除了 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";
    }
}

成果如下:

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

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

如果咱们心愿 的区域变得更大,那么能够在 grid-template-areas 上做个调整:

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

成果如下:

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

尽管在成果有所调整了,但还是均分状态。更好的解决方案是,将 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;
    }
}

成果如下:

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

六 12 列网格布局

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

12 列网格布局在设计零碎和 CSS Framework 中常常应用,比方业内经典的 Bootstrap 就采纳了 12 列网格布局零碎:

在社区中也有很多在线工具,帮忙咱们疾速构建 12 列网格零碎,比方 Free CSS Grid Tools & Resources For Developers 一文中列举的工具。

不过这里次要是想和大家一起看看在 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 构造,行中有三列,每列的宽度刚好四个网格宽度加两个列间距。并且在计算的时候有一套成熟的计算公式:

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

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

: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 1
        calc((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;}

你会看到的成果如下:

在该示例中采纳了 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;}

你将看到的成果如下:

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

除了上述这种粗犷的形式,还能够更灵便一些,将 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 来管制网格我的项目的地位:

加上 grid-auto-flow: dense 会依据 Grid 容器空间,Grid 我的项目会主动流到适合的地位:

这种布局对于杂志类的布局十分的实用。有对于这方面更具体的介绍能够浏览 @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 我的项目)就会呈现下图这样的成果:

像上图这样的成果,并不是咱们所须要的,因为咱们心愿在最初一行的 Flex 我的项目不足够排列满一行时,心愿 Flex 我的项目一个紧挨一个的排列:

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

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

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

不过这种形式也不是最佳的形式,当开端行的个数不只少一个时,就会呈现下图这样的成果:

面对这样的场景,咱们须要给 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);
}

成果如下:

留神,gap 使用在 Flexbox 中到目前为止,仅失去了 Firefox 浏览器的反对。下面的示例,应用 Firefox 浏览器,你看到的成果如下:

在 CSS Grid 布局中,就能够间接应用 gap:

body {padding: 1vh;}

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

成果如下:

八 抉择最佳的值

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

随着 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 渲染的后果如下:

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

如果咱们把浏览器视窗放大至 760px:

这个时候 .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:

这个时候 .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 开发中可能碰到过相似下图的这样的场景:

正像上图所示,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;
}

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

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

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

小结

文章中次要介绍了 Web 中一些布局的实现思路和具体计划。其实文章提到的成果,比方程度垂直居中、等高布局、均匀散布列和 Sticky Footer 等,在 CSS 中始终有多种解决方案,只不过随着 CSS Flexbox 布局模块和 CSS Grid 布局模块的到来,实现这些成果变得更为灵便和简洁。

当然,文章中提到的只是一些最为常见的一些成果,其实在 Web 布局中,特地是 Flexbox 布局和 Grid 布局中还存在着很多有意思的货色,只不过因为篇幅的起因没有一一列举。如果你感兴趣能够再开掘一些进去,如果你在这方面有更好的教训或计划,欢送在上面的评论中分享。最初心愿这篇文章对你平时的工作有所帮忙。

正文完
 0