0

我有一个 SVG,它是用一个用于锚边框的多边形创建的。我遇到的一个问题是我希望按钮支持可变内容 - 允许按钮根据需要水平调整大小以适应,同时限制侧线的角度。

我似乎无法弄清楚是否需要以某种方式处理拆分原始多边形、调整 viewBox 或其他什么。我们很难过。

我使用的内联 SVG 相当基本:

* { box-sizing: border-box; }

.btn {
  width: 198px;
  display: inline-block;
  background: transparent;
  margin: 2px 0;
  padding: 0;
  height: 41px;
  text-align: center;
  font-size: 10px;
  line-height: 41px;
  font-weight: 600;
  font-family: sans-serif;
  text-transform: uppercase;
  color: #FFF;
  position: relative;
  transition: all ease-in-out 0.3s; }
  .btn.btnFluid {
    width: auto; }
    .btn.btnFluid svg {
      width: 100%;
      height: 41px; }
  .btn svg polygon {
    fill: #000;
    transition: fill 0.3s ease;
    stroke: #002b5d;
    stroke-width: 2; }
  .btn:hover {
    color: #000; }
    .btn:hover svg polygon {
      stroke: #000;
      fill: #FFF; }
  .btn span {
    position: absolute;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    display: block;
    padding: 0 25px; }

svg:not(:root) {
  overflow: hidden; }

  
<a href="#" class="btn">
  <svg xmlns="http://www.w3.org/2000/svg" class="btn-svg" viewBox="0 0 386.16 80">
    <polygon points="346.14 78 40.02 78 3.19 2 382.97 2 346.14 78"></polygon>
   </svg>
  <span>Read More</span>
</a>
<br><br>
<a href="#" class="btn btnFluid">
  <svg xmlns="http://www.w3.org/2000/svg" class="btn-svg" viewBox="0 0 386.16 80" preserveAspectRatio="none">
    <polygon points="346.14 78 40.02 78 3.19 2 382.97 2 346.14 78"></polygon>
  </svg>
  <span>A much longer cta button label</span>
</a>

我在这里创建了一个可编辑的演示:https ://jsfiddle.net/32wcq1zr/1/——比较第一个按钮和第二个按钮的侧边角度。理想情况下,我希望拥有第二个按钮的功能,但侧线的角度一致。

4

3 回答 3

2

对于这种特殊的形状,这里介绍的其他选项(使用pseudo元素 或masks)是更好的解决方案。但是,对于更复杂的形状,这是一个很好的选择。


CSSborder-image已经存在了很长一段时间,具有相当好的支持并且允许 9 切片缩放

9 切片缩放允许您通过将图像分成代表所有 4 个角、4 个边和中心的象限来决定图像的每个部分的“缩放方式”。

您可以使用border-image图像或 SVG,但图像更直接。Chirs Coyer 有一个很好的概述

这是使用您的形状的示例

注意:如果您使用具有使数学变得容易的尺寸的图像,它会有所帮助

在此处输入图像描述(100px x 40px,底部插入 20px)

a {
  display:inline-block;
  text-decoration: none;
  margin: 10px;
  color: #fff;
  padding: 0 10px;
  border: 20px solid black;
  border-image: url(https://i.stack.imgur.com/T8TC6.png);
  border-image-slice: 0 20% fill;
  border-image-width: auto;
}
<a href="#">short</a>

<a href="#">much longer text that causes things to scale</a>

还有一个更复杂的形状来展示它是如何工作的:

在此处输入图像描述

a {
  display:inline-block;
	text-decoration:none;
  margin: 10px;
	color: #fff;
	padding: 0 10px;
	border: 20px solid;
  border-image: url(https://i.stack.imgur.com/pUwi4.png);
	border-image-slice: 15 fill;
	border-image-width: auto;
	border-image-repeat: round;
}
<a href="#">short</a>

<a href="#">much longer text that causes things to scale</a>

于 2019-05-08T21:51:57.083 回答
1

这是您的问题的替代解决方案。除了使用 SVG,这可以使用透明边框和文本到 ::before / ::after 中完成

.button {
  --h:50;
  width: 198px;
  display: inline-block;
  border: calc(var(--h) * 1px) solid black;
  border-left-color: transparent;
  border-right-color: transparent;
  border-bottom: none;
  position:relative;
}

.button::before {
  content: "Read More";
  color: white;
  display: block;
  width: 100%;
  height:calc(var(--h) * 1px);
  position: absolute;
  top: calc(var(--h) * -1px);
  left: 0;
  text-align: center;
  line-height:calc(var(--h) * 1px);
  font-weight: 600;
  font-family: sans-serif;
  text-transform: uppercase;
}

.button.long{width:300px}

.button.long::before{content:"A much longer cta button label"}
<div class="button"></div>
<div class="button long"></div>

于 2019-05-08T18:37:22.060 回答
1

一般来说,您所追求的“有弹性”的 SVG 是不可能的。

但在某些情况下,使用<use><mask>元素的一些技巧是有可能实现的。

这是如何工作的,我们将按钮分成两个形状。一个用于左端 ( #left),一个用于中间和右端 ( #right)。右侧的按钮非常长,因此可以容纳一系列按钮尺寸。右侧部分位于 SVG 的右手端,并被遮盖以使其不覆盖左侧部分。

* { box-sizing: border-box; }

.btn {
  width: 198px;
  display: inline-block;
  background: transparent;
  margin: 2px 0;
  padding: 0;
  height: 41px;
  text-align: center;
  font-size: 10px;
  line-height: 41px;
  font-weight: 600;
  font-family: sans-serif;
  text-transform: uppercase;
  color: #FFF;
  position: relative;
  transition: all ease-in-out 0.3s; }
  .btn.btnFluid {
    width: auto; }
    .btn.btnFluid svg {
      width: 100%;
      height: 41px; }
  .btn svg .highlight {
    fill: #000;
    transition: fill 0.3s ease;
    stroke: #002b5d;
    stroke-width: 2; }
  .btn:hover {
    color: #000; }
    .btn:hover svg .highlight {
      stroke: #000;
      fill: #FFF; }
  .btn span {
    position: absolute;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    display: block;
    padding: 0 25px; }

svg:not(:root) {
  overflow: hidden; }
<a href="#" class="btn">
  <svg class="btn-svg" width="100%">
    <defs>
      <polyline id="left" points="21,1, 1,1, 20,40, 21,40"/>
      <polyline id="right" points="-1500,1, -1,1, -20,40, -1500,40"/>
      <mask id="mask-right">
        <rect width="100%" height="100%" fill="white"/>
        <rect width="20" height="100%" fill="black"/>
      </mask>
    </defs>
    <g class="highlight" mask="url(#mask-right)">
      <use xlink:href="#right" x="100%"/>
    </g>
    <use class="highlight" xlink:href="#left"/>
  </svg>
  <span>Read More</span>
</a>
<br><br>
<a href="#" class="btn btnFluid">
  <svg class="btn-svg" width="100%">
    <defs>
      <polyline id="left2" points="21,1, 1,1, 20,40, 21,40"/>
      <polyline id="right2" points="-1500,1, -1,1, -20,40, -1500,40"/>
      <mask id="mask-right2">
        <rect width="100%" height="100%" fill="white"/>
        <rect width="20" height="100%" fill="black"/>
      </mask>
    </defs>
    <g class="highlight" mask="url(#mask-right2)">
      <use xlink:href="#right" x="100%"/>
    </g>
    <use class="highlight" xlink:href="#left2"/>
  </svg>
  <span>A much longer cta button label</span>
</a>

于 2019-05-08T18:37:42.973 回答