Dropdown 자바스크립트 없이 만들기(React)
웹사이트를 만들다 보면 드롭다운을 만들일이 많이 있습니다. 네비게이션에 메뉴라던지 필터등 여러가지에 사용이 됩니다. 예전에 드롭다운을 만들때 리액트로 state을 써서 만든 경우가 많이 있었습니다. CSS를 잘 못했던 이유도 있었고 복잡한 경우도 많았기 때문입니다. 최근들어 다시 CSS를 공부하다가 배웠는데 dropdown을 만들 때 그냥 간단한 input과 label만 있으면 되는 것이였습니다.
이번 예제는 리액트를 사용하는데 사실 대부분이 그냥 HTML과 CSS이기 때문에 크게 걱정할 필요는 없습니다. 따라하고 싶으신 분은 맨 끝에 남겨 놓도록 하겠습니다.
dropdown css로 만들기 원리
Label과 input은 id와 for로 연결 될 수 있습니다. 그렇게 연결 됐을 때에 label을 클릭하면 input이 checked로 설정 됩니다. checkbox label을 클릭했을 때 checkbox가 선택되는 것을 많이 보셨을 것입니다.
먼저 크게 html structure를 보도록 하겠습니다. (아이콘을 위해 react-icons를 사용했습니다.)
<div className="container">
<input id="dropdown" type="checkbox" />
<label className="dropdownLabel" for="dropdown">
<div>CSS</div>
<FaAngleDown className="caretIcon" />
</label>
<div className="content">
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
</ul>
</div>
</div>
Dropdown을 박스를 만들기 위해서 div.container를 만들어 주도록 하겠습니다.
.container는 나중에 클릭 했을 때 보여줄 .content가 이상한데로 가지 않도록 position: relative를 주겠습니다.
.container {
min-width: 150px;
box-shadow: 0 4px 5px 0 #00000026;
position: relative;
}
box-shadow를 아주 약하게 줍니다.
그리고 나서 input을 만들어 줍니다. input에 id와 label에 for가 꼭 같아야 됩니다.
<input id="dropdown" type="checkbox" />
<label className="dropdownLabel" for="dropdown">
label을 클릭하면 아래 처럼 checkbox가 선택 되면 반 이상 끝났습니다.
우리는 dropdown에서 checkbox를 보고 싶지 않기 때문에 감춰 주겠습니다.
#dropdown {
left: 0;
visibility: hidden;
position: absolute;
}
dropbox에 title과 아이콘을 양 끝에 배치하기 위해서 flex를 사용합니다.
.dropdownLabel {
display: flex;
justify-content: space-between;
padding: 12px;
}
그리고 이제 드롭박스가 선택 되면 보여줄 박스에 간단하게 css를 적용시켜 줍니다.
.content {
display: none;
position: absolute;
width: 100%;
left: 0;
background: white;
box-shadow: 0 4px 5px 0 #00000026;
}
위에 보시면 일단은 display: none; 나중에 checkbox가 checked로 변경 되었을 때 display를 바꿔서 보여 주도록 하기 위해서 입니다.
position도 나중에 나타 났을때 다른 dom에 자리를 밀어내지 않기 위해서 absolute로 변경 해놓았습니다.
아래 처럼 HTML이 있을 때 css로 label 또는 content를 어떻게 선택 할 수 있을까요?
<input id="dropdown" type="checkbox" />
<label className="dropdownLabel" for="dropdown">
<div>CSS</div>
<FaAngleDown className="caretIcon" />
</label>
<div className="content">
css selector중 하나인 + 로 가능 합니다. +는 바로 붙어 있는 바로 다음에 나오는으로 해석 할 수 있습니다.
만약에 아래와 같이 사용한다면
input + label = input 바로 다음에 label이 있으면 선택해 라는 뜻입니다.
div.content는 label다음에 있으니 아래 처럼 선택 할 수 있습니다.
#dropdown:checked + label + div {
display: block;
border-top: 1px solid #00000026;
}
그리고 아주 작은 에니매이션을 위해서 드롭다운이 선택되면 화살표가 위로 올라가게 만들기 위해서 rotate을 사용 하겠습니다.
.caretIcon {
transition: transform 250ms ease-out;
}
#dropdown:checked + label > .caretIcon {
transform: rotate(-180deg);
}
이제 나머지는 content안에 들어갈 ul, li를 스타일을 조금 입혀 주면 됩니다
.content ul {
list-style-type: none;
padding: 12px;
margin: 0;
}
.content ul li {
margin: 0.8rem 0;
}
프로젝