#yyds干货盘点#CSS-ing Candy Ghost 按钮

最近,在寻找关于编写什么代码的一些想法时,因为我的艺术感为零,所以我唯一能做的就是找到其他人想出的漂亮东西,并用干净紧凑的代码重新制作它们……我遇到了​​这些糖果鬼按钮​​!

它们似乎是我可以快速编码的一个很酷的小东西的完美选择。不到十五分钟后,这是我的 Chromium 结果:

#yyds干货盘点#CSS-ing Candy Ghost 按钮纯 CSS 糖果幽灵按钮

我认为这项技术值得分享,因此在本文中,我们将介绍我最初是如何做到的以及我们还有哪些其他选择。

起点

一个按钮是用…创建的,你准备好了吗?一个​button​​元素!这个​​button​​​元素有一个​​data-ico​​​属性,我们可以在其中放置一个表情符号。它还具有​​--slist​​​在​​style​​属性中设置的停止列表自定义属性 。

<button data-ico="" style="--slist: #ffda5f, #f9376b">boo!</button>

写完这篇文章后,我了解到 Safari 有很多剪切到 的问题​​text​​​,即它对​​button​​​元素不起作用,或者对​​具有display: flex​​​(也许​​grid​​​也是?)​​的元素​​​不起作用,更不用说​​元素子元素的文本了​​​。遗憾的是,这意味着这里介绍的所有技术在 Safari 中都失败了。唯一的解决方法是将​​button​​​此处的所有样式应用到​​span​​​嵌套在 中的元素上​​button​​​,覆盖其父元素的​​border-box​​​. 而且,如果这可以帮助其他像我一样使用 Linux 而无法物理访问 Apple 设备的人(除非你把 iPhone 5 算在四楼的人——你不想为这样的东西烦恼的人超过反正一个月两次——最近买的),我也学会了使用在未来​​顿悟​​​。感谢​​布赖恩​​的建议!

对于 CSS 部分,我们将图标添加到​​::after​​​伪元素中,并在 上使用​​grid​​​布局​​button​​​以使文本和图标对齐。在 上​​button​​​,我们还设置了 a ​​border​​​、 a ​​padding​​​、 a ​​border-radius​​​,使用停止列表​​--slist​​​, 为对角线渐变并美化了​​font​​。

button {
display: grid;
grid-auto-flow: column;
grid-gap: .5em;
border: solid .25em transparent;
padding: 1em 1.5em;
border-radius: 9em;
background:
linear-gradient(to right bottom, var(--slist))
border-box;
font: 700 1.5em/ 1.25 ubuntu, sans-serif;
text-transform: uppercase;

&::after { content: attr(data-ico) }
}

关于上面的代码,有一点需要澄清。在突出显示的行上,我们将 the​​background-origin​​​和 the都设置​​background-clip​​​为​​border-box​​​。​​background-origin​​​两者都将​​0 0​​​点放在​​background-position​​​它设置的框的左上角,并为我们提供了与其尺寸​​background-size​​相对的框。

也就是说,如果​​background-origin​​​设置为​​padding-box​​​,则​​0 0​​​for的点​​background-position​​​位于 的左上角​​padding-box​​​。如果​​background-origin​​​设置为​​border-box​​​,则 的​​0 0​​​点​​background-position​​​位于 的左上角​​border-box​​​。如果​​background-origin​​​被设置为​​padding-box​​​,一个​​background-size​​​的​​50% 25%​​​装置​​50%​​​的的​​padding-box​​​宽度和​​25%​​​所述的​​padding-box​​​高度。如果​​background-origin​​​被设置为​​border-box​​​,同样​​background-size​​​的​​50% 25%​​​手段​​50%​​​的的​​border-box​​​宽度和​​25%​​​所述的​​border-box​​高度。

为默认值​​background-origin​​​是​​padding-box​​​,这意味着默认大小​​100% 100%​​​渐变将覆盖​​padding-box​​​再重演下面的​​border​​​(在这里我们看不到它,如果​​border​​​是完全不透明)。然而,在我们的例子中,​​border​​​是完全的​​transparent​​​,我们希望我们的梯度延伸到整个​​border-box​​​. 这意味着我们需要将​​background-origin​​​值更改为​​border-box​​。

#yyds干货盘点#CSS-ing Candy Ghost 按钮应用基本样式后的结果(​​​现场演示​​)。

简单但可悲的是非标准 Chromium 解决方案

这涉及使用​​mask​​​三层并将它们合成。如果您需要复习​​mask​​​合成,可以查看​​此速成课程​​。

请注意,在 CSS​​mask​​图层的情况下,只有 alpha 通道很重要,因为遮罩元素的每个像素都获得相应​​mask​​​像素的 alpha ,而 RGB 通道不会以任何方式影响结果,因此它们可能是任何有效的价值。下面,你可以看到的效果​​purple​​​,以​​transparent​​​渐变叠加与使用完全相同的梯度作为的效果​​mask​​。

#yyds干货盘点#CSS-ing Candy Ghost 按钮渐变叠加与相同的渐变蒙版(​​​现场演示​​)。

我们将从底部的两层开始。第一个是完全不透明的层,完全覆盖整个​​border-box​​​,这意味着它的 alpha​​1​​​绝对无处不在。另一个也是完全不透明的,但限制(通过使用​​mask-clip​​​)到​​padding-box​​​,这意味着,虽然该层在整个 中的 alpha 为 1 ​​padding-box​​​,但它完全​​transparent​​​在该​​border​​​区域中,在​​0​​那里有一个 alpha 。

如果你很难想象这一点,一个很好的技巧是将元素的布局框视为嵌套矩形,如下图所示。

#yyds干货盘点#CSS-ing Candy Ghost 按钮布局框(​​​现场演示​​)。

在我们的例子中,底层​​1​​​在整个橙色框( )上是完全不透明的(alpha 值为​​border-box​​​)。我们放置在第一层之上的第二层是完全不透明的(alpha 值为​​1​​​),整个红色框(the ​​padding-box​​​)和完全​​transparent​​​(alpha 为​​0​​​)在​​padding​​​限制和​​border​​限制之间的区域中。

关于这些框的限制,一件非常酷的事情是圆角由 决定​​border-radius​​​(并且,在 的情况下​​padding-box​​​,也由 决定​​border-width​​​)。下面的交互式演示对此进行了说明,我们可以在其中看到 的圆角是如何​​border-box​​​由​​border-radius​​​值给出的,而 的圆角​​padding-box​​​计算为​​border-radius​​​减去 the ​​border-width​​​(在​​0​​差值为负值的情况下限制为)。

现在让我们回到我们的​​mask​​​图层,一个在整个 中完全不透明​​border-box​​​,而它上面的一个在整个​​padding-box​​​区域完全不透明并且在该​​border​​​区域(在​​padding​​​限制和​​border​​​限制之间)完全透明。这两个层使用​​exclude​​​操作(​​xor​​​在​​非标准 WebKit 版本中​​调用)合成。

#yyds干货盘点#CSS-ing Candy Ghost 按钮两个基础层(​​​现场演示​​)。

在两层的 alpha 为​​0​​​或的情况下,此操作的名称非常具有启发性​​1​​​,就像在我们的例子中一样——第一层​​1​​​的 alpha 无处不在,而第二层的 alpha(我们放在第一)的顶部是​​1​​​内部的​​padding-box​​​并​​0​​​在​​border​​​所述区域之间​​padding​​​限制和​​border​​限制。

在这种情况下,应用​​布尔逻辑​​​的​​规则​​​非常直观——对两个相同的值​​0​​​进行异或运算得到,而对两个不同的值进行异或运算得到​​1​​。

在整个 中​​padding-box​​​,第一层和第二层的 alpha 均为​​1​​​,因此使用此操作将它们合成为我们​​0​​​在该区域中生成的层的 alpha为 。但是,在该​​border​​​区域(在​​padding​​​限制之外,但在​​border​​​限制内)中,第一层的 alpha 为​​1​​​,而第二层的 alpha 为​​0​​​,因此我们​​1​​在该区域中得到的结果层的 alpha为 。

下面的交互式演示对此进行了说明,您可以在其中切换查看​​mask​​以 3D 方式分离的两个图层,以及使用此操作查看堆叠和合成的图层。

把东西变成代码,我们有:

button {
/* same base styles */
--full: linear-gradient(red 0 0);
-webkit-mask: var(--full) padding-box, var(--full);
-webkit-mask-composite: xor;
mask: var(--full) padding-box exclude, var(--full);
}

在我们进一步讨论之前,让我们讨论一些关于上述 CSS 的微调细节。

首先,由于完全不透明的层可以是任何东西(alpha 通道是固定的,总是​​1​​​和 RGB 通道不重要),我通常制作它们​​red​​​——只有三个字符!同样,使用圆锥渐变而不是线性渐变也可以为我们节省一个字符,但我很少这样做,因为我们仍然有​​支持 masking​​​但​​不​​​​支持​​​​圆锥渐变的​​移动浏览器。使用线性可确保我们获得全面支持。好吧,除了 IE 和 Chromium Edge 之前的版本,但话又说回来,无论如何,没有多少很酷的闪亮的东西在这些东西中起作用。

其次,我们对两个层都使用渐变。我们没有​​background-color​​​为底部使用一个普通的,因为我们不能​​background-clip​​​为它​​background-color​​​本身设置一个单独的。如果我们要将​​background-image​​​图层裁剪到​​padding-box​​​,那么这个​​background-clip​​​值也将应用于​​background-color​​​下面——它也会被裁剪到​​padding-box​​​,我们无法让它覆盖整个​​border-box​​。

第三,我们没有​​mask-clip​​​为底层明确设置一个值,因为这个属性的默认值正是我们在这种情况下想要的值,​​border-box​​。

第四,我们可以​​mask-composite​​​在​​mask​​速记中包含标准(Firefox 支持),但不能包含非标准(WebKit 浏览器支持)。

最后,我们始终将标准版本设置为最后,以便它覆盖可能也受支持的任何非标准版本。

到目前为止,我们的代码的结果(此时仍然是跨浏览器的)如下所示。我们还在​​background-image​​​根上添加了一个,这样很明显我们在整个​​padding-box​​区域都有真正的透明度。

#yyds干货盘点#CSS-ing Candy Ghost 按钮屏蔽整个​​​padding-box​​​(​​现场演示​​)后的结果。

这不是我们想要的。虽然我们有一个很好的渐变​​border​​​(顺便说一下,这是我获得渐变的首选方法,​​border​​​因为我们在整个过程中都有真正的透明度​​padding-box​​​,而不仅仅是​​封面​​),但我们现在缺少文本。

因此,下一步是使用​​mask​​​前一层之上的另一层重新添加文本,这一次仅限于​​text​​​(同时也使实际文本完全,​​transparent​​​以便我们可以​​background​​​通过它看到渐变)和 XOR 这第三​​mask​​层与前两个异或的结果(结果可以在上面的屏幕截图中看到)。

下面的交互式演示允许查看​​mask​​在 3D 中分离以及堆叠和合成的三个图层。

请注意,​​text​​​for的值​​mask-clip​​​是非标准的,因此,遗憾的是,这仅适用于 Chrome。在 Firefox 中,我们只是不再对按钮进行任何屏蔽,并且制作了 text ​​transparent​​,我们甚至不会优雅地降级。

button {
/* same base styles */
-webkit-text-fill-color: transparent;
--full: linear-gradient(red 0 0);
-webkit-mask: var(--full) text, var(--full) padding-box, var(--full);
-webkit-mask-composite: xor;
/* sadly, still same result as before :( */
mask: var(--full) padding-box exclude, var(--full);
}

如果我们不想以​​button​​​这种方式使我们无法使用,我们应该将应用​​mask​​​和 制作文本的代码​​transparent​​​放在一个​​@supports​​块中。

button {
/* same base styles */
@supports (-webkit-mask-clip: text) {
-webkit-text-fill-color: transparent;
--full: linear-gradient(red 0 0);
-webkit-mask: var(--full) text, var(--full) padding-box, var(--full);
-webkit-mask-composite: xor;
}
}

#yyds干货盘点#CSS-ing Candy Ghost 按钮使用仅屏蔽方法的最终结果(​​​现场演示​​)。

我真的很喜欢这种方法,它是我们目前拥有的最简单的方法,我真的希望它​​text​​​是一个标准值,​​mask-clip​​并且所有浏览器都正确支持它。

然而,我们还有其他一些实现糖果幽灵按钮效果的方法,尽管它们比我们刚刚讨论的非标准 Chromium-only 更复杂或更有限,但它们也得到了更好的支持。让我们来看看这些。

额外的伪元素解决方案

这涉及设置与以前相同的初始样式,但是,我们不使用 ,而是将​​mask​​​剪切​​background​​​到该​​text​​区域。

button {
/* same base styles */
background:
linear-gradient(to right bottom, var(--slist))
border-box;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent
}

就像以前一样,我们还需要制作实际的 text ​​transparent​​​,这样我们就可以看到它​​background​​后面的柔和渐变,现在被剪裁到了它的形状。

#yyds干货盘点#CSS-ing Candy Ghost 按钮淘汰赛按钮文本(​​​现场演示​​)。

好的,我们有渐变文本,但现在我们缺少渐变​​border​​​。因此,我们将使用绝对定位的​​::before​​​伪元素添加它,该伪元素覆盖 的整个​​border-box​​​区域​​button​​​并继承​​border​​​,​​border-radius​​​并​​background​​​从其父元素(除了​​background-clip​​​,它被重置为​​border-box​​)。

$b: .25em;
button {
/* same as before */
position: relative;
border: solid $b transparent;

&::before {
position: absolute;
z-index: -1;
inset: -$b;
border: inherit;
border-radius: inherit;
background: inherit;
background-clip: border-box;
content: '';
}
}

​inset: -$b​​​是以下​​的简写​​:

top: -$b;
right: -$b;
bottom: -$b;
left: -$b

请注意,我们在此处使用带减号的​​border-width​​​值 ( ​​$b​​​)。该​​0​​​值将使​​margin-box​​​假的(等同于​​border-box​​​在这种情况下,因为我们没有​​margin​​​对​​::before​​​)仅覆盖​​padding-box​​​其​​button​​​母公司,我们希望它覆盖整个​​border-box​​​。此外,正方向是向内,但我们需要向外走 a​​border-width​​​才能从​​padding​​​极限到​​border​​极限,因此是负号 – 我们向负方向前进。

我们还在​​z-index​​​这个绝对定位的元素上设置了一个否定,因为我们不希望它位于​​button​​​文本的顶部并阻止我们选择它。在这一点上,文本选择是我们区分文本和 的唯一方法​​background​​,但我们很快就会解决这个问题!

#yyds干货盘点#CSS-ing Candy Ghost 按钮添加渐变伪后的结果(​​​现场演示​​)。

请注意,由于伪元素内容不可选择,因此选择仅包括按钮的实际文本内容,而不包括​​::after​​伪元素中的表情符号。

下一步是添加一个两层,它们之间​​mask​​​有一个​​exclude​​​合成操作,以便只留下​​border​​这个伪元素的区域可见。

button {
/* same as before */

&::before {
/* same as before */
--full: linear-gradient(red 0 0);
-webkit-mask: var(--full) padding-box, var(--full);
-webkit-mask-composite: xor;
mask: var(--full) padding-box exclude, var(--full);
}
}

这几乎是我们​​button​​在前一种方法的一个中间阶段中为实际所做的。

#yyds干货盘点#CSS-ing Candy Ghost 按钮使用额外的伪方法(​​​现场演示​​)的最终结果。

我发现在大多数情况下,这是最好的方法,当我们想要跨浏览器的东西并且不包括 IE 或 Chromium Edge 之前,它们都不支持屏蔽。

该​​border-image​​解决方案

在这一点上,你们中的一些人可能会在屏幕上尖叫,​​::before​​​当我们可以使用渐变​​border-image​​​来创建这种幽灵按钮时,没有必要使用伪元素——这是一种​​已经​​使用了四分之三以上的策略十年!

但是,​​border-image​​​用于药丸形状的按钮有一个很大的问题:此属性与 不兼容​​border-radius​​​,如下面的交互式演示中所示。一旦我们​​border-image​​​在一个元素上设置了 a ​​border-radius​​​,我们就会失去 的角舍入​​border​​​,即使通过,有趣的是,​​background​​仍然会尊重这个舍入。

尽管如此,在不需要圆角或所需圆角最多为​​border-width​​.

在没有圆角的情况下,除了删除现在毫无意义的​​border-radius​​,我们不需要太多改变初始样式:

button {
/* same base styles */
--img: linear-gradient(to right bottom, var(--slist));
border: solid .25em;
border-image: var(--img) 1;
background: var(--img) border-box;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}

结果可以在下面看到,跨浏览器(即使在 Chromium Edge 之前也应该支持)。

#yyds干货盘点#CSS-ing Candy Ghost 按钮使用​​​border-image​​​方法(​​现场演示​​)的无圆角结果。

所需圆角小于 的技巧​​border-width​​​取决于​​border-radius​​​工作方式。当我们设置这个属性时,我们设置的半径代表​​border-box​​​. 如果该差为正,则​​padding-box​​​(即 的内部圆角​​border​​​)的角的圆角为​​border-radius​​​负数,​​border-width​​​否则为​​0​​​(无圆角)。这意味着​​border​​​如果​​border-radius​​​小于或等于 ,我们没有内部舍入​​border-width​​。

在这种情况下,我们可以将该​​inset()​​​函数用作​​clip-path​​值,因为它还提供了圆角剪切矩形角的可能性。如果您需要复习此功能的基础知识,可以查看下图:

#yyds干货盘点#CSS-ing Candy Ghost 按钮如何​​​inset()​​函数工作。

​inset()​​​剪掉由元素边缘的距离定义的裁剪矩形之外的所有内容​​border-box​​​,指定方式与我们指定的相同​​margin​​​,​​border​​​或者​​padding​​​(使用一个、两个、三个或四个值)以及此矩形的圆角,指定相同我们会指定方式​​border-radius​​​(任何​​有效的border-radius价值​​也是有效的在这里)。

在我们的例子中,到 边缘的距离​​border-box​​​是全部​​0​​​(我们不想从 的任何边缘切掉任何东西​​button​​​),但是我们有一个舍入,最多必须与 一样大,​​border-width​​​这样就没有任何内部​​border​​舍入都是有道理的。

$b: .25em;
button {
/* same as before */
border: solid $b transparent;
clip-path: inset(0 round $b)
}

请注意,​​clip-path​​​也将删除我们可能在​​button​​​元素上添加的任何外部阴影,无论它们是通过​​box-shadow​​​还是​​filter: drop-shadow()​​.

#yyds干货盘点#CSS-ing Candy Ghost 按钮使用​​​border-image​​​方法(​​现场演示​​)的小角圆角结果。

虽然这种技术不能达到药丸形状的外观,但它确实具有当今强大的支持优势,并且在某些情况下可能是我们所需要的。

到目前为止讨论的三个解决方案可以在下面的演示中看到编译,该演示还附带一个 YouTube 链接,如果您更喜欢通过观看在视频上构建的东西而不是阅读它们来学习,您可以看到我从头开始编写每个解决方案.

所有这些方法都​​padding-box​​​在文本外部创造了真正的透明度,因此它们适用于​​background​​​我们在​​button​​. 但是,我们还有一些其他方法可能值得一提,尽管它们在该部门受到限制。

封面解决方案

就像​​border-image​​​方法一样,这是一种非常有限的策略。除非我们​​background​​​在​​button​​.

它涉及使用不同​​background-clip​​​值对背景进行分层,就像渐变边框的覆盖技术一样。唯一的区别是,在这里我们在模拟元素​​background​​​后面的图层之上再添加一个渐变图层,​​button​​​并将此顶层剪辑为​​text​​。

$c: #393939;
html { background: $c; }
button {
/* same as before */
--grad: linear-gradient(to right bottom, var(--slist));
border: solid .25em transparent;
border-radius: 9em;
background: var(--grad) border-box,
linear-gradient($c 0 0) /* emulate bg behind button */,
var(--grad) border-box;
-webkit-background-clip: text, padding-box, border-box;
-webkit-text-fill-color: transparent;
}

遗憾的是,这种方法在 Firefox 中由于​​一个旧错误​​​而失败——只是没有应用任何内容​​background-clip​​​,同时使文本​​transparent​​产生一个没有可见文本的药丸状按钮。

#yyds干货盘点#CSS-ing Candy Ghost 按钮全​​​background-clip​​​覆盖解决方案(​​现场演示​​)。

我们仍然可以通过​​border​​​在​​::before​​​伪和​​background-clip: text​​​实际上使用渐变的覆盖方法使其跨浏览器​​button​​​,这基本上只是我们讨论的第二个解决方案的更有限版本 – 我们仍然需要使用伪,但是,因为我们使用盖子,而不是​​mask​​​,它只有​​background​​​在​​button​​.

$b: .25em;
$c: #393939;
html { background: $c; }
button {
/* same base styles */
--grad: linear-gradient(to right bottom, var(--slist));
border: solid $b transparent;
background: var(--grad) border-box;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;

&::before {
position: absolute;
z-index: -1;
inset: -$b;
border: inherit;
border-radius: inherit;
background: linear-gradient($c 0 0) padding-box,
var(--grad) border-box;
content: '';
}
}

从好的方面来说,这个更受限制的版本也应该适用于 Chromium Edge 之前的版本。

#yyds干货盘点#CSS-ing Candy Ghost 按钮​​​background​​​按钮后面的实体的伪封面解决方案(​​现场演示​​)。

下面,还有固定​​background​​版本。

$f: url(balls.jpg) 50%/ cover fixed;
html { background: $f; }
button {
/* same as before */

&::before {
/* same as before */
background: $f padding-box,
var(--grad) border-box
}
}

#yyds干货盘点#CSS-ing Candy Ghost 按钮固定​​​background​​​按钮后面的伪封面解决方案(​​现场演示​​)。

总的来说,我不认为这是最好的策略,除非我们都符合​​background​​​限制并且我们需要在不支持遮罩但支持将 剪切​​background​​​到 的浏览器中重现效果​​text​​,例如前 Chromium Edge。

混合溶液

这种方法是另一种有限的一个,因为它不会工作,除非每个那就是每一个可见的像素梯度,其通道具有要么全部被大或比所有比的对应的像素较小的值​​background​​​下面的​​button​​。然而,这并不是最糟糕的限制,因为它可能会导致我们的页面具有更好的对比度。

在这里,我们首先制作我们想要渐变的部分(即文本、图标和​​border​​​)​​white​​​或​​black​​​,这取决于我们分别拥有带有浅渐变的深色主题还是带有深色渐变的浅色主题。的其余部分​​button​​​(文本和图标周围的区域,但在 内部​​border​​​)与之前选择的相反​​color​​​(​​white​​​如果我们将​​color​​​值设置为​​black​​​和​​black​​否则)。

在我们的例子中,我们有一个漂亮的渐变光​​button​​​在一个黑暗的​​background​​​,所以我们先从​​white​​​文本,图标和边界,并​​black​​​为​​background​​​。我们的两个梯度停止点的十六进制通道值是​​ff​​​( ​​R​​​), ​​da​​​( ​​G​​​), ​​5f​​​( ​​B​​​) 和​​f9​​​( ​​R​​​), ​​37​​​( ​​G​​​), ​​6b​​​( ​​B​​​),所以我们​​background​​​对通道值至多与​​min(ff, f9) = f9​​​红色一样大的任何像素都是安全的,​​min(da, 37) = 37​​​因为绿色和​​min(5f, 6b) = 5f​​蓝色。

这意味着​​background-color​​​在我们的后面有一个​​button​​​小于或等于​​f9​​​,​​37​​​和 的通道值,或者单独​​5f​​​作为一个实体​​background​​​,或者在​​background-image​​​我们使用​​multiply​​​混合模式混合的层下面(这总是产生至少与两层中较深的一层)。我们将它设置​​background​​​在一个伪元素上,因为与实际混合​​body​​​或​​html​​在 Chrome 中不起作用。

$b: .25em;
body::before {
position: fixed;
inset: 0;
background: url(fog.jpg) 50%/ cover #f9375f;
background-blend-mode: multiply;
content: '';
}
button {
/* same base styles */
position: relative; /* so it shows on top of body::before */
border: solid $b;
background: #000;
color: #fff;

&::after {
filter: brightness(0) invert(1);
content: attr(data-ico);
}
}

需要注意的是使图标完全​​white​​​指使其先​​black​​​用​​brightness(0)​​​,然后反转这个​​black​​​用​​invert(1)​​。

#yyds干货盘点#CSS-ing Candy Ghost 按钮在​​​black​​​和​​white​​​按钮(​​现场演示​​)。

然后我们添加一个渐变​​::before​​伪元素,就像我们为第一个跨浏览器方法所做的那样。

button {
/* same styles as before */
position: relative;

&::before {
position: absolute;
z-index: 2;
inset: -$b;
border-radius: inherit;
background: linear-gradient(to right bottom, var(--slist);
pointer-events: none;
content: '';
}
}

唯一的区别是,这里不是给它一个负数​​z-index​​​,而是给它一个正数​​z-index​​​。这样它不仅在实际的​​button​​​,而且在​​::after​​​伪上,我们设置​​pointer-events​​​为​​none​​​以允许鼠标与​​button​​下面的实际内容进行交互。

#yyds干货盘点#CSS-ing Candy Ghost 按钮在​​​black​​​和​​white​​​按钮顶部添加渐变伪后的结果(​​现场演示​​)。

现在下一步是保留​​black​​​我们的部分​​button​​​,但用渐变替换​​white​​​部分(即文本、图标和​​border​​​)。我们可以使用​​darken​​​混合模式来做到这一点,其中两层是带有​​::after​​图标的黑白按钮和其上的渐变伪。

对于每个 RGB 通道,此混合模式采用两个图层的值,并使用较暗(较小)的一个作为结果。由于一切都比 暗​​white​​​,因此生成的图层使用该区域中的渐变像素值。由于​​black​​​是暗于一切,所得层是​​black​​​无处不在​​button​​​的​​black​​。

button {
/* same styles as before */

&::before {
/* same styles as before */
mix-blend-mode: darken;
}
}

#yyds干货盘点#CSS-ing Candy Ghost 按钮“几乎在那里”的结果(​​​现场演示​​)。

好的,但如果​​background​​​后面​​button​​​是纯​​black​​​. 否则,在 a​​background​​​的每个像素都比我们的 上的渐变的相应像素更暗的情况下​​button​​​,我们可以应用第二个混合模式,这次是​​lighten​​​在实际上​​button​​​(以前,我们​​darken​​​在​​::before​​伪上)。

对于每个 RGB 通道,此混合模式采用两个图层的值,并使用较亮(较大)的图层作为结果。因为任何事情比更轻​​black​​​,所得层使用​​background​​​后面​​button​​​到处​​button​​​是​​black​​​。并且由于要求是 的每个渐变像素​​button​​​都比其​​background​​后面的相应像素更亮,因此生成的图层使用该区域的渐变像素值。

button {
/* same styles as before */
mix-blend-mode: lighten;
}

#yyds干货盘点#CSS-ing Candy Ghost 按钮深色背景上的浅色幽灵按钮(​​​现场演示​​)。

对于​​button​​​light 上的暗渐变​​background​​​,我们需要切换混合模式。也就是说,使用​​lighten​​​的​​::before​​​假,并​​darken​​​在​​button​​​自身。首先,我们需要确保​​background​​​后面​​button​​足够轻。

假设我们的梯度介于​​#602749​​​和之间​​#b14623​​​。我们梯度站的通道值是​​60​​​( ​​R​​​), ​​27​​​( ​​G​​​), ​​49​​​( ​​B​​​) 和​​b1​​​( ​​R​​​), ​​46​​​( ​​G​​​), ​​23​​​( ​​R​​​),所以​​background​​​后面的​​button​​​通道值需要至少​​max(60, b1) = b1​​​为红色、​​max(27, 46) = 46​​​绿色和​​max(49, 23) = 49​​蓝色。

这意味着​​background-color​​​在我们​​button​​​的通道值上有一个大于或等于​​b1​​​, ​​46​​​and ​​49​​​,无论是作为一个实体​​background​​​,还是在一个​​background-image​​​层下面,使用​​screen​​混合模式(它总是产生至少与两层)。

我们还需要制作​​button​​​边框、文本和图标​​black​​​,同时将其设置​​background​​​为​​white​​:

$b: .25em;
section {
background: url(fog.jpg) 50%/ cover #b14649;
background-blend-mode: screen;
}
button {
/* same as before */
border: solid $b;
background: #fff;
color: #000;
mix-blend-mode: darken;
&::before {
/* same as before */
mix-blend-mode: lighten
}

&::after {
filter: brightness(0);
content: attr(data-ico);
}
}

​::after​​​伪元素中的图标是​​black​​​通过​​filter: brightness(0)​​在其上设置来制作的。

#yyds干货盘点#CSS-ing Candy Ghost 按钮浅色背景上的黑色幽灵按钮(​​​现场演示​​)。

我们还可以选择将所有​​button​​​图层混合为其 的一部分​​background​​​,无论是​​浅色​​​还是​​深色​​​主题,但是,如前所述,Firefox 只会忽略任何​​background-clip​​​声明,其中​​text​​是值列表的一部分,而不是单个值。

嗯,就是这样!我希望你有(或有)一个可怕的万圣节。我发现的所有错误绝对让我感到可怕……或重新发现,以及同时它们尚未修复的现实。

文章版权声明

 1 原创文章作者:0008,如若转载,请注明出处: https://www.52hwl.com/35690.html

 2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈

 3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)

 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023年7月15日 下午12:00
下一篇 2023年7月15日 下午12:01