现代 CSS

图解CSS: Grid布局(Part19)

特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)

CSS Grid 模块的出现以及浏览器对其支持,为 Web 布局提供了前所未有的可能性。我们可以用更少的元素(更简洁的 HTML 结构)构建更复杂的设计。这比我们一直认为非常强大的 Flexbox 要更强很多。但是,当你想到 CSS Grid 时,你一般会想到是我们平时习以为常的方块布局,对吗?

@Andy Barefoot他的个人网站Codepen 上提供了很多有创意的响应式布局效果,让你会对 Web 布局有一种焕然一新的感觉,感觉与你的经典 Web 设计(规规矩矩方块布局),而且他使用了 CSS Grid 布局来做到这一点。

正如 个人网站采用的 CSS Grid 网格布局,比如 3D 盒子,为不三不同面构建不同的网格系统:

@Andy Barefoot

首页中的每个 3D 盒子对应的是一个 Grid 案例,而且都是很有创意的案例,并且在 Codepen 都有较高的阅读量和点赞数。我们来看几个有意思的案例:

这几个案例除了创意新颖之外,他们还有一个共同的特性,具有响应式网格布局:

案例背景和特征

接下来以上面两个案例为示例,和大家一起聊聊,如何基于 CSS Grid 布局模块和其他 CSS 特性来实现上图的 Web 设计效果。

这两个示例都是响应式布局,随着视窗大小改变,布局也会调整:

除了具有响应式效果之外,它们还有一个共同的特征:不同层的叠加。另外,它们都采用了相似的 CSS 特性,比如 CSS 网格布局、自定义属性 和媒体查询等。

设置网格

先从 HTML 结构开始:

有着非常相似的 HTML 结构,用极简的 DOM 结构来完成很多事情。

<!-- HTML: Case1 -->
<ul>
    <li>
        <img src="fashion1.png" >
        <div>
            <h2> The Ruched Air Blouse</h2>
            <p>$55</p>
        </div>
    </li>
</ul>

<!-- HTML Case2 -->
<ul>
    <li>
        <img src="book.png" />
    </li>
</ul>

让我们来谈谈网格的设置,即ul创建网格容器。另外我们会用到响应式,因此在整个示例中离不开 CSS 的媒体查询,同时为了更为灵活的控制CSS,将还会使用 CSS的自定义属性。

同样遵循响应式设计的理念之一:移动端先行,为此先为移动端声明网格列轨道数量:

/* 为最小的视口设置默认列轨道数量 */

:root {
    --columns: 1;
}

/* 根据 --columns 来制作同等大小的列 */

ul {
    display: grid;
    grid-template-columns: repeat(var(--columns), 1fr);
}

使用 @media 在不同断点改变 --columns 的值即可:

/* Case 1: Product*/
@media (min-width:600px){
    :root {
        --columns: 2;
    }
}
@media (min-width:900px){
    :root {
        --columns: 3;
    }
}
@media (min-width:1200px){
    :root {
        --columns: 4;
    }
}
@media (min-width:1500px){
    :root {
        --columns: 5;
    }
}
@media (min-width:1800px){
    :root {
        --columns: 6;
    }
}


/* Case 2: Book */
@media (min-width:600px){
    :root {
        --columns: 5;
    }
}
@media (min-width:900px){
    :root {
        --columns: 7;
    }
}
@media (min-width:1200px){
    :root {
        --columns: 9;
    }
}
@media (min-width:1500px){
    :root {
        --columns: 11;
    }
}
@media (min-width:1800px){
    :root {
        --columns: 13;
    }
}
@media (min-width:2100px){
    :root {
        --columns: 15;
    }
}

设置好网格,就需要使用 grid-*(比如grid-columngrid-rowsgrid-area)来明确放置网格项目:

/* Case 2: Book */
li {
    grid-column-end: span 2;
}

li:nth-child(2n) {
    grid-column-start: 2;
}

@media (min-width: 600px) {
    li:nth-child(2n) {
        grid-column-start: auto;
    }
    li:nth-child(4n-1) {
        grid-column-start: 2;
    }
}

@media (min-width: 900px) {
    li:nth-child(4n-1) {
        grid-column-start: auto;
    }
    li:nth-child(6n-2) {
        grid-column-start: 2;
    }
}

@media (min-width: 1200px) {
    li:nth-child(6n-2) {
        grid-column-start: auto;
    }
    li:nth-child(8n-3) {
        grid-column-start: 2;
    }
}

@media (min-width: 1500px) {
    li:nth-child(8n-3) {
        grid-column-start: auto;
    }
    li:nth-child(10n-4) {
        grid-column-start: 2;
    }
}

@media (min-width: 1800px) {
    li:nth-child(10n-4) {
        grid-column-start: auto;
    }
    li:nth-child(12n-5) {
        grid-column-start: 2;
    }
}

@media (min-width: 2100px) {
    li:nth-child(12n-5) {
        grid-column-start: auto;
    }
    li:nth-child(14n-6) {
        grid-column-start: 2;
    }
}

注意,Case1中的网格项目是自动放置的。

将形状拼接在一起

示例中的每张卡片都有四个层级:

除了 HTML 元素之外还借助了 CSS 伪元素 ::before::after。他们的层级关系是:

就拿示例2中的书本层级,合在一起的过程和效果:

实现单个图形效果

第一个效果相对而言,要简单很多,花纹前景和背景采用的都是 SVG 图:

剩余80%内容付费后可查看
返回顶部