【问题标题】:Rounded arrow shape with gradient fill带渐变填充的圆角箭头形状
【发布时间】:2015-01-31 06:03:23
【问题描述】:

对于我的在线游戏 UI,我决定制作 Hill Climb Racing(Android 游戏) 的按钮。这是我目前拥有的:

body {
    color: white;
    font-family: Impact, fantasy;
    font-size: 40px;
    line-height: 100px;
    text-align: center;
}
.rect {
    height: 100px;
    width: 280px;
    background: #545D60;
    border-radius: 20px 50px 50px 20px;
    position: relative;
}
.rect:before {
    background: #545D60;
    content: "";
    position: absolute;
    top: 6px;
    left: 195px;
    height: 0px;
    width: 0px;
    border-radius: 30px 10px;
    border: 44px solid #545D60;
    transform: rotate(45deg);
}
<div class="rect">NEXT</div>

问题在于正确对齐渐变渐变背景可以添加到rect,但相同的渐变无法与右侧的三角形正确对齐。
诸如此类的解决方案很有帮助,但不适用于我正在尝试的解决方案: link

另外,我们可以创建一个带有渐变背景的响应式形状吗?

注意:这不是重复的,它是一个完全不同的问题。

编辑

此外,在悬停时,渐变会倒置,即旋转 180 度。这部分我可以创建,但是对齐rectbefore 的渐变仍然是个问题。

【问题讨论】:

  • --------------> Fiddle
  • CSS 请@chipChocolate.py.
  • @chipChocolate.py 你能让它响应 vh 吗?
  • 宽度也没有变化。
  • 这是一个 CSS 解决方案 ---> Fiddle

标签: html css css-shapes linear-gradients


【解决方案1】:

注意:这并不是您想要实现的方式,但在我看来,这可能是实现它的最简单方式,无需借助 SVG 或图像或复杂的渐变角度计算。旋转伪元素等会导致另一侧不匹配,因为右侧有弯曲的一侧。

形状是通过使用两个大约是父元素 (.rect) 一半大小的伪元素来实现的,将它们向相反方向倾斜,然后将它们准确地定位在另一个之下。通过使用伪元素的left 属性将其定位在父矩形内,另一侧(左侧)被隐藏起来。

所需的渐变被分配给父元素和伪元素。对于父元素,会根据需要应用完整的渐变,而对于伪元素,它会在 :before:after 元素之间精确地分成两半,以使其看起来是渐进式的。

由于:before:after 伪元素实际上是主元素的子元素,因此它们上的hover 实际上也意味着父元素上的hover

span 包含文本,并以更高的 z-index 定位,使其位于伪元素上方,从而可见。

body {
  color: white;
  font-family: Impact, fantasy;
  font-size: 40px;
  line-height: 100px;
  text-align: center;
}
.rect {
  height: 100px;
  width: 225px;
  position: relative;
  border-radius: 20px 0px 0px 20px;
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#949DA0), to(#545D60));
  background: -webkit-linear-gradient(#949DA0, #545D60);
  background: -moz-linear-gradient(#949DA0, #545D60);
  background: -o-linear-gradient(#949DA0, #545D60);
  background: linear-gradient(#949DA0, #545D60);
}
.rect span {
  position: relative;
  z-index: 2;
}
.rect:before {
  background: #545D60;
  content: "";
  position: absolute;
  top: 0px;
  left: 42px;
  height: 51%;
  width: 100%;
  border-radius: 0px 10px 6px 0px;
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#949DA0), to(#747D80));
  background: -webkit-linear-gradient(#949DA0, #747D80);
  background: -moz-linear-gradient(#949DA0, #747D80);
  background: -o-linear-gradient(#949DA0, #747D80);
  background: linear-gradient(#949DA0, #747D80);
  -webkit-transform: skew(45deg);
  -moz-transform: skew(45deg);
  transform: skew(45deg);
}
.rect:after {
  background: #545D60;
  content: "";
  position: absolute;
  bottom: 0px;
  left: 42px;
  height: 51%;
  width: 100%;
  border-radius: 0px 6px 10px 0px;
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#747D80), to(#545D60));
  background: -webkit-linear-gradient(#747D80, #545D60);
  background: -moz-linear-gradient(#747D80, #545D60);
  background: -o-linear-gradient(#747D80, #545D60);
  background: linear-gradient(#747D80, #545D60);
  -webkit-transform: skew(-45deg);
  -moz-transform: skew(-45deg);
  transform: skew(-45deg);
}
.rect:hover {
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#545D60), to(#949DA0));
  background: -webkit-linear-gradient(#545D60, #949DA0);
  background: -moz-linear-gradient(#545D60, #949DA0);
  background: -o-linear-gradient(#545D60, #949DA0);
  background: linear-gradient(#545D60, #949DA0);
}
.rect:hover:before {
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#545D60), to(#747D80));
  background: -webkit-linear-gradient(#545D60, #747D80);
  background: -moz-linear-gradient(#545D60, #747D80);
  background: -o-linear-gradient(#545D60, #747D80);
  background: linear-gradient(#545D60, #747D80);
}
.rect:hover:after {
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#747D80), to(#949DA0));
  background: -webkit-linear-gradient(#747D80, #949DA0);
  background: -moz-linear-gradient(#747D80, #949DA0);
  background: -o-linear-gradient(#747D80, #949DA0);
  background: linear-gradient(#747D80, #949DA0);
}
<div class="rect"><span>NEXT</span>
</div>

【讨论】:

  • 嘿,它有一个悬停。 z-index: -1; 上的 :before 将无法正常工作。
  • @Harry 我也需要悬停按钮。
  • @ThePragmatick:您不需要将鼠标悬停在:before 元素上。您可以在主元素悬停时更改它们。
  • @JakeMikail:请检查更新后的 sn-p 以获得悬停效果。唯一的问题是悬停时左侧的边界半径丢失。我会尽快修复它。 编辑: 似乎悬停会导致左侧的边框半径仅在较低版本的 Chrome 上消失。在其他最新版本中运行良好。
  • @Harry 工作得很好!没看到你有 2 个伪元素。