본문 바로가기
HTML CSS

배경 애니메이션 적용된 Toggle Switch 만들기

by 로터스233 2023. 4. 16.

구현할 예제

 

1. input tag > checkbox 이용

w3school에 들어가면 'How to create a toggle switch'라는 글이 있습니다.

이 글에서 rounded버전과 rectangular 버전을 참고해 만들 수 있습니다.

 

 

라운드를 구현해봅시다!

<!-- Rectangular switch -->
<label class="switch">
  <input type="checkbox">
  <span class="slider"></span>
</label>

<!-- Rounded switch -->
<label class="switch">
  <input type="checkbox">
  <span class="slider round"></span>
</label>

예제와 달리 여기서 만들어볼 토글은 클릭하는 순간 배경색이 왼쪽부터 오른쪽 끝까지 채워지는 애니메이션 효과를 주기로 했어요.

토글 버튼과 별개로 배경처리를 해줘야 해서 span class 2 만들어줍니다.

<div className={styles.toggleSwitch}>
  <input
    type="checkbox"
    className={styles.checkbox}
    id="toggleSwitch"
  />
</div>
  <label className={styles.label} htmlFor="toggleSwitch">
    <span className={styles.toggleInner} />
    <span className={styles.switch} />
  </label>

 

2. CSS

1) ToggleInner CSS

기존의 input checkbox는 dipslay를 없애주고 기능만 남겨놓아야 합니다.

label클래스로 버튼 모양을 잡고, toggleInner와 switch를 배치해줍니다.

 

가장 신경써야 하는 부분은 toggleInner인데, css 가상요소 선택자인 :before, :after를 사용해줘야해요.

이 때 주의해야할 것은 content인데, 내용이 없다고 지워버리면 요소가 아예 사라지게 됩니다.

 

toggleInner 전체 넓이는 토글의 200% 주고 before에는 핑크로, after에은 회색을 적용합니다. checkbox checked 되면 toggleInner 왼쪽으로 100% 가도록하게 만들어줘야 해서 초기값을 margin-left: -100%으로 세팅해줍니다.

.toggleInner {
  display: block;
  width: 200%;
  margin-left: -100%;
}

.toggleInner:before,
.toggleInner:after {
  float: left;
  width: 50%;
  height: 36px;
  padding: 0;
  box-sizing: border-box;
  content: "";
}

.toggleInner:before {
  background-color: pink;
}

.toggleInner:after {
  background-color: #bbb;
}

2) Switch CSS

배경색과 함께 버튼도 움직여야 하니, 스위치 버튼을 만들어줍니다.

.switch {
  display: block;
  width: 24px;
  margin: 5px;
  background: #fff;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 40px;
  border: 0 solid #bbb;
  border-radius: 50%;
 }

3) transition 적용

.checkbox:checked + .label .toggleInner {
  margin-left: 0;
}

.checkbox:checked + .label .switch {
  right: 0px;
}

/* toggleinner와 switch에 적용 */
/* switch의 transition property는 all을 적용 */
transition: margin-left 0.3s ease-in;

4) 완성

컴포넌트 state관리를 통해 text도 변경해줍니다.

  const onChangeText = e => {
    console.log(e.target.checked); // check 확인
    if (e.target.checked === false) {
      setOnOff("OFF");
    } else if (e.target.checked === true) {
      setOnOff("ON");
    }
  };