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");
}
};