如何使用CSS过渡将加号变成减号?

9
我想创建一个切换按钮,使其形状从加号变成减号。
使用纯 CSS 实现,不使用伪元素
我希望实现的效果是将“+”符号中的竖线缩小为水平线。
我知道这是可能的,但我不确定采取哪种最佳路线。我考虑使用 height 实现,但我担心浏览器的 line-height 会改变其在元素中的位置。

$('button').on("click", function(){
  $(this).toggleClass('active');
});
button {
color: #ecf0f1;
background:  #e74c3c;
  width: 50px;
  height: 50px;
  border: 0;
  font-size: 1.5em;
  }
button span {
  transition: all .75s ease-in-out;
  }
button.active span {
  /* Code to morph + to - */
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button><span>+</span></button>

5个回答

29

因为形状很简单,最简单的方法就是使用元素来制作+-。使用伪元素将是最干净的解决方案,但您也可以使用一个DOM元素并拥有稍微混乱的文档结构。

考虑到这一点,实际解决方案很简单。我们使用CSS定位元素以类似所需字符的方式,并通过动画该位置来“变形”它们。

查看以下代码,并尝试理解每个规则的作用。

button {
  color: #ecf0f1;
  background: #e74c3c;
  width: 50px;
  height: 50px;
  border: 0;
  font-size: 1.5em;
  position: relative;
}

button span {
  position: absolute;
  transition: 300ms;
  background: white;
  border-radius: 2px;
}

/* Create the "+" shape by positioning the spans absolutely */
button span:first-child {
  top: 25%;
  bottom: 25%;
  width: 10%;
  left: 45%;
}

button span:last-child {
  left: 25%;
  right: 25%;
  height: 10%;
  top: 45%;
}

/* Morph the shape when the button is hovered over */
button:hover span {
  transform: rotate(90deg);
}

button:hover span:last-child {
  left: 50%;
  right: 50%;
}
<button>
  <span></span>
  <span></span>
</button>


是的,这是最简单的方法,但 OP 不想要伪元素 :/ - dippas
@dippas 我会更新答案,但概念仍然相同。 - Jacob G

18

CSS解决方案

$('button').on("click", function(){
  $(this).toggleClass('active');
});
button {
  color: #ecf0f1;
  background: #e74c3c;
  width: 70px;
  height: 70px;
  position: relative;
  font-size: 50px;
  cursor: pointer;
  border: 0;
  outline: 0;
  padding: 0
}
.plus,
.minus {
  color: #fff;
  padding: 10px;
  width: 70px;
  height: 70px;
  line-height: 50px;
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  text-align: center;
  box-sizing: border-box;
  transition: .5s all ease-out;
}
.plus {
  opacity: 1;
  transform: rotate(0deg);
}
button.active .plus {
  opacity: 0;
  transform: rotate(90deg);
}
.minus {
  opacity: 0;
  transform: rotate(-90deg);
}
button.active .minus {
  opacity: 1;
  transform: rotate(0deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
<button>
  <span class="plus"><i class="fa fa-plus"></i></span>
  <span class="minus"><i class="fa fa-minus"></i></span>
</button>

CSS解决方案(旧版):

使用伪元素::beforecontent属性。

$('button').on("click", function() {
  $(this).toggleClass('active');
});
button {
  color: #ecf0f1;
  background: #e74c3c;
  width: 50px;
  height: 50px;
  border: 0;
  font-size: 1.5em;
}
button span {
  transition: all .75s ease-in-out;
  position:relative
}
button span::before {
  content:"+"
}
button.active span::before {
  content:"-"
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button><span></span></button>

一种(旧的)jQuery解决方案:

使用jQuery中的text()和if语句,无需使用span即可完成此操作。

$('button').on("click", function() {
  $(this).toggleClass('active');
  $(this).text() == "+" ? $(this).text("-") : $(this).text("+");
});
button {
  color: #ecf0f1;
  background: #e74c3c;
  width: 50px;
  height: 50px;
  border: 0;
  font-size: 1.5em;
  transition: all .75s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button>+</button>


我希望它能够变形,而不仅是改变。谢谢! - yaserso
只是提供信息,我添加了一个仅使用CSS的解决方案,你所说的“morph”是什么意思? - dippas
3
请停止编辑问题,以免导致答案不正确。 - dippas
我不知道如何更好地解释它。我已经在我的问题描述中提到了它。我希望加号中的竖线收缩直至消失,变成减号。 - yaserso
更新了答案,使用纯CSS解决方案,无需jQuery,无伪元素。 - dippas
2
优雅的解决方案 +1 - Ahmad Alfy

2

啊,我的错,我忽略了OP不想使用任何伪元素。但是伪元素的一个很大的优点是您可以减少HTML代码并获得更清晰的结构。

它也是一个不同的变形动画,正如OP想要的那样,但也许其他人可以使用这个。

所以,如果你不介意,我会留下我的建议。

也许像这样?

HTML

<div class="button"></div>

CSS

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: #343838;
}

.button {
  position: absolute;
  width: 55px;
  height: 55px;
  background: #70975B;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(0deg);
  border-radius: 50%;
  cursor: pointer;
  z-index: 100;
  transition: 0.4s cubic-bezier(0.2, 0.6, 0.3, 1.1);
}

.button:after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: 2px;
  width: 50%;
  background: white;
}

.button:before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: 50%;
  width: 2px;
  background: white;
}

.button.clicked {
  transform: translate(-50%, -50%) rotate(360deg);
  background: #CC2A41;
}

.button.clicked:before {
  width: 0;
}

jQuery

$(".button").click(function() {
  $(this).toggleClass("clicked");
});

以下是一个可工作的示例: http://codepen.io/svelts/pen/LkyZoZ


0
我写这个的时候想到了一个需要的例子,可以同时展示多个转换效果,使其看起来更加“精致”。
我还添加了一个“点击”事件,以保持交叉处于点击状态。

    .toggleIcon {
        position: relative;
        width: 50px; /* Define the size of your toggle icon */
        height: 50px;
        background: #ffffff; /* Set the background color */
        border-radius: 50%; /* Make it round */
        display: inline-flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
    }

    .toggleIcon::after,
    .toggleIcon::before {
        position: absolute;
        content: '';
        height: 30px;
        width: 2px;
        background: #1A0D07;
        left: 50%;
        top: 50%;
        transition: transform 0.4s ease;
        transform: translate(-50%, -50%);
    }
    .toggleIcon.toggleActive::before {
        transition: transform 0.2s ease;
    }

    .toggleIcon::before {
        transform: translate(-50%, -50%) rotate(90deg);
    }

    .toggleIconParent:hover .toggleIcon::before,
    .toggleIcon:hover::before,
    .toggleIcon:active::before{
        transform: translate(-50%, -50%) rotate(0deg) scale(1.2);
    }

    .toggleIcon:hover::after,
    .toggleIconParent:hover .toggleIcon::after,
    .toggleIcon:active::after,
    .toggleIcon.toggleActive::after {
        transform: translate(-50%, -50%) rotate(-90deg) scale(1.2);
    }

    .toggleIcon.toggleActive::before {
        transform: translate(-50%, -50%) rotate(90deg) scale(1.2);
    }

    .toggleIcon.toggleActive::after,
    .toggleIcon.toggleActive::before {
        width: 1px;
    }
<span <span onclick="this.classList.toggle('toggleActive');" class="toggleIcon h-8 w-8 cursor-pointer relative"></span>


-1

试一下这个

$('button').on("click", function() {
  var $this = $(this);
  $this.toggleClass('toggle');
  if ($this.hasClass('toggle')) {
    $this.text('+');
  } else {
    $this.text('-');
  }
});
button {
  color: #ecf0f1;
  background: #e74c3c;
  width: 50px;
  height: 50px;
  border: 0;
  font-size: 1.5em;
  transition: all .75s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="toggle">+</button>


我想让它变形,而不仅仅是改变。谢谢! - yaserso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接