본문 바로가기

Develop/Web

css만 사용해서 입력시 버튼이 나타나게 만들기 (feat. :placeholder-shown, peer)

 

 

input 태그가 있는 페이지를 만들다 보면 input 태그에 입력유무에 따라 다른 요소의 css가 변경되게 하고 싶을 때가 있다.

그 때 tailwindcss의 peer 클래스:placeholde-shown 가상 클래스를 함께 응용하여 css만으로 구현할 수 있다.

 

구체적인 예시를 가져왔다.

이메일을 입력할 떄에만 '계속' 버튼이 나타나게 하고싶다.

 

이메일을 '입력하는 칸'과 '계속' 버튼이 있다고 하자.

내가 하고 싶은건 '계속' 버튼은 입력이 없을 때에는 안보이게 하고 싶다.

즉, 사용자가 한글자라도 입력을 할 때 '계속'버튼을 활성화하고 싶다.

 

이 때 tailwindcss의 peer와 가상클래스 :placeholder-shown을 응용하여 구현할 수 있다.


 

먼저 TailwindCSS의 peer로 input 요소의 입력 상태를 관찰하고,

input 요소의 :placeholder-shown 가 아닐 때(:not) CSS 속성을 준다.

 

아래는 input 요소에 peer를 주어 요소의 이벤트를 관찰하고,
button 요소에는 input 요소의 상태 변경을 감지하기 위해 peer-[가상 클래스] 를 사용하였다. 

...
<input type="email" placeholder="이메일을 입력하세요." class="peer ..." value="" />

<button class="opacity-0 peer-[:not(:placeholder-shown)]:opacity-100 ...">계속</button>
...

 

input 요소의 경우 빈칸일 경우 placeholder가 노출 상태가 되고,  -> :placeholder-shown

한 글자라도 입력이 되면 placeholder가 사라진다는 특성이 있다. -> :not(placeholder-shown)

이러한 상태 변경 이벤트를 peer을 통해 캐치할 수 있다.

 

peer의 사용법은 간단하다. peer-[가상클래스] 으로 사용할 수 있다.

즉, peer-[:not(placeholder-shown)] 에 한해 css 속성을 주어 '계속' 버튼이 보이도록 한다.

peer 클래스와 & :placeholder-shown 가상 클래스의 응용한 결과는 다음과 같다.

 

 

input 요소의 상태가 :not(placeholder-shown) 일 때 button의 투명도를 없앴다.

 

 

티스토리에서는 HTML이 예상한대로 랜더링이 되지 않아서,
아래 코드를 https://play.tailwindcss.com/ tailwindcss play 에서 붙여놓기하여 확인하기를 추천한다. 

 

<div class="m-auto flex h-screen min-h-min w-screen min-w-min flex-grow flex-col items-center justify-center">
  <div class="m-4 mt-6">
    <div class="flex h-[56px] w-[380px] flex-row items-center justify-center rounded-[8px] border pl-[18px] has-[:focus]:border-[#09bb1b] has-[:focus]:shadow-sm">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" style="flex-shrink: 0;"><path fill="#8d96a1" d="M3.91 5 3 5.913v12.174l.91.913h16.18l.91-.913V5.913L20.09 5H3.91Zm.91 4.463V6.826h14.36v2.637L12 13.065 4.82 9.463Zm0 1.929v5.782h14.36v-5.782L12 14.993l-7.18-3.601Z" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

      <div class="relative mx-3 flex h-full w-full flex-row items-center justify-center text-[12px]">
        <input type="email" placeholder="이메일을 입력하세요." class="peer w-full border-none  text-[12px] font-semibold text-[#242a30] outline-none"/>

        <button class="h-[40px] w-[52px] rounded-[8px] bg-[#09bb1b] peer- text-white opacity-0 peer-[:not(:placeholder-shown)]:opacity-100">계속</button>
      </div>
    </div>
  </div>
</div>