텍스트 트렁케이팅

작성일:2024.11.24|수정일:2026.07.07|조회수:5

텍스트 트렁케이팅

박스의 높이를 제한해 두면, 내부 콘텐츠가 많아질수록 넘침(overflow)은 피하기 어렵다. 가장 단순한 해결책은 overflow: hidden이다. 하지만 그렇게만 두면 텍스트가 그냥 잘려 나간다. 사용자는 뒤에 내용이 더 있는지 알기 어렵고, 화면은 어딘가 덜 만든 것처럼 보인다.

텍스트 트렁케이팅(text truncating)은 이 문제를 조금 더 정직하게 처리하는 방법이다. 공간을 넘는 텍스트를 숨기되, 말줄임표()로 “여기서 끝난 것이 아니라 잘린 것”이라는 신호를 준다. 작은 차이처럼 보이지만 카드, 리스트, 테이블처럼 같은 모양의 정보가 반복되는 UI에서는 꽤 중요하다.

한 줄 말줄임

한 줄 텍스트는 CSS만으로 안정적으로 처리할 수 있다. 핵심은 줄바꿈을 막고, 넘치는 부분을 숨긴 뒤, 말줄임표를 표시하는 것이다.

CSS
.text-truncate {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

white-space: nowrap은 텍스트가 다음 줄로 내려가지 않게 만든다. overflow: hidden은 박스를 넘는 부분을 잘라낸다. text-overflow: ellipsis는 잘린 지점에 말줄임표를 표시한다.

이 방식은 카드 제목, 파일명, 테이블 셀, 내비게이션 라벨처럼 한 줄 안에 들어와야 하는 텍스트에 잘 맞는다. 다만 요소에 실제로 제한된 너비가 있어야 한다. 너비가 계속 늘어날 수 있는 상태라면 넘칠 일이 없으므로 말줄임표도 나타나지 않는다.

CSS
.table-cell-title {
  max-width: 16rem;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

text-overflow는 텍스트를 잘라 주는 속성이 아니라, 이미 잘린 텍스트를 어떻게 표시할지 정하는 속성에 가깝다. 그래서 overflowwhite-space 조건이 같이 맞아야 한다.

여러 줄 말줄임

문단이나 카드 설명처럼 여러 줄은 허용하되 일정 줄 수까지만 보여주고 싶은 경우가 있다. 이때는 line-clamp를 생각하게 된다.

CSS
.summary {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

조금 이상해 보이는 조합이다. display: -webkit-box, -webkit-box-orient: vertical, -webkit-line-clamp가 같이 나온다. 이름만 보면 오래된 WebKit 전용 해킹처럼 보이지만, 이 조합은 현재도 여러 줄 말줄임을 위해 널리 쓰이는 방식이고, 명세에서도 레거시 동작으로 정리되어 계속 지원되는 쪽에 가깝다.

표준 속성 이름은 line-clamp다.

CSS
.summary {
  overflow: hidden;
  line-clamp: 3;
}

문제는 아직 이 한 줄만 믿고 쓰기에는 브라우저 지원이 애매하다는 점이다. 그래서 실무에서는 표준 속성을 함께 적더라도 레거시 WebKit 조합을 같이 두는 편이 안전하다.

CSS
.summary {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
}

여기서 overflow: hidden도 거의 같이 써야 한다. 그렇지 않으면 말줄임표는 보이는데 실제 콘텐츠가 박스 밖으로 보이는 식의 이상한 결과를 만날 수 있다.

Tailwind에서는 line-clamp-*

Tailwind를 쓰고 있다면 직접 CSS를 쓰지 않고 line-clamp-* 유틸리티를 사용할 수 있다.

HTML
<p class="line-clamp-3">
  긴 설명 텍스트가 여기에 들어간다. 화면에는 세 줄까지만 보이고, 이후 내용은 말줄임표로 처리된다.
</p>

Tailwind의 line-clamp-3은 대략 다음 CSS를 만든다.

CSS
.line-clamp-3 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

반응형으로 줄 수를 바꾸는 것도 쉽다.

HTML
<p class="line-clamp-2 md:line-clamp-4">
  작은 화면에서는 두 줄, 중간 화면 이상에서는 네 줄까지만 보여준다.
</p>

이미 적용한 말줄임을 특정 구간에서 풀고 싶다면 line-clamp-none을 쓴다.

HTML
<p class="line-clamp-3 lg:line-clamp-none">
  작은 화면에서는 요약하고, 큰 화면에서는 전체 문장을 보여준다.
</p>

줄 수가 변수로 결정되어야 한다면 임의 값이나 CSS 변수를 사용할 수 있다.

HTML
<p class="line-clamp-[5]">
  다섯 줄까지만 보여준다.
</p>

<p class="line-clamp-(--summary-lines)">
  CSS 변수로 줄 수를 정한다.
</p>

이 유틸리티가 편한 이유는 문법을 외우지 않아도 된다는 점이다. 특히 -webkit-box 조합은 매번 손으로 쓰기에는 좀 구리다. 다만 Tailwind를 쓰더라도 실제로 어떤 CSS가 적용되는지는 알고 있어야 디버깅할 때 덜 헤맨다.

접근성: 숨긴 텍스트는 사라진 텍스트가 아니다

트렁케이팅은 시각적인 표현을 줄이는 기술이지, 콘텐츠의 중요도를 낮추는 기술은 아니다. 이 부분을 놓치면 UI는 깔끔해지는데 정보는 애매해진다.

판단 기준은 비교적 단순하다.

가장 흔한 방식은 상세 화면, 펼치기 버튼, 툴팁, aria-label 같은 보조 정보를 제공하는 것이다. 다만 aria-label은 화면에 보이지 않는 이름을 스크린 리더에 제공하는 도구이지, 긴 본문을 몰래 숨겨 두는 저장소가 아니다. 화면을 보는 사용자에게도 전체 텍스트가 필요하다면 시각적으로 확인할 수 있는 방법을 따로 둬야 한다.

HTML
<article class="product-card">
  <h2 class="product-card__title" title="아주 긴 상품명 전체 텍스트">
    아주 긴 상품명 전체 텍스트
  </h2>

  <p class="product-card__description line-clamp-3">
    상품 설명이 길어서 카드에서는 세 줄까지만 보여준다. 자세한 내용은 상세 페이지에서 확인할 수 있다.
  </p>

  <a href="/products/123">상세 보기</a>
</article>

title 속성은 없는 것보다는 낫지만, 모바일과 키보드 사용성까지 생각하면 만능 해결책은 아니다. 중요한 정보라면 “상세 보기”, “더 보기”, 펼침 영역처럼 명확한 UI를 두는 편이 낫다.

HTML
<div class="notice">
  <p id="notice-content" class="line-clamp-2">
    공지 내용이 길어서 목록에서는 두 줄까지만 보여준다. 전체 내용은 펼치기 버튼을 눌러 확인할 수 있다.
  </p>
  <button type="button" aria-expanded="false" aria-controls="notice-content">
    더 보기
  </button>
</div>

버튼을 눌렀을 때 line-clamp를 제거하고 aria-expanded 값을 바꾸면, 시각적으로도 의미적으로도 “접힌 콘텐츠를 펼친다”는 구조가 된다.

어디까지 자를 것인가

트렁케이팅은 레이아웃을 안정적으로 만드는 데 좋지만, 너무 쉽게 쓰면 콘텐츠 설계를 CSS에 떠넘기게 된다. 특히 제목을 한 줄로 자르는 UI는 보기에는 정돈되어도, 사용자가 서로 비슷한 항목을 구분하기 어려워질 수 있다.

내 경우에는 다음 정도를 기준으로 본다.

결국 텍스트 트렁케이팅은 “말줄임표를 어떻게 붙일까”의 문제가 아니라, 제한된 공간에서 어떤 정보를 먼저 보여주고 어떤 정보는 뒤로 미룰지 정하는 문제에 가깝다. CSS는 그 결정을 표현할 뿐이다.

댓글

댓글을 불러오는 중...