Только CSS, без перехода на нагрузку

У меня есть настраиваемый флажок, который заполняется переходами для границы, цвета и т.д., а также для 3D-преобразования, чтобы перевернуть его. Если флажок снят, он отлично выглядит и прекрасно переходит между состояниями, однако, если флажку задан атрибут checked на загрузке dom, тогда он должен встать на место, и флажок будет виден на обратной стороне.

введите описание изображения здесь

ПРИМЕЧАНИЕ.. Хотя я связываю 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" />

Ответ 1

Если вы просто хотите скрыть галочку при снятии флажка, то backface-visibility: hidden.

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

Это должно упростить вам многое. Во-первых, вам больше не нужно анимировать цвет галочки прозрачным.

Ответ 2

:focus и :hover pseudo -классы должны хорошо работать для ваших нужд. Просто переместите правило перехода от input.flipCheckbox к новому набору правил:

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

Поскольку флажок не ориентирован на загрузку страницы, переход не происходит, но когда пользователь проверяет флажок, он получает фокус, позволяющий осуществить переход. Единственным недостатком является то, что флажок использует фокус до завершения анимации. Например, когда пользователь слишком быстро использует клавиатуру и вкладки. То, где выполняется :hover. Поскольку :hover применяется к body (html или любой другой родитель будет работать также), пока курсор находится на странице, переход все еще происходит.

Вы можете просто использовать один или другой, но оба вместе охватывают все, кроме того, что курсор находится за пределами страницы, а пользовательские закладки слишком быстро.

Как вы сказали, проблемы не возникают в онлайн-редакторах, но в любом случае полный код.

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"/>

Ответ 3

Вы можете настроить анимацию на элемент, который изменяет состояние элемента с его собственной скоростью.

Трюк здесь - получить анимацию, которая:

  • На самом деле не анимация, в смысле отсутствия значения свойства. Это достигается установкой 2 разных ключевых кадров с одинаковым значением.
  • Такая же анимация как для проверенных, так и для непроверенных состояний. Если мы изменим имя анимации, анимация будет воспроизводиться каждый раз, когда мы меняем состояния. Чтобы это разрешить, я устанавливаю анимацию с двумя разными частями, одна из которых имеет элемент, который вращается, а другой - с элементом, который не вращается. Мы используем одну или другую часть, изменяя направление от нормали к обратному. И установка начальной задержки, которая позволяет использовать только последнюю половину.

Я попытался воспроизвести ваш сценарий с помощью javascript, снова обновив элемент и установив состояние проверки. Я не знаю точно, соответствует ли это этому.

В фрагменте нажмите кнопку, и он будет чередовать рендеринг элемента с нуля, один раз в проверенном состоянии, а другой - в непроверенных

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;
}
.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);
  }
}
<input type="checkbox" class="test" id="test" />
<button onclick="reload()">Load</button>

Ответ 4

Кажется, это ошибка с Chrome/Webkit. По крайней мере, в моей версии Chrome и Safari, у меня есть следующее:

  • Без тега script в теге html или script перед ссылкой css или полностью пустой script, и без каких-либо элементов ввода не происходит перехода на div или другие не входящие элементы.

  • Без тега script в теге html или script перед ссылкой css или полностью пустой script, как только будет один элемент ввода (какой бы тип), тогда все элементы, которые имеют стиль, который не соответствует значению по умолчанию, переходят.

  • Если вы добавите тег script после ссылки css с хотя бы пространством внутри него, то при загрузке какого-либо элемента переход не произойдет.

Итак, похоже, что элементы input запускают какое-то обновление макета, что странно не происходит, когда существует script. Может быть, просто из-за задержки где-то в синтаксическом разборе или в каком-то неправильном месте. По крайней мере, это поведение, которое у меня есть с Chrome и Safari.

Итак, вы можете просто добавить:

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

после элемента link, и вы не получите описанное вами поведение. Это не решение css, но проблема, похоже, не связана с вашим CSS, поэтому я отправляю его в любом случае.

Ответ 5

Нужно ли подключаться к внешней таблице стилей? Вы можете уйти с тегом <style> в самом файле html. Если нет, убедитесь, что <link> находится в заголовке, чтобы он загружался первым, позволяя применять CSS сразу после загрузки страницы.

Ответ 6

Бит хакерский, но удовлетворяет только требованию css. Сделайте одноразовую анимацию элементов с проверенным атрибутом:

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