带右箭头的按钮 - 过渡

时间:2016-05-13 08:57:45

标签: css css3 css-transitions css-shapes css-transforms

在css变换和伪元素的帮助下,我用箭头形状的右边框制作了css按钮。现在我试图在悬停时添加过渡到背景但是在过渡颜色不同的过程中,在按钮与伪元素重叠的地方意识到存在问题。请参阅下面的内容,尝试将鼠标悬停在按钮上:

body {
  background: gray;
background-image: linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),
linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),
linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),
linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),
linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a), 
linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a);
background-size:80px 140px;
background-position: 0 0, 0 0, 40px 70px, 40px 70px, 0 0, 40px 70px;
  font-family: sans-serif;
}
.more-skewed {
  display: inline-block;
  position: relative;
  color: white;
  text-decoration: none;
  border: solid 2px white;
  border-right: none;
  box-sizing: border-box;
  padding: 15px 40px;
  letter-spacing: 3px;
  transition: all 1s ease-out;
}

.more-skewed:before {
  content: '';
  position: absolute;
  left: 100%;
  margin-left: -10px;
  top: -2px;
  bottom: 50%;
  border-right: solid 2px white;
  transform: skewX(25deg);
  width: 15px;
  background: inherit;
}

.more-skewed:after {
  content: '';
  position: absolute;
  left: 100%;
  margin-left: -10px;
  bottom: -2px;
  top: 50%;
  border-right: solid 2px white;
  transform: skewX(-25deg);
  width: 15px;
  background: inherit;
}

.more-skewed:hover {
  color: black;
	background: white;
}
<a class="more-skewed" href="#">MORE</a>

有可能解决这个问题吗? JSfiddle - https://jsfiddle.net/k9jhuc34/
(按钮最初是透明的,它在图像背景上。)

3 个答案:

答案 0 :(得分:7)

正如我的评论中所述,这是预期的,因为粗略地说,发生的事情是半透明的白色层被放置在有重叠的区域中的另一个这样的层的顶部,因此,该区域很快看起来比其他人更白。

使用偏斜转换:

一个解决方案就像在下面的代码片段中一样,但它使悬停/命中区域成为一个矩形。我在这里做的是让伪元素创建整个形状(除了左边框),并且父元素上的overflow-hidden可以防止左侧不需要的倾斜部分显示出来。

&#13;
&#13;
body {
  background: gray;
  font-family: sans-serif;
}
.more-skewed {
  display: inline-block;
  position: relative;
  color: white;
  text-decoration: none;
  border-left: solid 2px white;
  box-sizing: border-box;
  padding: 15px 40px;
  letter-spacing: 3px;
  transition: all 1s ease-out;
  overflow: hidden;
}
.more-skewed:before {
  content: '';
  position: absolute;
  left: -2px;
  top: 0px;
  bottom: 50%;
  border-right: solid 2px white;
  border-top: solid 2px white;
  transform: skewX(25deg);
  transform-origin: right bottom;
  width: 100%;
  transition: all 1s ease-out;
  z-index: -1;
}
.more-skewed:after {
  content: '';
  position: absolute;
  left: -2px;
  bottom: 0px;
  top: 50%;
  border-right: solid 2px white;
  border-bottom: solid 2px white;
  transform: skewX(-25deg);
  transform-origin: right top;
  width: 100%;
  transition: all 1s ease-out;
  z-index: -1;
}
.more-skewed:hover {
  color: black;
}
.more-skewed:hover:before,
.more-skewed:hover:after {
  background: white;
}
&#13;
<a class="more-skewed" href="#">MORE</a>
&#13;
&#13;
&#13;

使用带透视的旋转:

另一种解决方案可能是使用旋转变换并添加一些透视图。通过设置transform-origin的适当值,我们可以使它产生一个梯形,可以放置在适当的位置以产生箭头。这里,悬停/命中区域保持在形状内,但只有在文本较小且静态时,此方法才有用。如果文本变长,形状右侧的斜率变得更加渐进而不是陡峭(当然,我们可以更改变换以使其看起来更好,但是如果我们必须不断变化则不是很有用经常)。

&#13;
&#13;
.more-skewed {
  display: inline-block;
  position: relative;
  color: white;
  text-decoration: none;
  border: solid 2px white;
  border-right: none;
  box-sizing: border-box;
  padding: 16px 40px;
  letter-spacing: 3px;
  margin: 10px;
}
.more-skewed:before,
.more-skewed:after {
  position: absolute;
  content: '';
  height: 50%;
  width: 100%;
  left: 0;
  border-right: 3px solid white;
  transition: all 1s ease-out;
}
.more-skewed:before {
  top: -2px;
  border-top: 2px solid white;
  transform-origin: left top;
  transform: perspective(100px) rotateX(30deg);
}
.more-skewed:after {
  bottom: -2px;
  border-bottom: 2px solid white;
  transform-origin: left bottom;
  transform: perspective(100px) rotateX(-30deg);
}
.more-skewed:hover {
  color: black;
}
.more-skewed:hover:before,
.more-skewed:hover:after {
  background: white;
}
.more-skewed span {
  position: relative;
  z-index: 1;
}
body {
  background: gray;
  font-family: sans-serif;
}
&#13;
<a class="more-skewed" href="#">
  <span>MORE</span>
</a>
<br/>
<a class="more-skewed" href="#">
  <span>MORE LONGER TEXT</span>
</a>
&#13;
&#13;
&#13;

反馈是以上代码段在IE中断开。我会在找到时间时解决这个问题。

这是我在玩的时候提出的另一个版本。它有点像背景滑动填充效果,它将悬停/命中区域保持在形状内,但由于浏览器渲染渐变的方式,它并不是非常干净。想把它留在这里,以防万一你发现它很有用。

&#13;
&#13;
body {
  background: gray;
  font-family: sans-serif;
}
.more-skewed {
  display: inline-block;
  position: relative;
  color: white;
  text-decoration: none;
  border: solid 2px white;
  border-right: none;
  box-sizing: border-box;
  padding: 15px 40px;
  letter-spacing: 3px;
  transition: all 1s linear;
  background: linear-gradient(245deg, transparent 9px, white 10px), linear-gradient(295deg, transparent 9px, white 10px);
  background-size: 0% 50%;
  background-position: top right, bottom right;
  background-repeat: no-repeat;
}
.more-skewed:before {
  content: '';
  position: absolute;
  left: 100%;
  margin-left: -7px;
  top: -2px;
  bottom: 50%;
  transform: skewX(25deg);
  width: 15px;
  background: linear-gradient(white, white);
  background-size: 3px 100%;
  background-repeat: no-repeat;
  background-position: top right;
  transition: all 1s 1s linear;
}
.more-skewed:after {
  content: '';
  position: absolute;
  left: 100%;
  margin-left: -7px;
  bottom: -2px;
  top: 50%;
  transform: skewX(-25deg);
  width: 15px;
  background: linear-gradient(white, white);
  background-size: 3px 100%;
  background-repeat: no-repeat;
  background-position: top right;
  transition: all 1s 1s linear;
}
.more-skewed:hover {
  color: black;
  background-size: 100% 50%;
  transition: all 1s 1s linear;
}
.more-skewed:hover:before,
.more-skewed:hover:after {
  color: black;
  background-size: 100% 100%;
  transition: all 1s linear;
}
&#13;
<a class="more-skewed" href="#">MORE</a>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

请使用transition检查下面的箭头代码,希望有所帮助。

由于

<强> HTML

<a class="arrow_box">
MORE
</a>

<强> CSS

body {
  background: gray;
  font-family: sans-serif;
}
.arrow_box {
    position: relative;
    background: gray;
    border: 2px solid #ffffff;
  display:inline-block;
  padding: 15px 40px;
  letter-spacing: 3px;
  color:#FFF;
  transition:0.4s;
}
.arrow_box:after, .arrow_box:before {
    left: 100%;
    top: 50%;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
  transition:0.4s;
}

.arrow_box:after {
    border-color: rgba(128, 128, 128, 0);
    border-left-color: gray;
  border-width: 24px;
  margin-top: -24px;
}
.arrow_box:before {
    border-color: rgba(255, 255, 255, 0);
    border-left-color: #ffffff;
    border-width: 26px;
  margin-top: -26px;
  margin-left: 2px;
}
.arrow_box:hover{
  color:#000;
  background:#FFF;
}
.arrow_box:hover:after{
  border-left-color: #FFF;
}

检查fiddle here

答案 2 :(得分:1)

如果链接所在的背景只是一个纯色,如提供的示例所示,您可以使用几个三角形实现此目的,如下所示:

*{box-sizing:border-box;font-family:sans-serif;}
body{
    background:#333;
}
a{
    border:2px solid #fff;
    border-right:0;
    color:#fff;
    display:inline-block;
    letter-spacing:3px;
    line-height:50px;
    padding:0 40px;
    position:relative;
    text-decoration:none;
    text-transform:uppercase;
    transition:background 1s ease-out,color 1s ease-out;
}
a::before{
    border-top:27px solid transparent;
    border-left:14px solid #fff;
    border-bottom:27px solid transparent;
    content:"";
    position:absolute;
    right:-14px;
    top:-2px;
}
a::after{
    border-top:25px solid transparent;
    border-left:12px solid #333;
    border-bottom:25px solid transparent;
    content:"";
    position:absolute;
    right:-12px;
    top:0;
    transition:opacity 1s ease-out;
}
a:hover{
    background:#fff;
    color:#333;
}
a:hover::after{
    opacity:0;
}
<a href="#">More</a>

我也想出了以下内容,但它有点“janky”,箭头并不是你想要的。无论如何我决定编辑它以防将来对其他任何人使用。

*{box-sizing:border-box;font-family:sans-serif;}
body{
    background:#333;
}
a{
    border:2px solid #fff;
    border-right:0;
    color:#fff;
    display:inline-block;
    letter-spacing:3px;
    line-height:50px;
    padding:0 40px;
    position:relative;
    text-decoration:none;
    text-transform:uppercase;
    transition:background 1s ease-out,color 1s ease-out;
}
a::before{
    border-right:2px solid #fff;
    border-top:2px solid #fff;
    content:"";
    height:36px;
    position:absolute;
    right:-19px;
    top:6px;
    transform:rotate(45deg);
    width:36px;
}
a::after{
    background:linear-gradient(-135deg,#fff 50%,transparent 50%);
    content:"";
    height:34px;
    opacity:0;
    position:absolute;
    right:-17px;
    top:8px;
    transform:rotate(45deg);
    transition:opacity 1s ease-out;
    width:34px;
}
a:hover{
    background:#fff;
    color:#333;
}
a:hover::after{
    opacity:1;
}
<a href="#">More</a>