본문으로 건너뛰기
Chloe
chloe
글로그인
OverviewPostsPlayground

© 2026 Hyunjoo. Built with Next.js

← 글 목록
2026.04.26

white-space: nowrap; 한 줄로 고친 UI를 보며 든 생각

cssfrontenduiinstagram
조회3

white-space: nowrap

어느 날처럼 생산적인걸 한다고 노트북 킨다음 인스타그램을 보다가 숫자가 두 줄로 떨어진 UI를 봤다.

no wrap example 1

좋아요 수가 27.3만으로 보여야 하는데, 화면에서는 27.3과 만이 줄바꿈되어 있었다. 기능이 깨진 건 아니지만 개발자 입장에서는 이런 작은 깨짐이 꽤 오래 눈에 남는다.

개발자 도구를 열어보니 해당 숫자는 span 안에 있었고, 스타일에 white-space: nowrap;을 추가하니 바로 해결됐다.

.like-count {
  white-space: nowrap;
}

no wrap example 2

표면적으로는 간단한 문제다. 하지만 이런 걸 보면 여러 생각이 같이 든다.

"메타 개발자도 실수하네"라는 생각

이 생각은 꽤 위험하다.

회사 이름이 개인의 실력을 완전히 대변하지는 않는다. 물론 좋은 회사일수록 채용 허들이 높고, 그만큼 평균적인 역량도 높을 가능성이 크다. 하지만 그렇다고 해서 모든 UI 상태를 완벽하게 검증할 수 있는 건 아니다.

프론트엔드에서 특히 이런 문제는 실력 부족이라기보다 조합의 문제에 가깝다.

  • 특정 언어

  • 특정 숫자 단위

  • 특정 화면 너비

  • 특정 폰트 렌더링

  • 특정 실험군

  • 특정 CSS 변경의 사이드 이펙트

이 조건들이 겹치면 평소에는 보이지 않던 UI 깨짐이 나온다.

이번 경우도 영어권 UI에서는 잘 드러나지 않았을 수 있다. 27.3K, 1.1K 같은 표기는 짧고 한 덩어리처럼 보인다. 반면 한국어에서는 27.3만, 1.1천처럼 숫자와 단위가 붙는다.

브라우저는 레이아웃 제약이 걸리면 줄바꿈 가능한 지점을 찾는다. 이때 숫자와 단위가 의미상 한 덩어리라고 해서 브라우저가 항상 그렇게 취급해주지는 않는다.

그래서 이런 UI에는 명시적인 스타일이 필요하다.

.countText {
  white-space: nowrap;
}

white-space: nowrap은 텍스트 내부 줄바꿈을 막는다. 좋아요 수, 가격, 날짜, 사용자명, 짧은 라벨처럼 의미상 한 덩어리인 텍스트에는 자주 필요한 속성이다.

왜 놓쳤을까

이런 버그를 보면 담당자가 궁금해진다.

이걸 담당한 사람은 어떡하지? 심장 달달 떨릴까? ㅜ

no wrap example 2


왜 놓쳤을까?
배포 전에 안 보였을까?

아마 안 보였을 가능성이 높다. (아마도 ?.. 나도 모름)

대부분의 UI 테스트는 대표 케이스를 기준으로 돈다. 영어, 기본 화면 너비, 대표 계정, 대표 데이터. 하지만 실제 서비스는 훨씬 더 많은 변수를 가진다.

좋아요 수 UI만 봐도 조건이 생각보다 많다.

function LikeCount({ count, locale }: Props) {
  return <span>{formatCompactNumber(count, locale)}</span>;
}

처음에는 이렇게 충분해 보인다. 하지만 실제로는 formatCompactNumber의 결과가 로케일마다 달라진다.

formatCompactNumber(273000, "en"); // "273K"
formatCompactNumber(273000, "ko"); // "27.3만"

문제는 데이터 포맷팅만 로케일 대응을 한다고 끝이 아니라는 점이다. 포맷된 문자열이 UI에서 어떻게 줄바꿈되는지도 같이 봐야 한다.

그래서 더 안전하게는 이런 식으로 의미를 드러낼 수 있다.

function CompactCount({ value, locale }: Props) {
  return (
    <span className="compactCount">
      {formatCompactNumber(value, locale)}
    </span>
  );
}
.compactCount {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

font-variant-numeric: tabular-nums까지 쓰면 숫자의 폭이 일정해져서 좋아요 수, 조회 수, 통계 값처럼 숫자가 반복되는 UI에서 흔들림을 줄일 수 있다.

모든 경우에 필수는 아니지만, 수치 UI에서는 꽤 유용하다.

작은 CSS 수정이지만 원인은 작지 않을 수 있다

white-space: nowrap 한 줄이면 고쳐지는 문제라고 해서 원인도 단순하다고 보기는 어렵다.

프론트엔드에서 줄바꿈 문제는 보통 레이아웃 정책과 함께 봐야 한다.

.actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

.count {
  white-space: nowrap;
}

하지만 부모가 flex라면 또 다른 조건도 필요할 수 있다.

.count {
  white-space: nowrap;
  flex-shrink: 0;
}

white-space: nowrap은 텍스트 내부 줄바꿈을 막지만, flex item 자체가 줄어드는 것까지 항상 원하는 방식으로 막아주지는 않는다. 주변 아이콘, gap, 컨테이너 너비, min-width, overflow 정책에 따라 다른 깨짐이 생길 수 있다.

즉, "줄바꿈만 막자"가 아니라 이 텍스트가 레이아웃 안에서 어떤 성격인지 정해야 한다.

  • 숫자와 단위는 한 덩어리인가?

  • 줄어들어도 되는가?

  • 넘치면 잘라야 하는가?

  • 아이콘보다 우선순위가 높은가?

  • 모바일과 데스크톱에서 같은 규칙을 가져도 되는가?

이 질문에 답하지 않고 CSS 한 줄만 넣으면 다른 곳에서 또 사이드 이펙트가 날 수 있다.

이런 건 언제 수정될까

두 번째로 궁금한 건 이거였다.

이런 건 언제 수정될까?

아마 우선순위는 낮을 것이다. 기능 장애도 아니고, 결제 문제도 아니고, 접근을 막는 버그도 아니다. 하지만 브랜드가 큰 서비스일수록 이런 작은 디테일도 눈에 띈다.

수정 과정은 생각보다 단순하지 않을 수 있다.

  1. 누군가 이슈를 발견한다.

  2. 재현 조건을 찾는다.

  3. 어떤 로케일과 화면에서 발생하는지 확인한다.

  4. 관련 컴포넌트가 공통 컴포넌트인지 확인한다.

  5. nowrap을 넣었을 때 다른 언어에서 깨지지 않는지 본다.

  6. 배포 실험이나 디자인 시스템 영향 범위를 확인한다.

  7. 수정한다.

사용자 눈에는 "CSS 한 줄이면 되는데?"처럼 보이지만, 대규모 서비스에서는 그 한 줄이 여러 화면에 퍼질 수 있다. 공통 컴포넌트라면 좋아요 수뿐 아니라 댓글 수, 공유 수, 조회 수에도 영향을 줄 수 있다.

그래서 작은 UI 버그도 결국 시스템의 문제다. 코드 한 줄의 문제가 아니라, 그 한 줄이 들어가야 할 위치를 찾는 문제에 가깝다.

이번 일에서 가져갈 것

이번에 다시 느낀 건 숫자 UI는 생각보다 깨지기 쉽다는 점이다.

특히 다음과 같은 값은 하나의 토큰처럼 다뤄야 한다.

.metric,
.price,
.date,
.username,
.compactNumber {
  white-space: nowrap;
}

그리고 로케일이 들어가는 UI라면 영어 기준으로만 보지 않는 게 좋다.

const locales = ["en", "ko", "ja", "de", "fr"];

한국어의 만, 일본어의 万, 독일어의 긴 단어, 프랑스어의 공백 규칙처럼 문자열은 언어마다 다른 방식으로 레이아웃을 흔든다.

결국 프론트엔드에서 디테일은 "보기 좋은가"보다 "어떤 조건에서도 의도대로 버티는가"에 가깝다.

white-space: nowrap 한 줄을 넣으면서 끝난 일이지만, 그 뒤에는 로케일, flex 레이아웃, 숫자 포맷팅, 회귀 테스트, 사이드 이펙트 같은 주제가 붙어 있었다.

작은 깨짐을 보고 남을 평가하는 건 쉽다. 하지만 개발자로서 더 유용한 질문은 따로 있다.

나는 이걸 내 코드에서 어떻게 예방할 수 있을까?

댓글

0/1000