仅限CSS,无负载转换

时间:2016-10-07 17:52:27

标签: css css-transitions

我有一个自定义复选框,其中填充了边框,颜色等的过渡以及3D转换以将其翻转过来。如果取消选中该复选框,它看起来很好并且在状态之间转换得很好,但是,如果复选框在dom加载时被赋予了checked属性,那么它必须旋转到位并且复选框在背面可见。

enter image description here

注意:虽然我链接了JsFiddle,但您可以看到代码中没有出现问题的代码。只有通过样式表链接样式时才会发生这种情况。

https://jsfiddle.net/tj2djeej/

/* Radio & Checkbox */

input.flipCheckbox {
  -webkit-transition: transform .5s linear 0s;
  -webkit-transform-style: preserve-3d;
  -webkit-appearance: none;
  -webkit-transform: rotatey(0deg);
  -webkit-perspective: 800;
  -webkit-transform-style: preserve-3d;
  box-sizing: border-box;
  position: relative;
  outline: none;
  width: 26px;
  height: 26px;
  border: 3px solid #C15649;
  cursor: pointer;
}
input.flipCheckbox:checked {
  -webkit-transform: rotatey(180deg);
}
input.flipCheckbox:after {
  -webkit-transform: rotatey(-180deg);
  -webkit-transition: color 0s linear .25s, -webkit-text-stroke-color 0s linear .25s;
  -webkit-text-stroke-color: transparent;
  cursor: pointer;
  line-height: 26px;
  font-size: 14px;
  width: 26px;
  height: 26px;
  position: absolute;
  z-index: 1;
  top: -3px;
  left: -3px;
  color: transparent;
  text-align: center;
  -webkit-text-stroke-width: 2px;
  -webkit-text-stroke-color: transparent;
}
input.flipCheckbox:checked:after {
  color: #C15649;
  -webkit-text-stroke-color: #C15649;
}
input.flipCheckbox:after {
  content: "\2713";
}
<input type="checkbox" class="flipCheckbox" />
<input type="checkbox" checked class="flipCheckbox" />

6 个答案:

答案 0 :(得分:5)

如果您只想在取消选中时隐藏复选标记,则会backface-visibility: hidden

input.flipCheckbox:after {
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}

这应该可以为您简化很多事情。例如,您不再需要为透明复选标记的颜色设置动画。

答案 1 :(得分:1)

:focus:hover伪类应该可以很好地满足您的需求。只需将您的转换规则从input.flipCheckbox移至新的规则集:

input.flipCheckbox:focus, body:hover input.flipCheckbox {
    -webkit-transition: transform .5s linear 0s;
}

由于复选框没有关注页面加载,因此不会发生转换,但是当用户选中复选框时,它会获得焦点以允许转换发生。唯一的缺点是如果复选框在动画完成之前使用焦点。就像用户只使用键盘和标签太快。这就是:hover介入的地方。由于:hover适用于bodyhtml或任何其他父级也适用),只要光标位于页面上,过渡仍然发生。

你可以只使用其中一个,但两者一起涵盖了所有内容,除非光标离开页面用户选项卡太快。

正如您所说,这些问题不会出现在在线编辑器中,但无论如何都是完整的代码。

input.flipCheckbox {
   -webkit-transform-style: preserve-3d;
   -webkit-appearance:none;
   -webkit-transform: rotatey(0deg);
   -webkit-perspective: 800;
   -webkit-transform-style: preserve-3d;
   box-sizing: border-box;
   position:relative;
   outline:none;
   width: 26px;
   height:26px;
   border: 3px solid #C15649;
   cursor: pointer;
}

input.flipCheckbox:focus, body:hover input.flipCheckbox {
    -webkit-transition: transform .5s linear 0s;
}

input.flipCheckbox:checked {
   -webkit-transform: rotatey(180deg);
}

input.flipCheckbox:after {
 -webkit-transform: rotatey(-180deg);
 -webkit-transition: color 0s linear .25s, -webkit-text-stroke-color 0s linear .25s;
 -webkit-text-stroke-color: transparent;
  cursor: pointer;
  line-height:26px;
  font-size:14px;
  width:26px;
  height:26px;
  position: absolute;
  z-index: 1;
  top:-3px;
  left:-3px;
  color:transparent;
  text-align: center;
  -webkit-text-stroke-width: 2px;
  -webkit-text-stroke-color: transparent;
}

input.flipCheckbox:checked:after {
   color: #C15649;
  -webkit-text-stroke-color: #C15649;
}

input.flipCheckbox:after {
  content:"\2713";
}
<input type="checkbox" class="flipCheckbox"/>
<input type="checkbox" checked class="flipCheckbox"/>

答案 2 :(得分:1)

您可以在元素上设置动画,以自己的速度更改元素状态。

这里的技巧是获得一个动画:

  • 不是真正的动画,因为属性值没有变化。实现此目的,设置2个具有相同值的不同关键帧。
  • 已选中状态和未选中状态的相同动画。如果我们更改动画名称,则每次更改状态时都会重播动画。为了实现这一点,我设置了一个动画,它有两个不同的部分,一个旋转了元素,另一个旋转了元素。我们使用一部分或另一部分改变从正常到反向的方向。并设置一个初始延迟,使其仅使用后半部分。

我尝试通过javascript重现您的场景,重新登录elemnt并在之后设置检查状态。我不确定这是否等同于它。

在片段上按下按钮,它会交替渲染元素,一旦处于选中状态,另一个处于未选中状态

&#13;
&#13;
var ele;
var checked = true;

function reload() {
  var oldele = document.getElementById("test");

  ele = oldele.cloneNode(true);
  oldele.parentNode.replaceChild(ele, oldele);
  setTimeout(check, 1);
}

function check() {
  ele.checked = checked;
  checked = !checked;
}
&#13;
.test {
  width: 100px;
  height: 100px;
  transition: transform 0.5s;
  transform: rotateY(180deg);
  animation-name: still;
  animation-duration: 0.2s;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-delay: -0.11s;
}
button {
  margin: 20px;
}
.test:checked {
  transform: rotateY(0deg);
  animation-direction: reverse;
}
input {
  animation-name: "";
}
@keyframes still {
  from, 49.9% {
    transform: rotateY(0deg);
  }
  50%,
  to {
    transform: rotateY(180deg);
  }
}
&#13;
<input type="checkbox" class="test" id="test" />
<button onclick="reload()">Load</button>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

这似乎是Chrome / Webkit的一个错误。至少在我的Chrome和Safari版本中,我的行为如下:

  • 在html中没有任何脚本标记,或者在css链接之前没有脚本标记或完全为空的脚本标记,并且没有任何输入元素,div或其他非输入元素上不会发生转换。

  • 在html中没有任何脚本标记,或者在css链接之前没有脚本标记或完全为空的脚本标记,只要有一个输入元素(无论哪种类型),那么所有具有不匹配默认值的样式的元素都会被转换。

  • 如果在css链接后添加脚本标记,其中至少有一个空格,则在任何元素的加载上都不会发生转换。

所以看起来输入元素会触发某种布局刷新,当脚本存在时奇怪的是不会发生。也许只是因为解析中某处的延迟,或某种错误设置的情况。至少这是我对Chrome和Safari的行为。

所以你可以简单地添加:

<script> </script> <!-- the space is important -->

链接元素后,您将无法获得您描述的行为。这不是一个css解决方案,但问题似乎与你的CSS无关,所以无论如何我都要发布它。

答案 4 :(得分:0)

是否需要连接到外部样式表?您可以在html文件本身中使用<style>标记。如果没有,请确保<link>位于标题中,以便首先加载,然后在页面加载后立即应用CSS。

答案 5 :(得分:0)

有点hackish但满足css唯一的要求。 在具有checked属性的元素上执行一次“动画”:

input.flipCheckbox[checked]{
  animation-name: fakeRotate;
  animation-duration: 0.1s; 
  animation-iteration-count: 1;
}
@keyframes fakeRotate {
  from {
    transform: rotatey(180deg);
  }
  to {
    transform: rotatey(180deg);
  }
}