본문 바로가기
Frontend2026년 8월 11일5분 읽기

field-sizing: content — JS 없이 입력창을 내용에 맞춰 늘리기

YS
김영삼
조회 8
field-sizing: content — JS 없이 입력창을 내용에 맞춰 늘리기

field-sizing: content<textarea><input>이 안에 든 내용에 맞춰 크기를 자동으로 조절하게 만드는 CSS 속성이다. 자바스크립트로 스크롤 높이를 재서 높이를 다시 세팅하던 그 흔한 코드를, CSS 한 줄로 대체한다.

채팅 입력창, 댓글 상자, 인라인 편집 필드… "내용이 늘면 칸도 같이 늘어나는" 그 동작. 나는 이걸 위해 매번 onInput에서 scrollHeight를 읽어 높이를 조정하는 코드를 복붙해왔다. 이제 그럴 필요가 없다.

기존 방식의 번거로움

textarea는 기본적으로 고정 높이다. 내용이 넘치면 스크롤바가 생길 뿐 스스로 늘어나지 않는다. 그래서 다들 이런 코드를 썼다.

function autoGrow(el) {
  el.style.height = 'auto'            // 먼저 줄이고
  el.style.height = el.scrollHeight + 'px'  // 실제 높이로
}
textarea.addEventListener('input', () => autoGrow(textarea))

동작은 한다. 그런데 함정이 많다. box-sizing에 따라 border·padding을 더해줘야 하고, 초기 렌더와 창 크기 변경 때도 다시 호출해야 하고, React라면 리렌더 타이밍과 엇갈려 깜빡이기도 한다. 몇 번 데인 뒤엔 "이걸 CSS가 좀 해줬으면" 싶었다.

이제는 CSS 한 줄

textarea {
  field-sizing: content;
  min-height: 3lh;   /* 최소 3줄 */
  max-height: 12lh;  /* 최대 12줄, 넘으면 스크롤 */
}

이게 전부다. 입력 이벤트도, scrollHeight 계산도 없다. 브라우저가 내용 길이에 맞춰 필드를 늘리고 줄인다. min-height·max-height로 범위를 잡아두면, 최댓값을 넘겼을 때 비로소 스크롤바가 생긴다. 여기서 lh 단위(줄 높이)를 쓰면 "몇 줄"을 직관적으로 지정할 수 있어 궁합이 좋다.

input과 select에도 먹는다

textarea만이 아니다. 한 줄 <input>은 입력한 텍스트 길이에 맞춰 가로로 늘고, <select>는 선택된 옵션 폭에 맞춰진다. 태그 입력 UI나 인라인 편집처럼 "글자 수만큼만 차지했으면" 하는 곳에 잘 맞는다.

요소content일 때 동작
textarea내용 줄 수에 맞춰 세로로 확장
input[type=text]입력 길이에 맞춰 가로로 확장
select선택된 옵션 폭에 맞춤

실무 팁과 함정

  • min/max로 반드시 경계를 잡아라. 안 잡으면 아주 긴 입력에 필드가 화면을 뚫고 늘어난다. textarea엔 max-height, 가로로 늘어나는 input엔 max-width가 안전벨트다.
  • rows·cols 속성과 공존. rows는 여전히 초기 높이 힌트로 작동한다. 다만 min-height를 함께 주는 편이 예측 가능하다.
  • 진보적 향상으로 접근. 미지원 브라우저에선 그냥 고정 높이 필드로 보일 뿐 기능이 깨지진 않는다. 중요한 UX라면 기존 JS 폴백을 병행하되, 지원 브라우저에선 CSS가 우선하게 둔다.
  • 애니메이션. 늘어날 때 자연스럽게 하려면 별도 트랜지션 처리가 필요할 수 있다. 기본은 즉시 반영이다.
개인적으로 가장 반가운 건 React에서의 해방이다. 제어 컴포넌트로 만든 textarea의 높이를 상태·ref·useEffect로 관리하던 코드가 통째로 사라진다. 렌더 타이밍과 싸울 일이 없어진다.

정리하면

과하게 요란한 기능은 아니다. 그런데 프론트엔드에서 지겹도록 반복하던 "자동 확장 입력창" 문제를 딱 필요한 만큼 표준으로 풀어준다. 새 프로젝트라면 자동 확장 textarea에 일단 이걸 먼저 얹어보고, 폴백이 필요한 환경에서만 JS를 덧대는 순서를 권한다.

자주 묻는 질문

field-sizing의 기본값은 무엇인가요?

기본값은 fixed로, 요소가 기존처럼 고정 크기를 유지합니다. 자동 확장을 원할 때만 content로 바꿉니다.

max에 도달하면 어떻게 되나요?

max-height(또는 max-width)에 닿는 순간부터는 더 늘지 않고 내부 스크롤이 생깁니다. 그래서 경계값을 지정해두는 게 좋습니다.

JS 자동 확장 코드는 이제 다 지워도 되나요?

지원 브라우저만 대상이라면 지워도 됩니다. 다만 폭넓은 호환이 필요하면 미지원 환경을 위해 기존 방식을 폴백으로 남겨두고 기능 감지로 분기하세요.

lh 단위는 꼭 써야 하나요?

필수는 아닙니다. px로 min/max를 줘도 됩니다. 다만 lh는 "몇 줄"을 직관적으로 표현해 줄 수 기반 제한과 잘 어울립니다.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록