SVG 选项卡(使用 SVG 形状作为模板)

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费信用额度!

SVG 的一个优秀特性是,您可以定义一个形状(或一组形状)一次,然后在整个页面中多次使用它。您甚至可以对不同版本应用不同的填充和滤镜等。如果可以的话,可以将其视为 SVG 模板。

让我们看看是否可以通过创建一些选项卡来充分利用它。

我从 Oleg Solomka 的 Codrops 文章 中了解到这是可能的。很聪明!

它的工作原理如下

  1. 定义形状(可以是圆形、矩形、多边形或 任何形状,或用 <g> 包裹的一组形状)。
  2. 给该形状一个 ID。
  3. 隐藏该形状。
  4. 在需要的地方使用 <use> 使用该形状。

在 HTML 中看起来像这样

<!-- TEMPLATE -->
<svg width="100px" height="100px" viewBox="0 0 100 100" class="visually-hidden">
  <circle id="template" cx="50" cy="50" r="50">
</svg>
  
<!-- USE TEMPLATE SEVERAL TIMES -->
<svg viewBox="0 0 100 100" class="circle circle-1">
  <use xlink:href="#template">
</svg>
  
<svg viewBox="0 0 100 100" class="circle circle-2">
  <use xlink:href="#template">
</svg>
  
<svg viewBox="0 0 100 100" class="circle circle-3">
  <use xlink:href="#template">
</svg>

然后,您可以分别引用这些模板的不同用法,并对它们执行任何您喜欢的操作。例如,使用 SVG 渐变填充或 SVG 滤镜等。

您可以通过将该模板定位在页面外或使用 display: none; 来隐藏它。我可能会避免尝试直接使用它,以保持良好的关注点分离。

演示

查看 Chris Coyier 在 CodePen 上的笔 基本 SVG 模板 (@chriscoyier)。

创建选项卡

我刚刚从律师那里收到了一些文件,当然,它们都使用了经典的文件文件夹设计进行了选项卡式布局。

以前曾尝试过使用 CSS 来创建这种形状。 圆角选项卡 处理了形状逐渐变细到文件夹其余部分的形状。 倾斜选项卡 处理了倾斜的侧面。但它们都不是完美的,组合它们将很困难或不可能,并且虽然很巧妙,但它们在使用生成内容等方面有点“hacky”。

难道仅仅将该形状绘制为矢量并使用它不是更容易吗?绝对地,这是 SVG 的完美领域。更好的是,我们可以只使用一个模板来定义它一次,然后反复使用它。这使我们能够更改颜色等,而无需请求新的资源,并且无论我们最终使用它的大小如何,它都能看起来很清晰。

您可以轻松地在任何矢量绘图工具中绘制该形状,并获取其 SVG 代码。如果您需要帮助, 这篇文章应该会有帮助

我只是在一些图片网站上搜索了一些图片,只是为了好玩,并且 在 Shutterstock 上找到了一些 符合我的目标。我下载了它们并从中提取了形状。

简而言之,基本上是 这个

<svg>
  <path id="tab-shape" d="M116.486,29.036c-23.582-8-14.821-29-42.018-29h-62.4C5.441,0.036,0,5.376,0,12.003v28.033h122v-11H116.486
			z">
</svg>

HTML

由于我们可能会将选项卡称为导航,并且 导航是列表,因此我们将得到以下内容

<nav role="navigation" class="main-navigation">
  <ul>
    <li class="tab-1 active">
      <a href="#home">
        <span>Home</span>
        <svg viewBox="0 0 122 40">
           <use xlink:href="#tab-shape"></use>
        </svg>
      </a>
    </li>
    <li class="tab-2">
      <a href="#about">
        <span>About</span>
        <svg viewBox="0 0 122 40">
          <use xlink:href="#tab-shape"></use>
        </svg>
      </a>
    </li>

    <!-- etc. as many tabs as you'd like -->

  </ul>
</nav>

我们需要在标记中使用 <svg>,因为这就是它的工作原理。我们将其包装在 <a> 中,因为我们希望选项卡成为可点击/可触摸的链接。我们需要 <span>,因为我们打算将 <svg> 和文本正好彼此叠加,文本在顶部。

CSS

我们可以使用其中一个包装元素作为定位上下文。我们将绝对定位 <span><svg>,并为 <span> 提供更高的 z-index

这里以 SCSS 呈现,因为嵌套使它更容易阅读

.main-navigation {
  overflow: hidden;
  position: relative;
  padding: 0 0 0 1rem; /* push tabs back to right */
  ul {
    list-style: none;
    padding: 0;
  }
  li {
    float: left;
    width: 12rem;
    height: 5rem;
    margin: 0 0 0 -1rem; /* pull to left to overlap tabs */
    position: relative;
    &.active {
      z-index: 6; /* active one on top */
    }
  }
  a {
    position: relative;
    display: inline-block;
    width: 100%;
    height: 100%;
  }
  svg {
    width: 120%; /* tab shape should stick out past clickable box */
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    pointer-events: none; /* SVG eats clicks weird */
  }
  span {
    position: relative;
    padding: 1rem 0 0 3.3rem; /* position the text */
    z-index: 2;
    display: inline-block;
    width: 100%;
    height: 100%;
  }
}

现在要更改每个选项卡的外观,您可以按类名引用它们并更改 fill。我们还需要以相反的 z-index 顺序排列它们,以便第一个选项卡位于顶部而不是最后一个,这很容易通过显式声明它们来完成。

.tab-1 {
    z-index: 4;
    svg {
      fill: red; 
    }
  }
.tab-2 {
    z-index: 3;
    svg {
      fill: orange; 
    }
  }

演示

查看 Chris Coyier 在 CodePen 上的笔 SVG 选项卡 (@chriscoyier)。

其中有一些 JavaScript 用于激活不同的选项卡,其本质只是更改类名。

您可能会注意到选项卡也有一些细微的渐变。这里有趣的联系是,您可以在与原始模板形状相同的 <svg> 中声明该 SVG 渐变,然后只需通过按 ID 引用滤镜即可填充模板形状。

<linearGradient id="tab-1-bg" x1="0%" y1="0%" x2="0%" y2="65%">
  <stop offset="0%" style="stop-color: rgba(136, 195, 229, 1.0);" />
  <stop offset="100%" style="stop-color: rgba(118, 160, 192, 1.0);" />
</linearGradient>
.tab-1 {
  svg {
    fill: url(#tab-1-bg); 
  }
}

因此,基本上您可以将您的滤镜也视为模板,随意重复使用它们。也请尝试一下 演示。其中有一些注释掉的关于阴影的部分,您可能喜欢。真正酷的事情是使它们灵活,以便选项卡大小根据可用空间(以及文本)变化得更大或更小,然后在空间非常小的时候完全放弃它们,并切换到移动导航解决方案。