줄바꿈 스타일에 대한 A to Z: 공백 문자편

앞서 줄바꿈 스타일에 대한 A to Z: 다국어편에서 줄바꿈에 대한 기본 이해와 SmartEditor에서 발생한 다국어 텍스트의 줄바꿈 이슈와 관련된 word-breakoverflow-wrap 스타일 속성에 대해 자세히 이야기했습니다. 이번 글에서는 언어에 상관없이 공통적으로 사용되는 “공백 문자”의 줄바꿈을 다루는 white-space 스타일 속성에 대해 알아보겠습니다. 

언급된 3가지 속성 모두 텍스트의 줄바꿈을 처리하는 속성이지만 각기 다른 기능을 갖고 있습니다. 이전 글에서 소개한  word-breakoverflow-wrap 은 단어 단위에서의 줄바꿈 처리를 다루는 속성으로, 단어가 너무 길어 영역을 벗어나는 경우 단어를 어떤 기준으로 자동 줄바꿈 할지를 결정합니다. 반면, 이번 글에서 소개할 white-space 는 텍스트 노드 내의 공백과 줄바꿈 처리를 다루는 속성으로 텍스트 내에서 공백, 탭, 줄바꿈 등의 여러 가지 공백 문자를 어떻게 처리할지를 결정합니다.

SmartEditor 와 같은 많은 WYSIWYG 에디터에서는 다국어 텍스트뿐만 아니라 공백 문자를 어떻게 처리할지에 대한 여러 고민과 이슈를 갖고 있습니다. 지금부터 공백문자와 줄바꿈 스타일에 대해 A부터 Z까지 깊게 알아봅시다.

1. 공백 문자 줄바꿈 속성

공백문자를 다루는 CSS 속성인 white-space  속성과 값에 대해 먼저 자세히 알아봅시다.

1) white-space 속성

HTML 요소 내에 있는 스페이스, 탭, 줄바꿈 등의 여러 가지 공백 문자를 어떻게 처리할지 정의합니다. 공백 문자가 여러 개 있을 때 공백 축소 여부 및 방법, 줄바꿈 여부 2가지를 지정합니다.

✔️ 속성값

속성값설명
normal (기본값)연속된 공백 문자를 하나로 합치고, 줄바꿈 문자도 공백으로 취급
* 소프트 랩 기회(soft wrap opportunity)에서 줄바꿈
nowrap 연속된 공백 문자를 하나로 합치고, 줄바꿈 문자도 공백으로 취급
* 강제 줄 바꿈(forced line break)만 줄바꿈
pre 연속된 공백 문자, 줄바꿈 문자 모두 유지
* 강제 줄 바꿈(forced line break)만 줄바꿈
pre-wrap 연속된 공백 문자, 줄바꿈 문자 모두 유지
* 소프트 랩 기회(soft wrap opportunity)에서 줄바꿈
pre-line 연속된 공백 문자를 하나로 합치고, 줄바꿈 문자는 유지
* 소프트 랩 기회(soft wrap opportunity)에서 줄바꿈
break-spaces pre-wrap 과 유사하나, 연속 공백에 대한 처리가 일부 다름
* 연속된 공백이 줄 끝에 위치하더라도 공간을 차지하고, 연속된 공백의 중간과 끝에서도 자동으로 줄바꿈 가능
* 유지된 연속 공백은 pre-wrap 과 달리 요소 바깥으로 넘치지 않으며, 공간도 차지하므로 박스의 본질 크기에 영향을 줌

See the Pen white-space by S.Young (@s_young) on CodePen.

브라우저 지원범위는 아래 링크를 참고하세요.

white-space 의 속성값들 대부분 브라우저 지원범위가 넓습니다.
하지만 break-spaces는 상대적으로 지원 범위가 적기 때문에 브라우저 호환성을 고려해야 합니다.
🔗 https://caniuse.com/?search=white-space

줄바꿈 스타일에 대한 A to Z: 다국어편 다시 보기: 소프트 랩 기회와 강제 줄바꿈

  • 소프트 랩 기회 (soft wrap opportunity)
    : 텍스트 라인이 한 줄에 들어갈 수 없을 때 텍스트 라인을 자동으로 분할하는 위치를 의미합니다
  • 강제 줄바꿈 (forced line break)
    : <br/> 태그를 사용하여 줄바꿈을 강제로 수행하는 방법입니다.

일반적으로 HTML에서 텍스트 라인이 너무 길어져서 화면에 표시할 수 없을 때, 소프트 랩 기회(soft wrap opportunity)에 해당하는 지점에서 자동으로 줄바꿈 됩니다.
그러나 강제 줄바꿈(forced line break)하면 브라우저가 줄바꿈을 수행하지 않기 전에 먼저 강제로 줄바꿈을 실행할 수 있습니다.

white-space 각 속성값들의 소프트 랩 기회에서 줄바꿈 여부를 잘 기억하세요.
소프트 랩 기회에서 줄바꿈 되지 않는 속성값에서는 이전 다국어 편에서 다룬 스타일 속성이 동작하지 않는 특징이 있습니다.

( 어떤 속성값이 예상대로 동작하지 않는지는 뒤에서 자세히 알아봅시다. 🔜)

✔️ 기본값이 다른 태그: <pre>, <textarea>

white-space  속성의 기본값은 모든 문서 공백 문자(스페이스, 탭, 줄바꿈 문자)를 축소하는 normal 이지만, 대부분의 브라우저에서 <pre><textarea> 태그의 기본 스타일을 문서 공백 문자를 축소하지 않고 유지하는 다른 속성값으로 다시 정의합니다.  아래 이미지와 같이 브라우저 대부분은 <pre>white-space: pre 를, <textarea>white-space: pre-wrap 을 사용자 에이전트 스타일로 갖고 있습니다.

브라우저별 <pre>, <textarea> 태그의 white-space 사용자 에이전트 스타일 비교

2. 공백 문자의 종류

white-space  속성은 공백 문자의 종류에 따라 다르게 동작합니다. 그러므로 어떤 공백 문자를 쓰느냐에 따라 예상치 못한 결과를 초래할 수 있기 때문에 공백 문자를 신중하게 다루어야 합니다.

공백 문자의 종류는 2가지로 나뉘며, 달리 지정된 경우를 제외하고 CSS의 공백 처리는 문서 공백 문자(document whitespace character)에만 영향을 미칩니다.

  • 문서 공백 문자 (document whitespace character)
    : 다음 3가지 공백 문자를 의미합니다.
    1. 공백(U+0020, space)
    2. 탭(U+0009, tab)
    3. 세그먼트 분리자(segment break) – ex) 줄바꿈 문자(U+000A, newlines)
  • 다른 공백 구분자 (other space separator)
    : 이미 기본 공백으로 정의된 것 외에 유니코드로 정의된 다른 공백 구분 기호

공백문자의 다양성

space, tab, non-breaking space(&nbsp;) 등 익숙한 공백 문자 외에도 다양한 공백 문자들이 있습니다. 아래 링크를 참고해 주세요.
🔗 https://en.wikipedia.org/wiki/Whitespace_character#Unicode

아래 화면을 통해 white-space 속성이 문서 공백 문자(space, tab)다른 공백 구분자(&nbsp;, &emsp;) 각각 어떤 차이가 있는지 비교해 봅시다. 문서 공백 문자는 6가지 속성값이 다 다르게 보이지만, 다른 공백 구분자는 공백을 축소하는 속성값에서 공백을 축소하지 않기 때문에 각 속성값들이 줄바꿈 문자(문서 공백 문자)로 인한 차이 외에는 차이가 없어 보입니다.

See the Pen [SmartStudio] white-space 내 space 와 nbsp; by S.Young (@s_young) on CodePen.

1) 공백 문자별 속성값 동작 비교

공백 문자 종류와 줄바꿈에 따라 white-space의 속성값들의 동작을 비교해 보면 아래 표와 같습니다.

줄바꿈 문자
(new line, U+000A)
공백 문자
(space, U+0020),
탭 문자
(tab, U+0009)
텍스트 줄바꿈
(Text Wrapping)
줄 끝의 공백 문자
(End-of-line spaces)
줄 끝의 다른 공백 구분자
(End-of-line other space separators)
normal 축소
(Collapse)
축소
(Collapse)
줄바꿈
(Wrap)
제거
(Remove)
걸쳐짐
(Hang)
nowrap 축소
(Collapse)
축소
(Collapse)
줄바꿈 X
(No wrap)
제거
(Remove)
걸쳐짐
(Hang)
pre 보존
(Preserve)
보존
(Preserve)
줄바꿈 X
(No wrap)
보존
(Preserve)
줄바꿈 X
(No wrap)
pre-wrap 보존
(Preserve)
보존
(Preserve)
줄바꿈
(Wrap)
걸쳐짐
(Hang)
걸쳐짐
(Hang)
pre-line 보존
(Preserve)
축소
(Collapse)
줄바꿈
(Wrap)
제거
(Remove)
걸쳐짐
(Hang)
break-spaces 보존
(Preserve)
보존
(Preserve)
줄바꿈
(Wrap)
줄바꿈
(Wrap)
줄바꿈
(Wrap)
white-space 동작 (출처: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space)

2) 다른 공백 구분자 중 많이 쓰이는 non-breaking space (&nbsp;)

문서 공백 문자 중 space 공백 문자(” “)를 대체하기 위해 많이 쓰이는 대표적인 다른 공백 구분자로는 &nbsp; 라는 엔티티 코드로 익숙한 non-breaking space 공백 문자가 있습니다. space 공백 문자와 non-breaking space 공백 문자 모두 공백을 나타내는 문자이지만, 이들은 사용 목적과 특징이 다릅니다.&nbsp; 는 non-breaking space 즉, 줄바꿈을 하지 않는 공백라는 의미를 가지며, 이 문자를 사용하면 공백 문자가 여러 개 있어도 브라우저가 하나의 공백으로 축소하지 않고, 그 공백을 줄바꿈 할 때 라인이 나누어지지 않고 한 줄에 모두 표시됩니다. 앞서 이야기한 CSS의 공백 처리 규칙은 문서 공백 문자에 해당하기 때문에 위의 화면과 같이 다른 공백 구분자인 &nbsp;white-space 를 무시하고 동작합니다.

✔️ contenteditable=”true”은 왜 white-space: normal임에도 불구하고,
여러 개의 공백이 유지될까요?

contenteditable<textarea>  태그가 아니라도 <div> 나 다른 태그에 true 값을 추가하면 텍스트 편집이 가능하도록 만들어주는 HTML attribute입니다. 앞서 이야기했던 <textarea>  태그는 사용자 에이전트 스타일로 white-space  기본값을 normal 이 아닌 pre-wrap 을 갖고 있습니다.

하지만, contenteditablewhite-space 기본값을 따로 다시 설정하지 않았기 때문에 <div> 요소에 적용한다면 기본값인 normal 이지만, 텍스트 입력 시 마치 pre-wrap 스타일을 갖고 있는 것처럼 보입니다.

그 이유는 다음 테스트를 통해 알아봅시다. 아래 화면으로 함께 따라 해보세요.
3개의 박스는 우선 동일한 텍스트를 갖고 있습니다.

1번째, 3번째 박스와 달리 2번째 박스의 경우, 동일한 텍스트를 기본 텍스트로 넣을 때는 white-space: normal 의 특징에 따라 여러 개의 space 공백 문자를 하나로 축소하고 있습니다.

하지만, 기존 텍스트를 지우고  1번째 박스에 있는 텍스트를 복붙하거나 동일하게 입력하면 white-space: pre-wrap 스타일을 갖고 있는 1번째, 3번째 박스처럼 space 키를 여러 번 입력했지만 normal이 아닌 pre-wrap스타일처럼 여러 개의 공백 문자가 축소되지 않고 입력한 만큼의 공백이 노출됩니다.

See the Pen [SmartStudio Blog] white-space와 contenteditable by S.Young (@s_young) on CodePen.

normal 임에도 불구하고, space 키로 입력한 공백 유지될까요?

그 이유는 개발자 도구로 contenteditable 이 적용된 요소의 텍스트 노드를 살펴보면 알 수 있습니다. 아래 화면과 같이 2번째 박스의 텍스트 노드는 space가 텍스트 맨 앞에 들어갔을 때와 여러 개의 공백이 추가될 때 space 공백 문자(” “)를 non-breaking space 공백문자(&nbsp; )로 자동으로 치환합니다. 반면, 2번째 박스에 white-space: pre-wrap 스타일을 추가한 3번째 박스에서는 non-breaking space 공백문자(&nbsp; )로 치환되지 않고 space 공백 문자(” “)가 유지됩니다.

위 코드펜 3가지 예시의 실제 적용되는 공백 문자를 크롬 개발자 도구로 확인한 화면

html 공식 스펙 문서에서는 WYSIWYG 에디터에서 가급적 white-space: pre-wrap 을 사용할 것을 권장하고 있지만, 에디터마다 각자의 상황에 따라 contenteditable 처럼 normal 기본값을 적용하고, &nbsp; 로 일부 스페이스 공백 문자를 치환하는 경우도 종종 있습니다.

white-space: pre-wrap 을 에디터에 사용하도록 권장하는 이유는 아래 링크를 참고해 주세요.
🔗 https://html.spec.whatwg.org/multipage/interaction.html#best-practices-for-in-page-editors

3. white-space와 다른 속성과의 관계

white-space  속성을 다른 텍스트 관련 CSS 속성과 사용할 때, 일부 브라우저나 특정 속성값에서 예기치 못한 결과가 발생할 수 있습니다. 어떤 속성과 조합할 때 이슈가 생기는지 알아봅시다.

1) 텍스트 줄바꿈 스타일

word-break , overflow-wrap/word-wrap , line-break , hyphenswhite-space  속성값 중 자동 줄바꿈이 허용되는 경우에만 작동합니다. 예를 들면, 아래 화면에 빨간 테두리로 표시된 nowrap , pre  속성값은 강제 줄바꿈만 허용하기 때문에 소프트 랩 기회에서 줄바꿈 가능한 그 외 속성값들과 비교해 보면 word-break , overflow-wrap 같은 다른 텍스트 줄바꿈 속성을 무시하여 속성값에 따라 줄바꿈 차이가 없습니다.

만약 텍스트 줄바꿈 속성이 예상대로 동작하지 않는다면, white-space 속성값이 nowrap이나 pre가 아닌지 확인해 보세요.

See the Pen [SmartStudio] white-space 와 word-break, overflow-wrap by S.Young (@s_young) on CodePen.

2) 텍스트 양측 정렬 스타일

text-align  속성은 텍스트의 가로 정렬 방식을 설정하며, 그중 justify 속성값은 인라인 콘텐츠를 양쪽 정렬합니다. 양쪽 정렬은 문단의 마지막 줄을 제외하고, 줄 상자의 왼쪽과 오른쪽 끝에 텍스트를 맞추기 위해 사이 공간을 띄우는 정렬입니다.

이 속성값을 white-space 와 함께 사용할 때, 일부 속성값은 브라우저별로 다른 결과를 출력합니다. 그러므로 두 속성을 함께 사용할 때는 브라우저 호환성을 고려해서 테스트를 진행하고, 해결책이 필요할 수 있습니다.

아래 화면으로 브라우저별로 white-space 속성값, text-align 속성값 중 leftjustify, 공백문자 space와 non-breaking space 조합에 따라 어떠한 차이가 있는지 비교해 봅시다.

See the Pen [SmartStudio] white-space와 text-align: justify, space vs   by S.Young (@s_young) on CodePen.

위 화면에서 text-align: left 일 때를 먼저 비교해 보면 white-space 속성값별로 텍스트 정렬에 별 차이가 없습니다. 하지만, justify일 때는 아래 브라우저별로 조합을 비교한 이미지처럼 white-space 속성값뿐만 아니라 브라우저에 따라 텍스트의 양측 정렬이 다르게 노출됩니다.

앞서 이야기했던 contenteditable에 관한 이야기를 다시 떠올리며 기본값인 normal과 html 공식 스펙 문서에서 WYSIWYG 에디터에서 권장한 white-space: pre-wrap 값을 우선 비교해 봅시다. 표에서 동일한 행에 있는 칸은 동일한 white-space 속성값을 갖고 있고, 각 3가지 브라우저별로 동일한 열은 동일한 공백문자를 갖습니다. 빨간 테두리로 표시된 1번째 행은 기본값인normal이며, 2번째 행은 pre-wrap 입니다. normal일 때는 space(” “)와 space+non-breaking space(” “+&nbsp;)로 조합된 공백문자 2가지 모두 브라우저별로 큰 차이가 없습니다. 하지만 pre-wrap일 때는 양측 정렬의 목적에 맞지 않게 박스 영역을 의미하는 회색 배경 밖으로 인라인 텍스트 영역을 의미하는 노란 배경이 나가거나 마지막 줄이 아닌 일부 중간 줄 끝이 오른쪽 끝에 닿지 않는 이슈가 발생하는 케이스가 종종 보입니다.

이 크로스 브라우저 이슈의 해결책 중 하나는 이슈가 있는 white-space: pre-wrap 대신 contenteditable 이 브라우저에서 동작하는 방식처럼 white-space: normal 기본값을 유지하고 여러 공백이나 줄바꿈 문자가 하나의 공백으로 축소되지 않도록 일부 Space 공백 문자(” “)를 &nbsp;로 치환하고, 줄바꿈은 줄바꿈 문자(\n) 대신 <br/> 이나 block 요소로 구분하는 방법이 있습니다. 일부 에디터들은 이러한 방법으로 공백을 처리하기도 합니다.

브라우저별 비교 화면 (text-align: justify 에서 white-space 와 공백문자 조합)

3) 텍스트 말줄임 스타일

white-space 는 말줄임 UI을 표현하는데 중요한 역할을 합니다. 그리고 1줄 말줄임일 때와 2줄 이상 말줄임을 표현할 때 적용되는 속성값이 다릅니다.

See the Pen [SmartStudio Blog] white-space와 contenteditable by S.Young (@s_young) on CodePen.

✔️ 1줄 말줄임

1줄 말줄임 스타일에는 white-space: nowrap  값과 아래 스타일 코드가 함께 적용됩니다.

.ellipsis-1 {
    overflow: hidden;
    white-space: nowrap; // 공백 제거, 줄바꿈 X
    text-overflow: ellipsis; // 말줄임 표현
}

✔️ 2줄 이상 말줄임

2줄 이상 말줄임을 적용할 때는 white-space: normal 기본값과 아래 스타일 코드가 함께 적용됩니다.

.ellipsis-2 {
    overflow: hidden;
    white-space: normal; // (기본값) 공백 제거, 소프트 랩 기회에서 자동 줄바꿈 가능
    text-overflow: ellipsis;
    display: -webkit-box; // -webkit prefix가 붙기 때문에 일부 브라우저에서만 사용 가능
    -webkit-line-clamp: 2; // 글의 최대 라인수 결정
    -webkit-box-orient: vertical;
}

✔️ 말줄임 시 주의해야 할 <br/> 태그 사용

말줄임 스타일을 사용할 때, 강제 줄바꿈을 허용하는 <br/> 사용을 주의하여야 합니다. <br/> 태그로 줄바꿈 하는 경우, white-space 속성으로 하나의 공백으로 처리 가능한 기본 줄바꿈 문자(\n )와 달리 속성에 영향을 받지 않고 무조건 줄바꿈이 적용되기 때문에 아래 화면처럼 예상치 못한 결과를 초래할 수 있습니다. 특히 1줄 말줄임 케이스에서 텍스트의 줄바꿈을 허용하지 않는 nowrap에서도 강제 줄바꿈이 발생하여 텍스트가 여러 줄이 노출되는 문제가 생길 수 있습니다.

See the Pen [SmartStudio Blog] white-space & ellipsis by S.Young (@s_young) on CodePen.

말줄임 스타일 속성의 브라우저 호환성

일부 하위 브라우저에서는 적용되지 않을 수 있습니다.
적용 가능 범위는 아래 링크를 참고해 주세요.
🔗 https://caniuse.com/?search=ellipsis

4. 마무리

이번 글에서는 줄바꿈과 공백 문자에 대해 깊이 있게 다루어보았습니다. 글의 내용을 다시 복습해 보자면 아래와 같습니다.

  • 공백 문자의 줄바꿈 속성
    • 공백 문자를 다루는 CSS 속성은 white-space 이며, 이 속성은 문서 공백 문자(스페이스, 탭, 줄바꿈 문자)가 여러 개 있을 때 공백 축소 여부 및 방법, 줄바꿈 여부를 지정합니다.
    • white-space 각 속성값들의 소프트 랩 기회에서 줄바꿈 여부를 잘 기억하세요. 소프트 랩 기회에서 줄바꿈 되지 않는 속성값인 nowrappre  에서는 이전 다국어 편에서 다룬 스타일 속성(word-breakoverflow-wrap 등)이 동작하지 않는 특징이 있습니다.
    • white-space: normal; 이 기본값이지만, 브라우저 대부분은 <pre> 는 white-space: pre 를, <textarea> 는 white-space: pre-wrap 을 사용자 에이전트 스타일로 갖고 있습니다.
  • 공백 문자의 종류
    • 문서 공백 문자와 다른 공백 구분자 2가지로 나뉘며, 달리 지정된 경우를 제외하고 CSS의 공백 처리는 문서 공백 문자에만 영향을 미칩니다.
    • 다른 공백 구분자 중 많이 쓰이는 non-breaking space ( &nbsp;)가 있습니다. contenteditable="true" 일 때, 텍스트 입력 시 일부 space 공백 문자(” “)가 &nbsp; 로 치환됩니다.
  • white-space  속성과 다른 속성과의 관계
    • 다른 텍스트 관련 CSS 속성과 사용할 때, 일부 브라우저나 특정 속성값에서 예기치 못한 결과가 발생할 수 있습니다.
    • white-space: pre-wrap 을 적용할 경우 text-align: justify 양측 정렬 스펙에 대해 크로스 브라우저 이슈가 있습니다. 
    • white-space 는 말줄임 UI을 표현하는데 중요한 역할을 합니다. 말줄임 스타일을 사용할 때는 강제 줄바꿈 <br/> 태그를 사용하지 마십시오.

이 글을 정리하면서 white-space 가 이렇게 다른 여러 텍스트 스타일에 영향을 미치고, 공백 문자별로 어떻게 다르게 표현하는지 자세히 알 수 있었습니다. 이로써 다국어편과 공백문자편 2편에 걸친 줄바꿈 스타일에 대한 A to Z 이야기가 마무리되었습니다. 여러분들도 텍스트와 관련된 CSS 속성을 깊게 이해하고, 앞으로 다양한 텍스트 이슈를 해결하실 때 도움이 되시길 바랍니다! 🙏🏻

참고자료

길선영 | SmartEditor

정렬을 맞추는 요가와 CSS를 좋아하는 개발자