왜 줄 바꿈이 적용되질 않는 거야?
다음은 내가 만든 텍스트 입력 폼이다.
<label for="content">
내용
<textarea id="content" name="content" rows={6} placeholder="궁금한 내용이 있다면 편하게 남겨주세요 :)" value={value} required />
</label>
<textarea>를 이용해서 폼을 만들다 보면 매번 맞닥뜨리는 문제가 하나 있는데
Enter 키를 쾅쾅 쳐서 위 이미지와 같이 긴 텍스트를 입력했는데도 불구하고
값을 화면에 렌더링 하면 줄 바꿈이 공백으로 대체된다.
<div>
{value} {/* textarea의 value 값 */}
</div>
이 현상에 대한 ChatGPT의 답변을 한 번 정리해 보았다.
사용자가 <textarea>에서 줄 바꿈을 입력하면
이는 텍스트 형태로 저장되면서 newline character(줄 바꿈 문자)로 표현된다고 한다.
그리고 이 줄바꿈 문자는 운영체제에 따라서 `\n` 또는 `\r\n` 으로 저장된다고 한다.
- Unix/Linux, macOS: Line Feed(LF)로 표현. 문자로는 `\n`으로 저장
- Windows: Carriage Return + Line Feed(CRLF)로 표현. 문자로는 `/r/n`으로 저장
예시로 작성한 위 문자의 경우는
"안\n녕\n하세\n요\n??\n?\n💩" 으로 저장된 것
(이모지도 사실은 <img>로 변환된 거지만 여기에서는 설명을 위해 넘어간다.)
반면 HTML에서는 일반적으로 여러 개의 공백이나 줄 바꿈 문자를 무시한다.
따라서 위 <textarea>에서 입력된 텍스트를 그대로 HTML 문서에 삽입하면 줄 바꿈은 적용되지 않고 공백 역시 하나로 압축된다.
"안 녕 하세 요 ?? ? 💩" 와 같이 그저 공백으로 대체된 것이다.
정리하자면 내가 의도하는 대로 줄 바꿈을 연출하기 위해서는
별도의 처리를 해줘야 한다는 셈이다.
다행히 방법은 여러 가지다.
방법 1. <pre> 요소를 사용하자
<pre>에 대해서는 한 번 따로 포스팅을 한 적이 있다. (📜 [HTML] 자주 사용하지 않는 HTML5 태그 정리)
여러 개의 공백이나 줄 바꿈을 있는 그대로 유지하면서 표시하도록 도와주는 요소이다.
<pre>
{value} {/* textarea의 value 값 */}
</pre>
이전에는 value를 <div>로 감싸서 표기했지만 위와 같이 <pre>를 이용한다면
`\n`, `\r\n` 으로 저장된 텍스트가 무사히 의도대로 줄 바꿈으로 표현된다.
방법 2. white-space: pre를 사용하자
느낌적인 느낌 상 이 스타일 속성이 먼저 존재했는데 편의를 위해서 후발주자로 <pre>가 생겨났지 싶다. 어쩐지 HTML5 속성이더라.
스타일링을 통해서도 다음과 같이 줄 바꿈을 표현할 수 있다.
<div style="white-space: pre;">
{value} {/* textarea의 value 값 */}
</div>
white-space 속성을 별도로 지정하지 않은 경우 그 값은 normal인데
이 설정이 여러 개의 공백과 줄 바꿈을 무시하게 되는 원인이다.
때문에 HTML 문서 안에서 이를 표현하기 위해서 값을 pre로 적용해 주면 된다.
방법 3. 어어 직접 바꿔줘. `\n`, `\r\n` 을 <br />로 대체하기
가능하면 위의 두 방법이 간단하니 추천하고 싶으나 여건이 좋지 않을 수도 있지 않을까.
그래서 제안하는 방법은 직접 텍스트를 줄 바꿈 요소로 변경해 주는 것.
`\n` 또는 `\r\n` 을 <br> 요소로 직접 바꿔주는 것이다.
<div>
{value.replace(/\n|\r\n\g, '<br />')} {/* textarea의 value 값 */}
</div>
위와 같이 정규표현식을 활용해서 <br /> 요소로 대체해 줄 수 있다.
'MARKUP' 카테고리의 다른 글
[HTML][JAVASCRIPT] wai-aria를 이용해서 접근성 갖춘 탭 UI 만들기 (0) | 2024.01.15 |
---|---|
[HTML] 자주 사용하지 않는 HTML5 태그 정리 (0) | 2023.04.28 |