精美的图像装饰:面具和高级悬停效果 PlatoBlockchain 数据智能。垂直搜索。人工智能。

花式图像装饰:面具和高级悬停效果

欢迎来到这个由三部分组成的系列的第 2 部分! 我们仍在装饰图像,没有任何额外的元素和伪元素。 我希望你已经花时间消化 部分1 因为我们将继续使用大量渐变来创造令人敬畏的视觉效果。 我们还将介绍 CSS mask 属性以获得更复杂的装饰和悬停效果。

花式形象装饰品系列

  • 单元素魔法
  • 蒙版和高级悬停效果 (你在这里!)
  • 轮廓和复杂动画 (即将于 28 月 XNUMX 日 )

让我们转向我们正在合作的第一个示例……

邮票

信不信由你,制作邮票 CSS 效果所需要的只是两个渐变和一个过滤器:

img {
  --r: 10px; /* control the radius of the circles */
  padding: calc(2 * var(--r));
  filter: grayscale(.4);
  background: 
    radial-gradient(var(--r),#0000 98%,#fff) round
      calc(-1.5 * var(--r)) calc(-1.5 * var(--r)) / calc(3 * var(--r)) calc(3 * var(--r)),
    linear-gradient(#fff 0 0) no-repeat
      50% / calc(100% - 3 * var(--r)) calc(100% - 3 * var(--r));
}

正如我们所见 上一篇文章,第一步是在图像周围留出空间 padding 所以我们可以绘制一个背景渐变并在那里看到它。 然后我们使用组合 radial-gradient()linear-gradient() 切割图像周围的那些圆圈。

这是一个分步说明,显示了如何配置渐变:

注意使用 round 第二步的值。 这对于技巧非常重要,因为它可以确保调整渐变的大小以在所有边上完美对齐,无论图像的宽度或高度是多少。

规范:图像在适合背景定位区域的范围内重复出现。 如果它不适合整数次,它会重新缩放以使其适合。

圆形框架

让我们看看另一个使用圆圈的图像装饰......

这个例子还使用了一个 radial-gradient(),但这次我创建了圈子 围绕 图像而不是剪切效果。 请注意,我也在使用 round 再值。 这里最棘手的部分是框架和图像之间的透明间隙,这是我接触 CSS 的地方 mask 属性:

img {
  --s: 20px; /* size of the frame */
  --g: 10px; /* the gap */
  --c: #FA6900; 

  padding: calc(var(--g) + var(--s));
  background: 
    radial-gradient(farthest-side, var(--c) 97%, #0000) 
      0 0 / calc(2 * var(--s)) calc(2 * var(--s)) round;
  mask:
    conic-gradient(from 90deg at calc(2 * var(--s)) calc(2 * var(--s)), #0000 25%, #000 0)
      calc(-1 * var(--s)) calc(-1 * var(--s)),
    linear-gradient(#000 0 0) content-box;
}

蒙版使我们能够显示图像的区域——这要归功于 linear-gradient() 在那里——以及 20px 围绕它的每一面——多亏了 conic-gradient()。 该 20px 只不过是变量 --s 它定义了框架的大小。 换句话说,我们需要隐藏差距。

这就是我的意思:

线性渐变是背景的蓝色部分,而圆锥渐变是背景的红色部分。 两个渐变之间的透明部分是我们从元素中剪切出来的,以创建内部透明边框的错觉。

内部透明边框

对于这个,我们不打算创建一个框架,而是尝试一些不同的东西。 我们将创建一个透明的内边框 我们的形象。 在实际场景中可能没有那么有用,但使用 CSS 掩码是一种很好的做法。

与前面的示例类似,我们将依赖两个梯度: linear-gradient() 对于内部,以及 conic-gradient() 对于外部。 我们将在它们之间留出空间以创建透明边框效果。

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the distance from the edge */

  --_g: calc(100% - 2 * (var(--d) + var(--b)));
  mask:
    conic-gradient(from 90deg at var(--d) var(--d), #0000 25%, #000 0)
      0 0 / calc(100% - var(--d)) calc(100% - var(--d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
}
花式图像装饰:面具和高级悬停效果

您可能已经注意到,这个例子的圆锥梯度与前面的例子有不同的语法。 两者都应该创建相同的形状,那么为什么它们不同呢? 这是因为我们可以使用不同的语法达到相同的结果。 起初这可能看起来令人困惑,但这是一个很好的功能。 您没有义务找到 实现特定形状的解决方案。 您只需要从众多可能性中找到一种适合您的解决方案。

以下是使用渐变创建外部正方形的四种方法:

还有更多方法可以实现这一点,但你明白了。

没有 Best™ 方法。 就个人而言,我尝试找到具有最小和最优化代码的那个。 对我来说,任何需要更少梯度、更少计算和更少重复值的解决方案都是最合适的。 有时我会选择更冗长的语法,因为它让我可以更灵活地更改变量和修改内容。 它伴随着经验和实践。 您玩渐变的次数越多,您就越了解使用什么语法以及何时使用。

让我们回到我们的内部透明边框并深入研究悬停效果。 如果您没有注意到,有一个很酷的悬停效果,它使用 font-size 诡计。 这个想法是定义 --d 变量值为 1em. 此变量控制边界到边缘的距离。 我们可以这样变换:

--_d: calc(var(--d) + var(--s) * 1em)

…给我们以下更新的 CSS:

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the distance from the edge */
  --o: 15px; /* the offset on hover */
  --s: 1;    /* the direction of the hover effect (+1 or -1)*/

  --_d: calc(var(--d) + var(--s) * 1em);
  --_g: calc(100% - 2 * (var(--_d) + var(--b)));
  mask:
    conic-gradient(from 90deg at var(--_d) var(--_d), #0000 25%, #000 0)
     0 0 / calc(100% - var(--_d)) calc(100% - var(--_d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
  font-size: 0;
  transition: .35s;
}
img:hover {
  font-size: var(--o);
}

font-size 最初等于 0 ,所以 1em 也等于 0--_d 等于 --d. 但是,在悬停时, font-size 等于一个定义的值 --o 设置边框偏移量的变量。 这反过来又更新了 --_d 变量,将边框移动偏移量。 然后我添加另一个变量, --s, 来控制决定边界是向内还是向外移动的标志。

font-size 如果我们想要对原本无法动画化的属性进行动画处理,这个技巧真的很有用。 自定义属性定义为 @property 可以解决这个但是 支持它 在我写这篇文章的时候仍然缺乏。

框架显示

我们在本系列的第一部分制作了以下展示动画:

我们可以采用相同的想法,但我们将使用这样的渐变来代替纯色边框:

如果您比较两个代码,您会注意到以下变化:

  1. 我使用了与第一个示例相同的渐变配置 mask 财产。 我只是将渐变从 background 财产 mask 属性。
  2. 我加了一个 repeating-linear-gradient() 创建渐变边框。

而已! 我重新使用了我们已经看到的大部分相同的代码 - 进行了超小的调整 - 并获得了另一个带有悬停效果的酷图像装饰。

/* Solid color border */

img {
  --c: #8A9B0F; /* the border color */
  --b: 10px;   /* the border thickness*/
  --g: 5px;  /* the gap on hover */

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, var(--c) 0;
  background: 
    conic-gradient(from 180deg at top var(--b) right var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b)) no-repeat,
    conic-gradient(at bottom var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200% no-repeat;
  transition: .3s, background-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, background-size .3s .3s;
}
/* Gradient color border */

img {
  --b: 10px; /* the border thickness*/
  --g: 5px;  /* the gap on hover */
  background: repeating-linear-gradient(135deg, #F8CA00 0 10px, #E97F02 0 20px, #BD1550 0 30px);

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, #000 0;
  mask: 
    conic-gradient(from 180deg at top var(--b) right var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b)) no-repeat,
    conic-gradient(at bottom var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200% no-repeat,
    linear-gradient(#000 0 0) content-box;
  transition: .3s, mask-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, mask-size .3s .3s;
}

让我们尝试另一个帧动画。 这个有点棘手,因为它有一个 三步动画:

动画的第一步是让底边变大。 为此,我们调整 background-sizelinear-gradient():

您可能想知道为什么我还要添加顶部边缘。 第三步我们需要它。 我总是尝试优化我编写的代码,所以我使用一个渐变来覆盖顶部和底部,但顶部的部分被隐藏并稍后显示 mask.

第二步,我们添加第二个渐变来显示左右边缘。 但这一次,我们使用 background-position:

我们可以在这里停下来,因为我们已经有了两个渐变的不错效果,但是我们在这里挑战极限,所以让我们添加一点遮罩来实现第三步。

诀窍是隐藏顶部边缘,直到我们显示底部和侧面,然后我们更新 mask-size (或 mask-position) 以显示顶部。 正如我之前所说,我们可以找到很多渐变配置来达到相同的效果。

这是我将使用的渐变的图示:

我正在使用两个锥形渐变,其宽度等于 200%. 两种渐变都覆盖了该区域,只留下顶部未覆盖(该部分稍后将不可见)。 悬停时,我滑动两个渐变以覆盖该部分。

以下是其中一种渐变的更好说明,可让您更好地了解正在发生的事情:

现在我们把它放在里面 mask 财产,我们完成了! 这是完整的代码:

img {
  --b: 6px;  /* the border thickness*/
  --g: 10px; /* the gap */
  --c: #0E8D94;

  padding: calc(var(--b) + var(--g));
  --_l: var(--c) var(--b), #0000 0 calc(100% - var(--b)), var(--c) 0;
  background:
    linear-gradient(var(--_l)) 50%/calc(100% - var(--_i,80%)) 100% no-repeat,
    linear-gradient(90deg, var(--_l)) 50% var(--_i,-100%)/100% 200% no-repeat;  
  mask:
    conic-gradient(at 50% var(--b),#0000 25%, #000 0) calc(50% + var(--_i, 50%)) / 200%,
    conic-gradient(at 50% var(--b),#000 75%, #0000 0) calc(50% - var(--_i, 50%)) / 200%;
  transition: 
    .3s calc(.6s - var(--_t,.6s)) mask-position, 
    .3s .3s background-position,
    .3s var(--_t,.6s) background-size,
    .4s transform;
  cursor: pointer;
}
img:hover {
  --_i: 0%;
  --_t: 0s;
  transform: scale(1.2);
}

我还引入了一些变量来优化代码,但你现在应该已经习惯了。

四步动画怎么样? 是的,有可能!

对此没有任何解释,因为这是你的功课! 使用您在本文中学到的所有内容来剖析代码并尝试阐明它在做什么。 逻辑与前面的所有示例类似。 关键是隔离每个渐变以了解动画的每一步。 我保持代码未优化,以使事情更容易阅读。 我有 优化版本 如果您有兴趣,但您也可以尝试自己优化代码并将其与我的版本进行比较以进行额外练习。

结束了

这就是这个关于创意图像装饰的三部分系列的第 2 部分,仅使用 元素。 我们现在已经很好地处理了如何组合渐变和蒙版来创建令人敬畏的视觉效果,甚至动画 - 而无需使用额外的元素或伪元素。 是的,单 标签就够了!

我们在这个系列中还有一篇文章要写。 在那之前,这是一个带有很酷的悬停效果的奖励演示,我在其中使用 mask 组装损坏的图像。

花式形象装饰品系列

  • 单元素魔法
  • 蒙版和高级悬停效果 (你在这里!)
  • 轮廓和复杂动画 (即将于 28 月 XNUMX 日 )

时间戳记:

更多来自 CSS技巧