div에서 placeholder 사용하기 (styled-component)

2022-02-28

요구조건

select에 placeholder를 적용해주세요.

문제점

select가 input 태그로 구현되어있었다면 placeholder속성만 넣으면 간단히 해결 됐겠지만, select는 구현체가 div였다.

div에 placeholder를 어떻게 적용할 수 있을까?

div에 placeholder 적용하기

<Select placeholder={placeholder} />
  • 우선 div로 구현되어있는 컴포넌트에 placeholder 속성을 넣어준다. (속성 이름은 꼭 placeholder가 아니어도 된다.)
<Select placeholder={placeholder} hasValue={!!value} />
  • placeholder는 select에 값이 선택되면 사라져야하므로, hasValue 란 prop을 넘겨준다.
${({ hasValue, placeholder }) =>
    !hasValue &&
    placeholder &&
    css`
      &:before {
        content: attr(placeholder);
        color: gray;
      }
    `}
  • hasValue가 없으면서 placeholder가 있을때만 보여야하므로 styled-component 내에서 분기처리를 한다.

  • 가상요소 before와 속성을 가져오는 함수인 attr을 이용해 placeholder를 적용한다.

  • 하지만 select의 영역을 다 차지하는 것이 아니라 일부만 차지하고 있다.
${({ hasValue, placeholder }) =>
    !hasValue &&
    placeholder &&
    css`
      &:before {
        content: attr(placeholder);
        color: gray;
        white-space: nowrap;
        width: 100%;
      }
    `}
  • 해결을 위해 width에 100%값을 주고, white-space: nowrap; 속성을 추가한다.

::before

::before

::before는 선택한 요소의 첫 자식으로 요소를 생성한다.

예를 들어서 설명하자면, 다음과 같은 span태그가 있다고 하자.

<span class="text">텍스트</span>
.text::before {
  content: "♥";
}

span 앞에 하트를 추가하면 다음과 같이 보여지게 된다.

attr()

attr()는 요소의 속성 값을 문자열로 반환하는 함수이다.

요소에 속성 값이 없으면 빈 문자열이 반환된다.

위의 예제에서 placeholder란 속성을 추가하고 내용을 입력해보자.

<span class="text" placeholder="placeholder">텍스트</span>
.text::before {
  content: attr(placeholder);
}

placeholder의 내용을 가져올 수 있다.