clipPath在:focus /:hover上转换相同图标的多个实例

时间:2019-04-01 14:18:29

标签: css svg mask css-transforms clip-path

我有一个SVG图标,带有一些蒙版形状,包括:

  • book-1:被clipPath mask-1
  • 掩盖
  • book-2:被clipPath mask-2
  • 掩盖
  • book-3:未屏蔽,无需变换

:focus / :hover上,我希望mask-1(但不是book-1)和book-2(但不是mask-2)进行变换。直截了当…

<a href="whatevs" class="icon">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44">
        <defs>
            <style>
                #book-1 {clip-path:url(#mask-1);} 
                #book-2 {clip-path:url(#mask-2);}
            </style>

            <clipPath id="mask-1">
                <path class="nudge" fill="none" … />
            </clipPath>
            <clipPath id="mask-2">
                <path fill="none" … />
            </clipPath>
        </defs>

        <g id="book-1">
            <path fill="#fff" … />
        </g>
        <g id="book-2">
            <path fill="#fff" class="nudge" … />
        </g>
        <path fill="#fff" … /> <!-- book-3 -->
    </svg>
</a>

/* CSS */

.icon .nudge {
    transition: transform 0.2s ease-in;
}

.icon:focus .nudge, 
.icon:hover .nudge {
    transform: translate(-2px, 2px);
}

但是,当页面中有多个相同图标的实例时,乐趣就开始了。


我在CodePen上有3支笔,每支笔都有2个链接图标的实例,其中:

  1. MRYwBq 失败,并且:
    • 详细代码,说明每次显示完整的SVG
    • book-1book-2
    • 类名称
    • 每个掩码实例的唯一ID名称:mask-1mask-2
  2. qwEZrG 用于:
    • 详细代码,说明每次显示完整的SVG
    • 书籍和蒙版的每个实例的唯一ID名称:book-1mask-1book-2mask-2
  3. gybrvL 失败,并且:
    • 通过页面中的<symbol>迭代的图标的<use>实例

想法

  1. 这太奇怪了。我想了解为什么它会失败。
  2. 这很好,但是我希望在ID未区分大小写地发送到页面后,不必使用JavaScript进行迭代。
  3. 这就是我想要的工作,但是我不知道是否可能。

1 个答案:

答案 0 :(得分:1)

由于clip-path要求一个svg def子代的ID,因此如果在页面上放置多个图标,则仅考虑这些<clipPath>定义之一。这就是为什么转换<clipPath>元素是不可行的原因,因为引用该元素的所有项目都会受到影响。因此,我们需要一种不基于:hover的{​​{1}}移动或修改这些元素的解决方案。

幸运的是,可以使用以下技巧仅移动分配给元素的剪切路径,而无需移动元素本身:

  1. 将剪辑路径分配给父对象
  2. 沿剪切路径应移动的方向移动父对象
  3. 以相反的方向移动所有孩子

可以在下面的代码段中找到基于您提供的代码的此技巧的示例:

:focus
a .nudge, a .unnudge {
  transition: transform 0.2s ease-in;
}

a:focus, 
a:hover {
    background-color: black;
}
    
a:focus .nudge, 
a:hover .nudge {
    transform: translate(-2px, 2px);
}

a:focus .unnudge, 
a:hover .unnudge {
    transform: translate(2px, -2px);
}


* {
  box-sizing: border-box;
}

a {
  display: block;
  background-color: red;
  padding: 0.5rem;
  border-radius: 50%;
  transition: background-color 0.2s ease-in;
  width: 60px;
  height: 60px;
}

body {
  font-family: sans-serif;
  line-height: 1.5;
  max-width: 36em;
  color: #333;
}

code {
  background: #e5e5e5;
  font-size: 1.125em;
  border-radius: 2px;
}

请注意,该解决方案不是完美的,并且在两个浏览器(例如Firefox)上,具有两个相反的动作的总和应为零,这可能会导致<p>Instance 1: <a href="#"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44" width="44" height="44"> <defs> <style> .book-1{clip-path:url(#mask-1-1);} .book-2{clip-path:url(#mask-2-1);} </style> <clipPath id="mask-1-1"> <path fill="none" d="M13.823,33.1V18.293a4.738,4.738,0,0,1,1.4-3.371S24.6,5.531,25.085,5.048L20.019-.019H8.143V33.1Z"/> </clipPath> <clipPath id="mask-2-1"> <path fill="none" d="M31.814,10.117,21.12,20.822a4.733,4.733,0,0,0-1.4,3.371V39H12V7H28.7Z"/> </clipPath> </defs> <g class="nudge book-1" > <path fill="#fff" class="unnudge" d="M22.736,5.72a1.193,1.193,0,0,0-1.686,0l-7.516,7.516a1.191,1.191,0,0,1-1.685-1.685l7.516-7.516a1.192,1.192,0,0,0-1.686-1.686L10.163,9.865h0a3.565,3.565,0,0,0-1.047,2.529h0V26.625h0a3.576,3.576,0,0,0,6.1,2.528h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V6.563A1.188,1.188,0,0,0,22.736,5.72Z"/> </g> <g class="book-2"> <path fill="#fff" class="nudge" d="M21.723,22.193a4.733,4.733,0,0,1,1.4-3.371l5.865-5.871v-.488a1.192,1.192,0,0,0-2.035-.843l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.191,1.191,0,1,0-1.685-1.685l-7.516,7.516a3.561,3.561,0,0,0-1.048,2.528h0V32.524h0a3.577,3.577,0,0,0,6.105,2.529h0l.6-.6Z"/> </g> <path fill="#fff" d="M34.535,17.52a1.19,1.19,0,0,0-1.685,0l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.192,1.192,0,1,0-1.686-1.685l-7.516,7.516h0a3.564,3.564,0,0,0-1.047,2.528h0V38.424h0a3.576,3.576,0,0,0,6.1,2.529h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V18.363A1.188,1.188,0,0,0,34.535,17.52Z"/> </svg> </a> </p> <p>Instance 2, exact copy of instance 1: <a href="#"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44" width="44" height="44"> <defs> <style> .book-1{clip-path:url(#mask-1-1);} .book-2{clip-path:url(#mask-2-1);} </style> <clipPath id="mask-1-1"> <path fill="none" d="M13.823,33.1V18.293a4.738,4.738,0,0,1,1.4-3.371S24.6,5.531,25.085,5.048L20.019-.019H8.143V33.1Z"/> </clipPath> <clipPath id="mask-2-1"> <path fill="none" d="M31.814,10.117,21.12,20.822a4.733,4.733,0,0,0-1.4,3.371V39H12V7H28.7Z"/> </clipPath> </defs> <g class="nudge book-1" > <path fill="#fff" class="unnudge" d="M22.736,5.72a1.193,1.193,0,0,0-1.686,0l-7.516,7.516a1.191,1.191,0,0,1-1.685-1.685l7.516-7.516a1.192,1.192,0,0,0-1.686-1.686L10.163,9.865h0a3.565,3.565,0,0,0-1.047,2.529h0V26.625h0a3.576,3.576,0,0,0,6.1,2.528h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V6.563A1.188,1.188,0,0,0,22.736,5.72Z"/> </g> <g class="book-2"> <path fill="#fff" class="nudge" d="M21.723,22.193a4.733,4.733,0,0,1,1.4-3.371l5.865-5.871v-.488a1.192,1.192,0,0,0-2.035-.843l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.191,1.191,0,1,0-1.685-1.685l-7.516,7.516a3.561,3.561,0,0,0-1.048,2.528h0V32.524h0a3.577,3.577,0,0,0,6.105,2.529h0l.6-.6Z"/> </g> <path fill="#fff" d="M34.535,17.52a1.19,1.19,0,0,0-1.685,0l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.192,1.192,0,1,0-1.686-1.685l-7.516,7.516h0a3.564,3.564,0,0,0-1.047,2.528h0V38.424h0a3.576,3.576,0,0,0,6.1,2.529h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V18.363A1.188,1.188,0,0,0,34.535,17.52Z"/> </svg> </a> </p>的混乱。