如何缩放特定点,而又不留其他点?

时间:2019-05-08 15:48:29

标签: html5 css3 svg

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

我似乎无法弄清楚是否需要以某种方式处理拆分原始多边形,调整viewBox或其他操作。我们很沮丧。

我使用的内联SVG非常基本:

return false
* { 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; }

  

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

3 个答案:

答案 0 :(得分:2)

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


CSS border-image已经存在了一段时间,已经reasonably good support并且允许9切片缩放

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

您可以将border-image与图像或SVG一起使用,但是图像更为简单。 Chirs Coyer有一个good overview

以下是使用您的形状的示例

注意:如果您使用尺寸易于数学运算的图像

enter image description here(100像素x 40像素,底部插图20像素)

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>

还有一个更复杂的形状来显示其工作原理:

enter image description here

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>

答案 1 :(得分: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>

答案 2 :(得分: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>