前言
最近在学习grid布局,发现了一个很有意思的布局(来自Code Pen上一位神奇的网友所做),如下图:
是一个电子商务的网页,页面上陈列着琳琅满目的鞋子,这些鞋子呈阶梯式摆放,给人一种3d空间的视觉。
那么它是怎么实现的呢?发动你的小脑袋,好好想一下。
好了,如果你还没想到,那么就跟着我,一起来解密下这个网页是如何实现的吧~
一起来解密吧~
这个阶梯式网格我们可以使用网格布局实现。
具体步骤
第一步、先把DOM结构建立下
<div class="container">
<div class="adidas">
<div class="desc">
<h2>I-5923 RUNNER PRIDE</h2>
<p>£99.95</p>
</div>
<img src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/881020/adidas01.png' alt='' />
</div>
<div class="tiger">
<div class="desc">
<h2>TIGER ALLY</h2>
<p>£95.00</p>
</div>
<img src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/881020/tiger05.png' alt='' />
</div>
<div class="adidas">
<div class="desc">
<h2>NMD_R1</h2>
<p>£109.95</p>
</div>
<img src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/881020/adidas02.png' alt='' />
</div>
</div>
container是父容器,每一个放置鞋子的格子是子元素,这个子元素可无限增加。子元素中包含描述性文字desc和鞋子元素。
这样我们的dom结构就完成了,很简单是不是。
第二步、网格布局
使用一张这样的图片让它作为父容器的背景,并且平铺满整个网页。
.container {
margin: 100px 0;
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 600 1040' xmlns='http://www.w3.org/2000/svg' fill-rule='evenodd' clip-rule='evenodd' stroke-linejoin='round' stroke-miterlimit='2'%3E%3Cpath d='M0 0l300 173.205v346.41L0 346.41V0z' fill='url(%23_Linear1)'/%3E%3Cpath d='M300 519.615L600 692.82v346.411L300 866.025v-346.41z' fill='url(%23_Linear2)'/%3E%3Cpath d='M600 0L300 173.205v346.41L600 346.41V0z' fill='url(%23_Linear3)'/%3E%3Cpath d='M300 519.615L0 692.82v346.411l300-173.206v-346.41z' fill='url(%23_Linear4)'/%3E%3Cdefs%3E%3ClinearGradient id='_Linear1' x1='0' y1='0' x2='1' y2='0' gradientUnits='userSpaceOnUse' gradientTransform='rotate(-30 646.41 173.205) scale(346.41)'%3E%3Cstop offset='0' stop-color='%23b7ccc3'/%3E%3Cstop offset='1' stop-color='%23cde2d9'/%3E%3C/linearGradient%3E%3ClinearGradient id='_Linear2' x1='0' y1='0' x2='1' y2='0' gradientUnits='userSpaceOnUse' gradientTransform='rotate(-30 1766.025 -126.796) scale(346.41)'%3E%3Cstop offset='0' stop-color='%23b7ccc3'/%3E%3Cstop offset='1' stop-color='%23cde2d9'/%3E%3C/linearGradient%3E%3ClinearGradient id='_Linear3' x1='0' y1='0' x2='1' y2='0' gradientUnits='userSpaceOnUse' gradientTransform='rotate(-150 346.41 92.82) scale(346.41)'%3E%3Cstop offset='0' stop-color='%23e8dad1'/%3E%3Cstop offset='1' stop-color='%23fff0e7'/%3E%3C/linearGradient%3E%3ClinearGradient id='_Linear4' x1='0' y1='0' x2='1' y2='0' gradientUnits='userSpaceOnUse' gradientTransform='rotate(-150 266.025 392.82) scale(346.41)'%3E%3Cstop offset='0' stop-color='%23e8dad1'/%3E%3Cstop offset='1' stop-color='%23fff0e7'/%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E");
/* (100% / var(--columns)) * 2 图片的大小是每一列的2倍,平铺展示。 */
background-size: calc(200% / (var(--columns)));
}
此时body的背景色是红色,便于看到背景图的平铺效果,后面设置成需要的颜色。
我们想让他在一行展示1个格子,故我们需要3列。
:root {
--columns: 3;
}
body {
background-color: #E7FFF4;
}
.container {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
}
鞋子是放在一个格子内的,给网格项元素设置样式
.container > div {
/*子元素定位使用 */
position: relative;
/*每个格子占据两列*/
grid-column-end: span 2;
/*撑起div高度是宽度的86.66% */
padding-bottom: 86.66%;
}
我们发现每一行第一个格子都是从第二条网格线开始的,故
.container > div:nth-child(2n-1) {
grid-column-start: 2;
}
接下来,将鞋子放在网格的中间
img {
/*水平居中*/
position: absolute;
left: 50%;
transform: translateX(-50%);
/* 设置一个合理的宽度 */
width: 62%;
}
到这一步,效果是这样的
将鞋子放低一点,设置bottom
img {
bottom: -10%;
}
想要有空间感,我们给鞋子搞一个底部阴影
img {
-webkit-filter: drop-shadow(0 50px 20px rgba(0, 0, 0, 0.20));
filter: drop-shadow(0 50px 20px rgba(0, 0, 0, 0.20));
}
接下来我们给鞋子添加个浮动效果,鼠标移上去,鞋子向上浮动,投影也相应变大。
img {
transition-property: bottom, filter, -webkit-filter;
transition-duration: .3s;
}
img:hover {
bottom: 0;
-webkit-filter: drop-shadow(0 80px 40px rgba(0, 0, 0, 0.20));
filter: drop-shadow(0 80px 30px rgba(0, 0, 0, 0.20));
cursor: pointer;
}
鞋子的效果实现了,接下来我们设置下左侧边上的信息样式。
.desc {
position: absolute;
/*想要文字不超过侧边格子,宽度设置50%*/
width: 50%;
padding: 3%;
}
接下啦让文字贴在左侧边上,预估下左侧边倾斜角度为30度,此时我们将文字变形30度就OK
.desc {
/* 沿着y轴逆时针变形30度,让文字贴在格子上 */
transform: skewy(-30deg);
margin-top: 14%;
}
效果杠杠的~
接下来,实现格子右侧边上的logo,和左侧边同理
直接使用伪元素,将logo定位到相应位置
.container > div:before {
content: "";
position: absolute;
right: 0;
width: 50%;
height: 100%;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/881020/adidas.png);
background-repeat: no-repeat;
background-size: 40%;
background-position: 90% 27%;
}
再变形+设置透明度
.container > div:before {
transform: skewy(30deg);
opacity: 0.6;
}
到此一个格子的样式就完成了。
如果想要设置不同的logo,那就单独
.tiger:before{
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/881020/tiger.png) !important;
}
最终效果
这是在一行只放置一个格子的情况下,适合小屏幕。
那么大屏幕下,一行可以放置多个格子,怎么实现呢?
响应式布局
我们通过媒体查询,设置几个屏幕尺寸,600,900,1200,1500,1800,2100,对这几个尺寸做响应式布局。
1、最小屏幕600px,一行5列,2个格子,每4n-3个格子就缩进一列。
@media (min-width:600px){
:root {
--columns: 5;
}
/*1,3,5,7...*/
.container div:nth-child(2n-1){
grid-column-start:auto;
}
/*1,5,9,13.. (格子数)*/
.container div:nth-child(4n-3){
grid-column-start: 2;
}
}
2、屏幕最小为900时,一行7列,3个格子
@media (min-width:900px){
:root {
--columns: 7;
}
/* 重置上一次设置的值 */
.container div:nth-child(4n-3){
grid-column-start:auto;
}
.container div:nth-child(6n-5){
grid-column-start: 2;
}
}
从这两次我们可以得到规律,当columns
为x
时,grid-column-start
的值为(x-1)n - (x-2)
。
以此类推,当屏幕最小为1200px,columns为9
@media (min-width:1200px){
:root {
--columns: 9;
}
/* 重置上一次设置的值 */
.container div:nth-child(6n-5){
grid-column-start:auto;
}
.container div:nth-child(8n-7){
grid-column-start: 2;
}
}
当屏幕最小为1500px,columns为11
@media (min-width:1500px){
:root {
--columns: 11;
}
/* 重置上一次设置的值 */
.container div:nth-child(8n-7){
grid-column-start:auto;
}
.container div:nth-child(10n-9){
grid-column-start: 2;
}
}
当屏幕最小为1800px,columns为13
@media (min-width:1800px){
:root {
--columns: 11;
}
/* 重置上一次设置的值 */
.container div:nth-child(10n-9){
grid-column-start:auto;
}
.container div:nth-child(12n-11){
grid-column-start: 2;
}
}
当屏幕最小为2100px,columns为15
@media (min-width:2100px){
:root {
--columns: 11;
}
/* 重置上一次设置的值 */
.container div:nth-child(12n-11){
grid-column-start:auto;
}
.container div:nth-child(14n-13){
grid-column-start: 2;
}
}
小结
很神奇,如果第一次拿到这样的设计稿,我应该会无从下手,grid布局很强大。从这个demo中我们可以学习到:
- 背景图平铺
- grid布局的实践应用
- 变形
这些知识点很简单,分开我们都知道,但他们结合起来就可以实现这么有意思的布局。
知识点仅仅是知道还不够,我们要学会融会贯通~
原文链接:https://juejin.cn/post/7316723621292916774 作者:叁两