你多久接触一次 CSS background-size
财产? 如果你和我一样——可能还有很多其他前端人员——那么通常是当你 background-size: cover
一个图像来填充整个元素的空间。
好吧,我遇到了一个有趣的挑战,需要更高级的背景尺寸调整:悬停时过渡的背景条纹。 检查一下并用光标将其悬停:
除了背景的大小之外,还有很多事情要做,但这是我需要让条纹过渡的技巧。 我想我会告诉你我是如何到达那里的,不仅因为我认为它是一个非常好的视觉效果,而且因为它需要我通过我认为你可能会喜欢的渐变和混合模式来发挥创意。
让我们从一个非常基本的设置开始,以使事情变得简单。 我说的是单身
在样式为绿色方块的 HTML 中:
div {
width: 500px;
height: 500px;
background: palegreen;
}
设置背景条纹
如果您在看到这些条纹时直接想到 CSS 线性渐变,那么我们已经在同一页上了。 在这种情况下,我们不能完全重复渐变,因为我们希望条纹占据不均匀的空间量并对其进行过渡,但我们可以通过将五个背景链接到现有背景颜色之上并将它们放在顶部来创建五个条纹-容器右侧:
div {
width: 500px;
height: 500px;
background:
linear-gradient(black, black) top right,
linear-gradient(black, black) top 100px right,
linear-gradient(black, black) top 200px right,
linear-gradient(black, black) top 300px right,
linear-gradient(black, black) top 400px right,
palegreen;
}
我做了水平条纹,但我们也可以用我们在这里介绍的方法垂直。 我们可以使用自定义属性来简化这一过程:
div {
--gt: linear-gradient(black, black);
--n: 100px;
width: 500px;
height: 500px;
background:
var(--gt) top right,
var(--gt) top var(--n) right,
var(--gt) top calc(var(--n) * 2) right,
var(--gt) top calc(var(--n) * 3) right,
var(--gt) top calc(var(--n) * 4) right,
palegreen;
}
所以, --gt
值是梯度和 --n
是我们用来向下推动条纹的常量,因此它们垂直偏移。 你可能已经注意到我没有设置真正的渐变,而是在 linear-gradient()
功能——这是有意为之的,我们稍后会解释为什么要这样做。
在继续之前我们应该做的另一件事是防止我们的背景重复; 否则,它们将平铺并填满整个空间:
div {
--gt: linear-gradient(black, black);
--n: 100px;
width: 500px;
height: 500px;
background:
var(--gt) top right,
var(--gt) top var(--n) right,
var(--gt) top calc(var(--n) * 2) right,
var(--gt) top calc(var(--n) * 3) right,
var(--gt) top calc(var(--n) * 4) right,
palegreen;
background-repeat: no-repeat;
}
我们可以设置 background-repeat
,在 background
速记,但我决定在这里打破它以使事情易于阅读。
偏移条纹
从技术上讲,我们有条纹,但很难分辨,因为它们之间没有间距,而且它们覆盖了整个容器。 它更像是我们有一个实心的黑色方块。
这是我们可以使用的地方 background-size
财产。 我们想要设置条纹的高度和宽度,并且该属性支持双值语法,使我们能够做到这一点。 而且,我们可以通过逗号分隔这些大小来链接它们,就像我们在 background
.
让我们先从设置宽度开始。 使用单值语法 background-size
设置宽度并将高度默认为 auto
. 我在这里使用了完全任意的值,因此将值设置为最适合您的设计:
div {
--gt: linear-gradient(black, black);
--n: 100px;
width: 500px;
height: 500px;
background:
var(--gt) top right,
var(--gt) top var(--n) right,
var(--gt) top calc(var(--n) * 2) right,
var(--gt) top calc(var(--n) * 3) right,
var(--gt) top calc(var(--n) * 4) right,
palegreen;
background-repeat: no-repeat;
background-size: 60%, 90%, 70%, 40%, 10%;
}
如果您使用与我相同的值,您将得到:
看起来不像我们为所有条纹设置了宽度,是吗? 那是因为 auto
单值语法的高度行为。 第二条条纹比它下面的其他条纹宽,并且覆盖了它们。 我们应该设置高度,以便我们可以看到我们的工作。 它们应该都是相同的高度,我们实际上可以重新使用我们的 --n
变量,再次,使事情简单:
div {
--gt: linear-gradient(black, black);
--n: 100px;
width: 500px;
height: 500px;
background:
var(--gt) top right,
var(--gt) top var(--n) right,
var(--gt) top calc(var(--n) * 2) right,
var(--gt) top calc(var(--n) * 3) right,
var(--gt) top calc(var(--n) * 4) right,
palegreen;
background-repeat: no-repeat;
background-size: 60% var(--n), 90% var(--n), 70% var(--n), 40% var(--n), 10% var(--n); // HIGHLIGHT 15
}
啊,好多了!
在条纹之间添加间隙
如果您的设计不需要条纹之间的间隙,那么这是一个完全可选的步骤,但我的需要并且并不过分复杂。 我们改变每个条纹的高度 background-size
一点点,降低价值,使他们无法填满整个垂直空间。
我们可以继续使用我们的 --n
变量,但减去少量,比如说 5px
使用 calc()
得到我们想要的。
background-size: 60% calc(var(--n) - 5px), 90% calc(var(--n) - 5px), 70% calc(var(--n) - 5px), 40% calc(var(--n) - 5px), 10% calc(var(--n) - 5px);
我们可以用另一个变量消除很多重复:
div {
--h: calc(var(--n) - 5px);
/* etc. */
background-size: 60% var(--h), 90% var(--h), 70% var(--h), 40% var(--h), 10% var(--h);
}
掩蔽和混合
现在让我们交换 palegreen
到目前为止,我们一直为视觉目的使用的背景颜色为白色。
div {
/* etc. */
background:
var(--gt) top right,
var(--gt) top var(--n) right,
var(--gt) top calc(var(--n) * 2) right,
var(--gt) top calc(var(--n) * 3) right,
var(--gt) top calc(var(--n) * 4) right,
#fff;
/* etc. */
}
像这样的黑白图案非常适合遮蔽和混合。 为此,我们首先要包装我们的
在一个新的父容器中并引入第二个
在它下面:
我们将在这里做一些 CSS 重构。 现在我们有了一个新的父容器,我们可以传递固定的 width
和 height
我们在我们的网站上使用的属性
在那边:
section {
width: 500px;
height: 500px;
}
我还将使用 CSS Grid 来定位这两个
元素相互叠加。 这与 Temani Afif 用来创建他的 超级酷的图片库. 这个想法是我们使用
grid-area
属性并将所有内容对齐到中心:
section {
display: grid;
align-items: center;
justify-items: center;
width: 500px;
height: 500px;
}
section > div {
width: inherit;
height: inherit;
grid-area: 1 / 1;
}
现在,检查一下。 我之前使用从黑色到黑色的纯色渐变的原因是为我们设置遮罩和混合两者
层。 从我们称之为
mask
属性,但图层之间的对比度控制着哪些颜色可见。 被白色覆盖的区域将保持白色,被黑色覆盖的区域会漏光。 MDN 关于混合模式的文档 很好地解释了这是如何工作的。
为了让它工作,我将应用我们想要在第一个看到的真实渐变
在应用我们最初的样式规则时
在新的上,使用
:nth-child()
伪选择器:
div:nth-child(1) {
background: linear-gradient(to right, red, orange);
}
div:nth-child(2) {
--gt: linear-gradient(black, black);
--n: 100px;
--h: calc(var(--n) - 5px);
background:
var(--gt) top right,
var(--gt) top var(--n) right,
var(--gt) top calc(var(--n) * 2) right,
var(--gt) top calc(var(--n) * 3) right,
var(--gt) top calc(var(--n) * 4) right,
white;
background-repeat: no-repeat;
background-size: 60% var(--h), 90% var(--h), 70% var(--h), 40% var(--h), 10% var(--h);
}
如果我们停在这里,实际上我们将看不到与之前的任何视觉差异。 那是因为我们还没有完成实际的混合。 所以,让我们现在使用 screen
混合模式:
div:nth-child(2) {
/* etc. */
mix-blend-mode: screen;
}
我在本文开头展示的演示中使用了米色背景色。 这种稍微深一点的灰白色可以让一点颜色渗透到背景的其余部分:
悬停效果
这个难题的最后一块是将条纹加宽到全宽的悬停效果。 首先,让我们为它写出我们的选择器。 我们希望这发生在父容器(
在我们的例子中)悬停。 当它悬停时,我们将更改第二个中包含的条纹的背景大小
:
/* When is hovered, change the second div's styles */
section:hover > div:nth-child(2){
/* styles go here */
}
我们想要改变 background-size
将条纹调整到容器的整个宽度,同时保持相同的高度:
section:hover > div:nth-child(2){
background-size: 100% var(--h);
}
这会将背景“捕捉”到全角。 如果我们加一点 transition
为此,然后我们看到条纹在悬停时展开:
section:hover > div:nth-child(2){
background-size: 100% var(--h);
transition: background-size 1s;
}
这是最后的演示:
我只是在其中添加了文本以显示在不同的上下文中使用它可能是什么样子。 如果你这样做,那么值得确保文本颜色和渐变中使用的颜色之间有足够的对比度以符合 WCAG指南. 虽然我们只是简单地谈到了可访问性,但值得 考虑用户对减少运动的偏好 当涉及到悬停效果时。
这是一个包装!
很整洁,对吧? 我当然这么认为。 我也喜欢这个,因为它非常易于维护和定制。 例如,我们可以通过更改一些值来改变条纹的高度、颜色和方向。 你甚至可以改变其中的一些东西——比如颜色和宽度——以使其更具可配置性。
如果您以不同的方式处理这个问题,我真的很感兴趣。 如果是这样,请在评论中分享! 看看我们可以收集多少变体会很好。