写在开头
哈喽,各位看官早上好呀。😀
人活着要有生活的目标,一辈子的目标,一段时间的目标,一个阶段的目标,一年的目标,一个月的目标,一个星期的目标,一天一小时一分钟的目标。
------(俄国)列夫·托尔斯泰
离过年已经过去一个多月了,都说人活着要有目标,新的一年小编也给自己定了各种各样的目标,足足十大项,每天忙得不亦乐乎,刷手机短视频时间也减少很多了耶😆,就是不知道到年底能完成几个Flag,尽力而为吧,加油❗
今天给各位大大分享的是一篇 CSS
技巧的文章,主要是网格布局(grid
)与 var()
函数相结合应用方面的。
如果你觉得内容还不错,希望您能给小编点个赞呗,谢谢了。😁
九宫格
如上图,这是我们要实现的第一个效果,可能看着挺复杂的,实际我们仅需 HTML+CSS
就能完成啦。
在继续往下看之前,小编希望你对
grid
布局有一定了解哦,不了解其实也没关系,小编标上详细注释,问题不大。😂
先来构建一个九宫格结构:
javascript
<div class="box">
<img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c09cf20b89f64392a5a3348ab2700201~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis" />
<img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9e32595c18264cb19d253e3818780fdf~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis" />
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/012f26b7191a479fb170d919c4ffbe5f~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis" />
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/da61b167975f4d0f97aeb0efb733f39c~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis#?w=2560&h=1440&s=1383522&e=jpg&b=84713e" />
<img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/17afe5f019774f85bf7f5463e92e95c4~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis#?w=3840&h=2160&s=2406233&e=jpg&b=e59c77" />
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3a5273c488dc46cba4bec37c93897eba~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis#?w=1920&h=1080&s=517958&e=jpg&b=78d1e3" />
<img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/34e76d8eefc14e46be3a78a2f9ff7ee0~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis#?w=1920&h=1080&s=959879&e=jpg&b=dac6b7" />
<img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/abfe0341b25d4db8853f6bb3ace73f40~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis" />
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/49951c3ded774e62bbd1ce76b2a24de6~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis" />
</div>
样式:
css
.box {
/* 定义一个格子大小 */
--size: 100px;
/* 定义格子之间的间隔 */
--gap: 10px;
display: grid;
/* 格子之间的间隔 */
gap: var(--gap);
/* 容器宽度=3个格子+2个间隔 */
width: calc(3 * var(--size) + 2 * var(--gap));
/* 保持格子的宽高比例 */
aspect-ratio: 1;
/* 生成三列 */
grid-template-columns: repeat(3, auto);
}
.box img {
width: 0;
height: 0;
min-height: 100%;
min-width: 100%;
object-fit: cover;
transition: 0.28s linear;
}
aspect-ratio: 1; 等同于 height: calc(3 * var(--size) + 2 * var(--gap));
grid-template-columns: repeat(3, auto); 等同于 grid-template-columns: auto auto auto;
为什么说要稍微了解一下 grid
布局,就是怕这两个属性有的小伙伴没接触过😄,可以上MDN瞧瞧哈,挺简单基础的东西了。
还有就是子元素图片的样式,这里的图片既没有宽度也没有高度,但是最小宽度和高度都为 100%
,这是一个非常巧妙的技巧,后面我们的图片缩放效果就是依赖这个样式实现。
上面我们仅通过
grid-template-columns: repeat(3, auto);
属性就创造了一个九宫格,可能你会想,这个属性不是仅定义了列
吗?行
呢?浏览器怎么知道我们要创建多少行?这主要是我们并不需要显示的定义行的数量,
CSS Grid
能够自动将子元素放置在隐式的行和列上。Em...这是
Grid
的一个基础规则吧,学了你就懂了。😁
现在我们就拥有一个最简单的九宫格结构了,接下来我们来给它加上缩放的效果。
css
.box {
...
/* 定义缩放比例 */
--scale: 1.2;
...
}
.box img:hover{
width: calc(var(--size) * var(--scale));
height: calc(var(--size) * var(--scale));
}
没了,就这样😦,我们轻易完成了上面动图的效果,是不是非常简单。但在没有 CSS Grid
之前,要实现这么一个效果,可是要费不少劲来着。
当然,尽管这个过程看起来很简单,代码量也不多,但要深入理解其背后的原理,你需要对 CSS Grid
有足够的了解和基础知识。😗
任意数量
上面,我们成功构建了一个 3x3
的九宫格,但实际情况中,我们可能需要不同尺寸的网格布局,比如 3x4
或 4x4
等等,接下来我们就来解决这个问题。
css
.box {
...
/* 定义行数量 */
--row: 3;
/* 定义列数量 */
--column: 4;
display: grid;
gap: var(--gap);
/* 容器宽度=列数*格子大小 + 格子间隔 */
width: calc(var(--column) * var(--size) + (var(--column) - 1) * var(--gap));
/* 容器宽度=行数*格子大小 + 格子间隔 */
height: calc(var(--row) * var(--size) + (var(--row) - 1) * var(--gap));
/* 列数根据需求生成 */
grid-template-columns: repeat(var(--column), auto);
}
我们把 行
和 列
单独抽出来定义成变量,让容器的宽度和高度、列数的生成都通过这些变量来重新计算。
这样我们就能生成任意数量的网格了,对了,记得把子元素的图片补齐噢❗
不定宽高
既然都能任意数量的格子了,那么,格子的宽度与高度我们肯定也希望不是固定的,像上面例子都是 100px
的正方形,能不能搞个长方形呢?😐
当然可以,这不 so easy 的事嘛!
css
.box {
...
/* 定义格子宽度 */
--width: 150px;
/* 定义格子高度 */
--height: 120px;
display: grid;
gap: var(--gap);
/* 容器宽度=列数*格子大小 + 格子间隔 */
width: calc(var(--column) * var(--width) + (var(--column) - 1) * var(--gap));
/* 容器宽度=行数*格子大小 + 格子间隔 */
height: calc(var(--row) * var(--height) + (var(--row) - 1) * var(--gap));
grid-template-columns: repeat(var(--column), auto);
}
.box img:hover{
width: calc(var(--width) * var(--scale));
height: calc(var(--height) * var(--scale));
}
一样,我们被格子的宽度和高度单独定义成变量,替换原理的 --size
即可。
全屏
有时,我们希望做一个全屏的照片墙,这又要如何解决呢❓
要做一个全屏的照片墙,意味我们要把 .box
容器铺满一屏,而铺满一屏的容器宽度和高度我们可以直接使用 100vw
与 100vh
。
css
.box {
...
width: 100vw;
height: 100vh;
...
}
但是,这还没完,里面格子的宽度与高度呢?
最开始我们提过,容器宽度=3个格子+2个间隔
,其实就是"容器宽度=格子总宽度+格子之间的总间隔"。
也就可以推断出如下:
javascript
100vw = var(--column) * var(--width) + (var(--column) - 1) * var(--gap)
100vh = var(--row) * var(--height) + (var(--row) - 1) * var(--gap)
再反推格子的宽度与高度,可以得到:
javascript
--width: (100vw - (var(--column) - 1) * var(--gap)) / var(--column)
--height: (100vh - (var(--row) - 1) * var(--gap)) / var(--row)
最后,把它们带入我们定义的样式变量即可:
css
.box {
...
/* 不需要太大的缩放,防止溢出屏幕外 */
--scale: 1;
--width: calc((100vw - (var(--column) - 1) * var(--gap)) / var(--column));
--height: calc((100vh - (var(--row) - 1) * var(--gap)) / var(--row));
display: grid;
gap: var(--gap);
width: 100vw;
height: 100vh;
...
/* 防止出行滚动条 */
box-sizing: border-box;
}
body {
padding: 0;
margin: 0;
display: grid;
place-content: center;
box-sizing: border-box;
}
由于我们是全屏铺满,注意要清一下 body
的默认样式,还有 :hover
的时候由于是全屏铺满,可能会导致出现滚动条,需要我们设置 box-sizing: border-box;
样式,并且适当的调整缩放比例(--scale
),防止溢出屏幕外。
(效果图就不放了,质量太大,有点卡😅)
手风琴
最后,我们再来做一个手风琴的效果来结尾。
其实也比较简单了,我们仅需要调整相应的样式变量即可。
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
height: 100vh;
display: grid;
place-content: center;
}
.box {
/* 注意是0px,不是0 */
--gap: 0px;
--scale: 1.5;
--row: 1;
--column: 5;
--width: 100px;
--height: 300px;
display: grid;
gap: var(--gap);
width: calc(var(--column) * var(--width) + (var(--column) - 1) * var(--gap));
height: calc(var(--row) * var(--height) + (var(--row) - 1) * var(--gap));
grid-template-columns: repeat(var(--column), auto);
}
.box img {
width: 0;
height: 0;
min-height: 100%;
min-width: 100%;
object-fit: cover;
transition: 0.28s linear;
}
.box img:hover{
width: calc(var(--width) * var(--scale));
/* 高度不变 */
height: var(--height);
}
</style>
</head>
<body>
<div class="box">
<img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c09cf20b89f64392a5a3348ab2700201~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis" />
<img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9e32595c18264cb19d253e3818780fdf~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis" />
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/012f26b7191a479fb170d919c4ffbe5f~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis" />
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/da61b167975f4d0f97aeb0efb733f39c~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis#?w=2560&h=1440&s=1383522&e=jpg&b=84713e" />
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3a5273c488dc46cba4bec37c93897eba~tplv-k3u1fbpfcp-jj:135:90:0:0:q75.avis#?w=1920&h=1080&s=517958&e=jpg&b=78d1e3" />
</div>
</body>
</html>
注意,间隔(--gap
)是 0px
不是 0
,或者你直接写死你想要的手风琴宽度与宽度也可以的。
至此,本篇文章就写完啦,撒花撒花。
希望本文对你有所帮助,如有任何疑问,期待你的留言哦。
老样子,点赞+评论=你会了,收藏=你精通了。