单选按钮上的动态css动画

时间:2018-04-12 04:31:51

标签: html css radio-button

是否可以让.switch__indicator覆盖每个label,而无需为.switch容器设置固定宽度?

我使用translate3d,但这需要我设置容器的宽度,我希望保持动态。



.wrap {
  display: flex;
}

.switch {
  position: relative;
  width: auto;
  padding: 0 1rem;
}

.switch:before {
  content: '  ';
  position: absolute;
  left: 0;
  z-index: -1;
  width: 100%;
  height: 3rem;
  border: 2px solid #eee;
  border-radius: 30px;
}

.switch__label {
  display: inline-block;
  width: 2rem;
  border: 3px solid;
  padding: 1rem;
  text-align: center;
  cursor: pointer;
  transition: color 200ms ease-out;
}

.switch__indicator {
  width: 4rem;
  height: 4rem;
  position: absolute;
  top: -.5rem;
  left: 0;
  background: green;
  border-radius: 50%;
  transition: transform 600ms cubic-bezier(0.02, 0.94, 0.09, 0.97), background 300ms cubic-bezier(0.17, 0.67, 0.14, 1.03);
  transform: translate3d(1rem, 0, 0);
}

.switch input#one:checked~.switch__indicator {
  transform: translate3d(1.2rem, 0, 0);
}

.switch input#two:checked~.switch__indicator {
  transform: translate3d(5.5rem, 0, 0);
}

.switch input#three:checked~.switch__indicator {
  transform: translate3d(9.6rem, 0, 0);
}

.switch input#four:checked~.switch__indicator {
  transform: translate3d(14rem, 0, 0);
}

.switch input[type="radio"]:not(:checked),
.switch input[type="radio"]:checked {
  display: none;
}

<div class="wrap">
  <div class="switch">
    <input id="one" type="radio" name='thing' value='a' checked="checked" />
    <label for="one" class="switch__label">One</label>

    <input id="two" type="radio" name='thing' value='b' />
    <label for="two" class="switch__label">Two</label>

    <input id="three" type="radio" name='thing' value='c' />
    <label for="three" class="switch__label">Three</label>

    <input id="four" type="radio" name='thing' value='d' />
    <label for="four" class="switch__label">Four</label>

    <div class="switch__indicator"></div>
  </div>
</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:3)

计算标签之间的确切空间有点困难,因为label是内联元素,它们周围有空格要对齐,所以最好在这里使用flexbox删除空格,然后使用{ {1}}在它们之间留出空间。

现在,您需要计算确切的margin值,该值将是translateX值,border标签和它们之间的width值的总和。

此外,您不需要margin,只需使用translate3d并使用translateX来计算确切的空间量。

calc()
.wrap {
  display: flex;
}

.switch {
  position: relative;
  width: auto;
  padding: 0 1rem;
  display: flex;
}

.switch:before {
  content: '  ';
  position: absolute;
  left: 0;
  z-index: -1;
  width: 100%;
  height: 3rem;
  border: 2px solid #eee;
  border-radius: 30px;
}

.switch__label {
  display: inline-block;
  width: 2rem;
  border: 3px solid;
  padding: 1rem;
  text-align: center;
  cursor: pointer;
  transition: color 200ms ease-out;
  margin-right: 4px;
}

.switch__indicator {
  width: 4rem;
  height: 4rem;
  position: absolute;
  bottom: 0;
  left: 0;
  background: green;
  border-radius: 50%;
  transition: transform 600ms cubic-bezier(0.02, 0.94, 0.09, 0.97), background 300ms cubic-bezier(0.17, 0.67, 0.14, 1.03);
  transform: translate3d(1rem, 0, 0);
}

.switch__label:last-of-type {
  margin-right: 0;
}

.switch input#one:checked~.switch__indicator {
  transform: translateX(calc(1rem + 3px));
}

.switch input#two:checked~.switch__indicator {
  transform: translateX(calc(5rem + 13px));
}

.switch input#three:checked~.switch__indicator {
  transform: translateX(calc(9rem + 23px));
}

.switch input#four:checked~.switch__indicator {
  transform: translateX(calc(13rem + 33px));
}

.switch input[type="radio"]:not(:checked),
.switch input[type="radio"]:checked {
  display: none;
}