[CSS] type이 date인 input의 캘린더 아이콘 커스텀하기

박기영·2023년 6월 17일
2

CSS

목록 보기
8/9
post-custom-banner

팀 프로젝트 도중 input 태그의 typedate로 설정하여 날짜를 입력받는 기능을 만들어야했다.
이 때, 자동으로 브라우저마다 설정된 캘린더 아이콘이 나오게 되는데,
필자는 이를 커스텀하고 싶었다. 그 방법을 알아보자!

준비물

  1. 기존 캘린더 아이콘 대신 사용할 이미지
  2. typedateinput 태그
<input
  type='date'
  placeholder='날짜를 선택해주세요.'
  required
  value={props.date}
  onChange={props.changeHandler}
  id='dateSelect'
  min={props.isFullRange ? undefined : getDate()}
/>

SCSS로 간단하게 해결!

사실 간단하지는 않다.
설정 값에 대한 이유를 주석에 달아 놓았으므로, 읽어 내려가시면 좋을 것 같습니다.

input[type='date'] {
  border: none; // 테두리 설정은 본인 맘대로
  position: relative; // 캘린더 아이콘을 클릭해야만 달력이 보이기 때문에 이 영역 자체를 제어하기 위해 설정 
  width: 100%;
  padding: 10px;
  background: url(../../../assets/Calendar.svg) no-repeat right 10px center /
    35px auto; // 배경에 커스텀 아이콘을 넣어주자! x축은 오른쪽에서부터 10px 떨어지게 하고, y축은 가운데 정렬하고, width 35px에 height auto라는 크기를 부여한다.
  background-color: #bbbbbb;
  box-shadow: 2px 2px 7px rgba(0, 0, 0, 0.2);
  border-radius: 8px;
  text-align: center;
  font-size: 100%;
  margin-bottom: 20px;
}

// 실제 캘린더 아이콘을 클릭하는 영역을 의미하는 선택자
// 이 영역을 확장해서 input의 어떤 곳을 클릭해도 캘린더를 클릭한 것과 같은 효과를 만들자!
input[type='date']::-webkit-calendar-picker-indicator {
  position: absolute; // 이를 설정하기 위해 사전에 relative를 설정한 것이다.
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: transparent; // 배경은 투명하게,
  color: transparent; // 글자도 투명하게! 이 두 설정을 통해 캘린더 아이콘을 사라지게 만든다.
  cursor: pointer;
}

// type이 date인 input의 placeholder를 커스텀하기 위한 선택자
// 기본적으로 type date인 input은 placeholder가 먹히지 않기 때문이다!
input[type='date']::before {
  content: attr(placeholder); // input 태그의 placeholder라는 속성값을 가져와서 content로 사용한다. 보통은 placeholder보다는 data-placeholder라는 커스텀 속성을 만들어서 사용하시는 것 같다.
  width: 100%;
  height: 100%;
}

// input에 어떠한 유효값이 입력된 상태인지 확인하는 선택자
// 날짜를 선택하면 유효값이 입력된다.
// 이 속성을 활용하고자 한다면 반드시 태그에 required 속성을 달아줘야한다.
input[type='date']:valid::before {
  display: none; // 유효값이 입력된 경우 before에 있는 것을 사라지게 한다. 즉, placeholder를 사라지게 한다.
}

결과는 다음과 같다.

참고 이미지

ref를 걸어서 클릭되게 하면 되지않을까?!

평소의 필자였다면 input 태그와 별도의 아이콘 태그를 사용하여 기존 캘린더를 덮었을 것 같은데,
이 방법은 위험하다.

왜?

캘린더 아이콘을 클릭해야 날짜를 선택할 수 있기 때문이다.
그러면 ref 걸어서 클릭되게 하면 해결 할 수 있지않느냐는 질문이 나올 수 있다.(React에서)

그 방법은 통하지 않는다.(매우 어렵다가 더 맞는 표현일 것 같다.)

input을 클릭하는게 아니라 input에 있는 캘린더 아이콘을 클릭해야하는 것이기 때문이다.

JS로 이를 구현하는 것은 매우 어렵게 돌아가는 방법이라고 생각된다.
필자는 CSS로 처리할 수 있는건 최대한 CSS로 처리하는 것을 선호하기 때문에,
굳이 JS를 사용하는 방법으로는 구현하지 않을 것 같다.

참고 자료

리베하얀님 youtube
jobcoding님 블로그
sir 질문글
webruden님 블로그

profile
나를 믿는 사람들을, 실망시키지 않도록
post-custom-banner

4개의 댓글

comment-user-thumbnail
2023년 6월 17일

설명이 너무 깔끔합니다 🥹

1개의 답글
comment-user-thumbnail
2023년 6월 18일

scss type기능 안 써봤는데 저렇게 사용할 수 있군요 배워갑니다!

답글 달기
comment-user-thumbnail
2023년 7월 18일

덕분에 날짜창 깔끔히 바꿀 수 있었습니다 감사합니다!

답글 달기