truncate와 line-clamp, 말줄임이 안 먹을 때 뭘 봐야 할까?

truncate와 line-clamp, 말줄임이 안 먹을 때 뭘 봐야 할까?

June 26, 2026

truncateline-clamp은 둘 다 넘치는 텍스트를 로 줄이는 Tailwind 유틸이지만, 동작 기반이 다릅니다.

그래서 flex 같은 레이아웃과 같이 쓰면 에러도 없이 조용히 안 잘리는 경우가 생깁니다.

두 유틸이 뭐가 다른지, 말줄임이 의도대로 안 먹을 때 어디부터 확인해야 하는지 정리합니다.

두 유틸은 동작 원리가 다릅니다

이름은 비슷하지만, 실제로 생성되는 CSS를 보면 기반이 다릅니다.

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

/* line-clamp-1 */
.line-clamp-1 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
}

truncatewhite-space: nowrap으로 줄바꿈을 막고, 넘치는 부분을 text-overflow: ellipsis로 자릅니다. 한 줄 전용이고, display는 건드리지 않습니다.

line-clamp은 여러 줄을 자를 수 있는 대신, display: -webkit-box라는 옛날 webkit 박스 모델 위에서만 동작합니다. N줄 말줄임이 그 위에 구현돼 있기 때문입니다.

한 줄(line-clamp-1)도 되지만, 이걸 쓰는 순간 그 엘리먼트의 display를 차지한다는 게 핵심입니다.

webkit 박스 모델(-webkit-box)이란?
지금 쓰는 display: flex가 표준이 되기 전, 2009년경 webkit이 먼저 구현한 1세대 플렉스 레이아웃입니다. 표준에서는 밀려났지만 -webkit-line-clamp(여러 줄 말줄임)이 이 박스 모델 위에 얹혀 있어서, 지금도 N줄 말줄임을 쓰려면 display: -webkit-box를 함께 선언해야 합니다. 표준은 아니지만 모든 주요 브라우저가 지원합니다.

truncateline-clamp-N
줄 수한 줄만N줄 (1줄 포함)
핵심 속성white-space: nowrap + text-overflowdisplay: -webkit-box + -webkit-line-clamp
display 점유안 함함 (-webkit-box)
동작 기반블록 안 인라인 텍스트webkit 박스 모델

한 줄이면 둘 다 됩니다. 하지만 여러 줄을 자르려면 line-clamp뿐이고, 그 대가로 display를 내줘야 합니다.

바로 이 점이 flex와 충돌하는 지점입니다.

안 잘릴 때 1순위: 같은 엘리먼트의 display

가장 흔한 경우가 line-clampflex를 같은 엘리먼트에 준 것입니다.

<span className="... flex items-center line-clamp-1">{label}</span>

이러면 line-clamp-1을 붙여도 안 잘립니다. flexdisplay: flex를 선언하고, line-clampdisplay: -webkit-box를 깔고 동작합니다.

display는 값이 하나뿐이라 두 선언이 같은 속성을 두고 경합하고, 보통 뒤에 선언된 쪽이 적용되면서 -webkit-box가 사라집니다. line-clamp이 기대던 기반이 없어지니 에러도 없이 조용히 무력화됩니다.

충돌이라기보다 “같은 display를 다른 값으로 덮어쓴” 것입니다.

flowchart TD
    A["한 엘리먼트에 line-clamp + flex"] --> B["line-clamp → display: -webkit-box"]
    A --> C["flex → display: flex"]
    B --> D["display 값은 하나뿐, 뒤 선언이 이김"]
    C --> D
    D --> E["-webkit-box 제거 → 말줄임 무력화"]

truncate로 바꿔도 flex 컨테이너에 직접 주면 마찬가지입니다. text-overflow: ellipsis는 블록 안에서 넘치는 인라인 텍스트를 자르는데, display: flex가 되면 자식이 flex item으로 배치되어 ellipsis 적용 대상에서 빠집니다.

그래서 말줄임이 안 먹으면 같은 엘리먼트에 display를 바꾸는 다른 유틸이 있는지부터 봅니다. flex, grid가 대표적입니다.

해결은 레이어를 나누는 것

원인이 “한 엘리먼트가 display를 두 용도로 못 쓴다”는 것이라면, 해결도 단순합니다.

바깥은 레이아웃(flex)을 맡고, 안쪽 별도 span이 말줄임을 맡도록 역할을 나눕니다.

flowchart TD
    O["바깥 span · flex items-center · min-w-0 (레이아웃 담당)"] --> I["안쪽 span · truncate (말줄임 담당)"]
    I --> T["텍스트를 … 로 자름"]
<span className="... flex items-center min-w-0">
  <span className="truncate" title={label}>
    {label}
  </span>
</span>
  • 바깥 span: flex items-center로 세로 중앙 정렬 유지
  • 안쪽 span: truncate로 말줄임, title로 hover 시 전체 텍스트

여기서 flex item의 최소 너비도 같이 봐야 합니다.

flex item은 기본값이 min-width: auto라 콘텐츠의 min-content 아래로는 안 줄어듭니다. 긴 텍스트가 셀을 무시하고 밀고 나가서 애초에 overflow가 안 생깁니다.

푸는 방법은 둘입니다.

  1. 바깥에 min-w-0(min-width: 0)을 줘서 줄어들 수 있게 한다.
  2. 스펙상 flex item의 overflowvisible이 아니면 자동 최소 너비가 0이 됩니다(CSS Flexbox §4.5). truncateoverflow: hidden이 들어있으니, 안쪽 truncate span 자체가 이미 이 조건을 충족합니다.

즉 안쪽 truncate만으로도 동작하고, 바깥 min-w-0은 굳이 없어도 됩니다.

정리하기

  • 한 줄이면 truncate, 여러 줄이면 line-clamp-N. 한 줄은 둘 다 되지만 line-clampdisplay를 차지한다는 비용이 있습니다. 참고로 -webkit-box는 표준이 아니라 벤더 프리픽스로 굳어진 구현이고, 여러 줄 말줄임은 이 방식에 의존합니다.
  • 말줄임이 에러 없이 안 먹으면, 같은 엘리먼트에 flex·grid처럼 display를 바꾸는 유틸이 있는지부터 의심하세요.
  • 해결은 레이어 분리입니다. 바깥은 레이아웃, 안쪽은 말줄임으로 역할을 나눕니다. flex 안에서 너비가 안 줄면 min-w-0도 같이 봅니다.
On this page