【问题标题】:Elongated hexagon shaped button using only one element仅使用一个元素的细长六边形按钮
【发布时间】:2014-10-16 04:41:50
【问题描述】:

我想用 CSS 制作一个像这样的按钮,而不使用其他元素。

按钮图片

由于按钮附有border,我想我通常需要:before:after 元素来在一侧创建一个箭头。因此,要在每一侧制作一个箭头,我需要在链接中添加另一个 span 元素。

我尝试的第二种方法是您在下面看到的方法。但是在这种解决方案中,它们没有正确居中,并且箭头的每一侧的长度都不同。

有人有解决办法吗?

/* General Button Style */

.button {
  display: block;
  position: relative;
  background: #fff;
  width: 300px;
  height: 80px;
  line-height: 80px;
  text-align: center;
  font-size: 20px;
  text-decoration: none;
  text-transform: uppercase;
  color: #e04e5e;
  margin: 40px auto;
  font-family: Helvetica, Arial, sans-serif;
  box-sizing: border-box;
}
/* Button Border Style */

.button.border {
  border: 4px solid #e04e5e;
}
.button.border:hover {
  background: #e04e5e;
  color: #fff;
}
/* Button Ribbon-Outset Border Style */

.button.ribbon-outset.border:after,
.button.ribbon-outset.border:before {
  top: 50%;
  content: " ";
  height: 43px;
  width: 43px;
  position: absolute;
  pointer-events: none;
  background: #fff;
}
.button.ribbon-outset.border:after {
  left: -3px;
  margin-top: -40px;
  transform-origin: 0 0;
  box-sizing: border-box;
  border-bottom: 4px solid #e04e5e;
  border-left: 4px solid #e04e5e;
  transform: rotate(57.5deg) skew(30deg);
}
.button.ribbon-outset.border:before {
  right: -46px;
  margin-top: -40px;
  transform-origin: 0 0;
  box-sizing: border-box;
  border-top: 4px solid #e04e5e;
  border-right: 4px solid #e04e5e;
  transform: rotate(57.5deg) skew(30deg);
}
.button.ribbon-outset.border:hover:after {
  background: #e04e5e
}
.button.ribbon-outset.border:hover:before {
  background: #e04e5e
}
<a href="#" class="button ribbon-outset border">Click me!</a>

CodePen Demo

【问题讨论】:

  • 也许您可以使用 SVG 背景图像并添加数据 url。
  • @Harry 我认为您的评论仍然有用,如果它不完全符合我的需要,因为它带有进一步的标记。仍然很有趣,谢谢。

标签: html css css-shapes pseudo-element


【解决方案1】:

我叉了你的笔

Codepen Demo

主要的变化是我从主按钮上删除了侧边框(因为它们是多余的

/* Button Border Style */
.button.border {
    border-top: 4px solid #e04e5e;
   border-bottom: 4px solid #e04e5e;
}

并更改了几个值以将其全部调整到位

/* Button Ribbon-Outset Border Style */
.button.ribbon-outset.border:after,
.button.ribbon-outset.border:before {
        top: 50%;
        content: " ";
        height: 43px;
        width: 43px;
        position: absolute;
        pointer-events: none;
}

.button.ribbon-outset.border:after {
        left:0;
        margin-top:-40px;
        transform-origin:0 0;
        box-sizing:border-box;
        border-bottom:4px solid #e04e5e;
        border-left:4px solid #e04e5e;
        transform:rotate(57.5deg) skew(30deg);
    }
    .button.ribbon-outset.border:before {
        right:-43px;
        margin-top:-40px;
        transform-origin:0 0;
        box-sizing:border-box;
        border-top:4px solid #e04e5e;
        border-right:4px solid #e04e5e;
        transform:rotate(57.5deg) skew(30deg);
    }

【讨论】:

  • 非常感谢,它看起来更清晰。但是仍然存在箭头的角没有居中或正确对齐的问题:See Image 如果没有进一步的标记,它可能是不可能的?
  • 这是由于我怀疑的变换和倾斜造成的问题......以及亚像素。坦率地说,除非我真的放大... 很多
  • 我可以清楚地看到它,但我认为如果不是不可能,使用 CSS 就很难做到这一点。也许你可以称之为“设计”。 ;)
  • 坦率地说,我正在从这些效果转向内联 SVG 元素...这要容易得多
  • 知道了:Updated Codepen。由于边框,我不确定如何使用内联 SVG 元素实现相同的效果。
【解决方案2】:

我自己得到了答案。这是 :before 和 :after 元素的转换属性的问题。

CSS 更改:

/* Button Border Style */
.button.border {
    border-top:4px solid #e04e5e;
    border-bottom:4px solid #e04e5e;
}
/* Button Ribbon-Outset Border Style */
.button.ribbon-outset.border:after, .button.ribbon-outset.border:before {
    height: 42px;
    width: 42px;
}
.button.ribbon-outset.border:after {
    left:0;
    border-bottom:5px solid #e04e5e;
    border-left:5px solid #e04e5e;
    transform:rotate(45deg) skew(19deg,19deg);
}
.button.ribbon-outset.border:before {
    right:-42px;
    border-top:5px solid #e04e5e;
    border-right:5px solid #e04e5e;
    transform:rotate(45deg) skew(19deg,19deg);
}

Updated Codepen

【讨论】:

  • 很高兴看到你已经能够自己解决它,伙计。以防万一,this demo 有另一种方法。 注意:仅在 Chrome 上测试。
【解决方案3】:

这是另一种仅使用一个元素即可完成此操作的替代方法。

这种方法的工作原理如下:

  1. 两个伪元素:before:after 大约是主.button 元素的一半大小(包括borders)。每个伪元素的高度为 34px + 4px 边框(顶部/底部)和 2px 在另一侧。
  2. 形状的上半部分是使用:before 元素实现的,而下半部分是使用:after 元素实现的。
  3. 使用rotateXperspective 来实现倾斜效果并定位以放置两个元素,使它们形成预期的形状。

/* General Button Style */

.button {
  position: relative;
  display: block;
  background: transparent;
  width: 300px;
  height: 80px;
  line-height: 80px;
  text-align: center;
  font-size: 20px;
  text-decoration: none;
  text-transform: uppercase;
  color: #e04e5e;
  margin: 40px auto;
  font-family: Helvetica, Arial, sans-serif;
  box-sizing: border-box;
}
.button:before,
.button:after {
  position: absolute;
  content: '';
  width: 300px;
  left: 0px;
  height: 34px;
  z-index: -1;
}

.button:before {
  transform: perspective(15px) rotateX(3deg);
}
.button:after {
  top: 40px;
  transform: perspective(15px) rotateX(-3deg);
}

/* Button Border Style */

.button.border:before,
.button.border:after {
  border: 4px solid #e04e5e;
}
.button.border:before {
  border-bottom: none; /* to prevent the border-line showing up in the middle of the shape */
}
.button.border:after {
  border-top: none; /* to prevent the border-line showing up in the middle of the shape */
}

/* Button hover styles */

.button.border:hover:before,
.button.border:hover:after {
  background: #e04e5e;
}
.button.border:hover {
  color: #fff;
}
<!-- Library included to avoid browser prefixes -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>

<a href="#" class="button ribbon-outset border">Click me!</a>

Fixed Width Demo | Dynamic Width Demo

输出截图:

这是在 Chrome v24+、Firefox v19+、Opera v23+、Safari v5.1.7、IE v10 中测试的。


按原样,这在 IE 8 和 IE 9 中会很好地降级为带边框的方形按钮。然而,由于一个borderborder-bottom 用于:beforeborder-top 用于:after)的无效,它会在中间留下一个白色区域(类似于删除线)。这可以通过使用this demo 中的条件 cmets 添加几个 IE

<!--[if IE]>
  <style>
    .button.border:after{
      top: 38px;
    }
    .button.border:hover:before, .button.border:hover:after {
      border-bottom: 4px solid #e04e5e;
    }
  </style>
<![endif]-->

IE 9 和 IE 8 的输出屏幕截图:

【讨论】:

  • 我真的很喜欢你的解决方案,没想到透视变换,但我认为这种效果最好。非常感谢!
  • @Snowball:欢迎朋友。总是很乐意提供帮助:)
  • 对于 IE 9,您可以使用 -ms- 前缀。
  • 这是一个非常好的方法,因为您可以控制边框和边框半径。但是,正如您在动态宽度演示中看到的那样,随着宽度的变化,两侧会变得不同。希望它可以保持相同的角度。
【解决方案4】:

这只是哈利答案的一个更简单的替代方案。

此方法使用scale()rotate(45deg) 转换。使用这种方法,您可以非常轻松地更改左右 V 形的角度。

Fiddle

div {
    height: 70px;
    width: 200px;
    margin-left: 40px;
    border-top: 4px solid #E04E5E;
    border-bottom: 4px solid #E04E5E;
    position: relative;
    text-align: center;
    color: #E04E5E;
    line-height: 70px;
    font-size: 21px;
    font-family: sans-serif;
}
div:before, div:after {
    content:'';
    position: absolute;
    top: 13px;
    height: 40px;
    width: 40px;
    border: 4px solid #E04E5E;
    -webkit-transform: scale(0.8,1.25) rotate(45deg);
    -moz-transform: scale(0.8,1.25) rotate(45deg);
    -ms-transform: scale(0.8,1.25) rotate(45deg);
    transform: scale(0.8,1.25) rotate(45deg);
}
div:before {
    left: -22px;
    border-top: 0px solid transparent;
    border-right: 0px solid transparent;
}
div:after {
    right: -22px;
    border-bottom: 0px solid transparent;
    border-left: 0px solid transparent;
}
div:hover, div:hover:before, div:hover:after {
    background-color: #E04E5E;
    color: #EEE;
}
&lt;div&gt;HELLO!&lt;/div&gt;

想要更宽的箭头?只需减小scale() 变换的xFiddle (wide)

窄一点?增加scale()变换的xFiddle (narrow)


注意: IE 8 及以下版本不支持 CSS 转换(9 支持带有 -ms- 前缀),因此您可以查看此站点以获取支持:IE Transform Translator

【讨论】:

  • 不错的替代方法。但我不太同意更简单的部分,因为正如我在其他评论中所指出的,两者都涉及计算。在这种方法中,需要修改比例值,而在另一种方法中,需要修改旋转角度。此外,缩放和倾斜都会导致边框变得更厚/更薄。
猜你喜欢
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
相关资源
最近更新 更多