위와 같은 커스텀 체크박스 인풋을 만들어보자.
일단 내가 세운 구조는 다음과 같다.
- 부모 : div (조정)
- 자식1 : input : checkbox (터치영역)
- 자식2 : label (스타일링)
모든 스타일을 자식2인 label 에 주고,
input 과 label을 감싼 div 를 통해
input의 크기를 키워 체크 터치영역을 늘리고,
input이 체크 됐을 때, label의 스타일 값 변경을 조정한다.
styled component 를 사용할 때는 부모 컴포넌트가
자식 요소들을 하위 스타일로 내려받을 수 있다.
내가 짠 코드의 구조는 아래와 같다.
input 체크박스의 position을 absolute로 하고,
input 체크박스의 너비와 높이를, label의 크기에 맞춰진, div 영역의 100%로 설정해주어서
div, input, label 모두가 같은 크기와 영역으로 딱 겹쳐지도록 해주었다.
그리고 나중에 input 의 opacity를 0%로 설정해주면,
터치영역은 유지되면서 기본 체크박스는 보이지 않게된다.
물론 위의 방법이 정답이라거나, 가장 깔끔한 방법은 아닐 수 있지만,
커스텀 인풋이 필요한 경우가 종종 있어 스니펫을 남겨둔다.
참고로, 아래의 코드는 리액트 타입스크립트로 작성했다.
import styled from 'styled-components';
const CustomTag = ({ children }: { children: string }) => {
return (
<TagWrapper>
<input type="checkbox" id="tagInput" />
<TagLabel htmlFor="tagInput">{children}</TagLabel>
</TagWrapper>
);
};
export default CustomTag;
const TagWrapper = styled.div`
height: fit-content;
position: relative;
input[type='checkbox'] {
position: absolute;
width: 100%;
height: 100%;
opacity: 0%;
margin: 0px;
}
input[type='checkbox']:checked + label {
background-color: #62ffa1;
box-shadow: none;
}
`;
const TagLabel = styled.label`
display: none;
margin: 0px;
display: flex;
justify-content: flex-start;
align-items: center;
height: 32px;
padding: 16px;
box-shadow: 0px 0px 8px 0px #8d8d8d40;
border-radius: 10px;
:hover {
cursor: pointer;
}
`;