개발자로 살아남기-캐나다

Dropdown 자바스크립트 없이 만들기(React) 본문

카테고리 없음

Dropdown 자바스크립트 없이 만들기(React)

志者必得 2022. 1. 26. 12:33

웹사이트를 만들다 보면 드롭다운을 만들일이 많이 있습니다. 네비게이션에 메뉴라던지 필터등 여러가지에 사용이 됩니다. 예전에 드롭다운을 만들때 리액트로 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;
}

 

 

 

 

 

 

프로젝

0 Comments
댓글쓰기 폼