Handling different text directions

김동현·2026년 3월 18일

mdn 학습 번역 - CSS

목록 보기
17/190

안녕하세요! CSS 기초 여정의 새로운 장에 오신 것을 환영합니다.

지금까지 우리는 주로 왼쪽에서 오른쪽으로, 위에서 아래로 흐르는 영어나 한국어 같은 텍스트 환경을 염두에 두고 CSS를 다루어 왔습니다. 하지만 전 세계에는 아랍어처럼 오른쪽에서 왼쪽으로 읽는 언어도 있고, 일본어나 옛날 한국어처럼 위에서 아래로 세로로 적는 언어도 있죠.

오늘 배울 '쓰기 모드(Writing modes)'와 '논리적 속성(Logical properties)'은 현대 웹 개발에서 정말 중요한 개념으로 떠오르고 있습니다. 글로벌 서비스를 만들거나, 혹은 독특한 세로 디자인 요소 등을 구현할 때 꼭 필요하거든요.

다소 생소할 수 있는 개념이지만, 공식 문서의 내용을 꼼꼼하게 번역하고 제가 현업에서 배운 노하우와 팁을 더해서 이해하기 쉽게 설명해 드리겠습니다. 자, 시작해 볼까요?


다양한 텍스트 방향 다루기 (Handling different text directions)

이전 페이지 (Test your skills: Box model) | 개요: CSS 스타일링 기초 | 다음 페이지 (Test your skills: Cascade)

지금까지 우리가 CSS 학습 과정에서 만난 많은 속성(properties)과 값(values)들은 화면의 물리적인 차원(physical dimensions)에 묶여 있었습니다. 예를 들어, 우리는 상자의 위(top), 오른쪽(right), 아래(bottom), 왼쪽(left)에 테두리를 만듭니다. 이러한 물리적 차원들은 텍스트가 가로로 표시되는 상황에 매우 잘 들어맞았으며, 기본적으로 웹은 아랍어와 같은 우에서 좌로(right-to-left) 읽는 언어보다 영어나 프랑스어(그리고 한국어) 같은 좌에서 우로(left-to-right) 읽는 언어들을 더 잘 지원하는 경향이 있었습니다.

하지만 최근 몇 년 동안, CSS는 오른쪽에서 왼쪽으로 읽는 것은 물론이고 일본어처럼 위에서 아래로(top-to-bottom) 내려쓰는 콘텐츠 등 다양한 콘텐츠 방향성을 더 잘 지원하기 위해 진화해 왔습니다. 이러한 다양한 방향성을 가리켜 쓰기 모드(writing modes)라고 부릅니다. 앞으로 학습을 진행하고 레이아웃(layout) 작업을 시작하게 되면, 이 쓰기 모드를 이해하는 것이 큰 도움이 될 것이므로 지금 미리 소개해 드리고자 합니다.

사전 준비 지식:기본 소프트웨어 설치, 파일 다루기에 대한 기본 지식, HTML 기초 (HTML 소개 학습 권장), CSS 작동 방식에 대한 이해 (CSS 스타일링 기초 학습 권장).
학습 목표:모던 CSS에서 쓰기 모드(writing modes)의 중요성 이해하기.

쓰기 모드란 무엇인가요? (What are writing modes?)

CSS에서 쓰기 모드란 텍스트가 가로(수평)로 흐르는지 세로(수직)로 흐르는지를 나타냅니다. writing-mode 속성을 사용하면 하나의 쓰기 모드에서 다른 쓰기 모드로 전환할 수 있습니다.

꼭 세로 쓰기 모드를 사용하는 언어권의 프로젝트를 진행할 때만 이 속성을 써야 하는 것은 아닙니다. 창의적이고 독특한 웹 디자인을 목적으로 레이아웃 일부의 쓰기 모드를 변경할 수도 있거든요.

아래 예제에는 writing-mode: vertical-rl 속성이 적용된 제목(heading)이 있습니다. 이제 텍스트가 세로 방향으로 흘러내립니다. 세로 텍스트는 그래픽 디자인에서 꽤 흔하게 쓰이는 요소이며, 웹 디자인에 좀 더 흥미로운 외관과 느낌을 더하는 방법이 될 수 있습니다.

<h1>Play with writing modes</h1>
body {
  font-family: sans-serif;
  height: 300px;
}
h1 {
  writing-mode: vertical-rl;
  color: white;
  background-color: black;
  padding: 10px;
}

writing-mode 속성이 가질 수 있는 세 가지 값은 다음과 같습니다:

  • horizontal-tb: Top-to-Bottom(위에서 아래로) 블록 흐름 방향입니다. 문장은 가로로 진행됩니다. (우리가 평소에 쓰는 일반적인 웹페이지 방향입니다.)
  • vertical-rl: Right-to-Left(오른쪽에서 왼쪽으로) 블록 흐름 방향입니다. 문장은 세로로 진행됩니다. (전통적인 동양권 세로쓰기입니다.)
  • vertical-lr: Left-to-Right(왼쪽에서 오른쪽으로) 블록 흐름 방향입니다. 문장은 세로로 진행됩니다.

결국 writing-mode 속성은 실제로 블록 레벨 요소(block-level elements)가 페이지에 쌓이는 방향 — 위에서 아래로, 오른쪽에서 왼쪽으로, 혹은 왼쪽에서 오른쪽으로 — 을 설정하는 것입니다. 그리고 이것이 문장이 흘러가는 방향을 결정짓게 됩니다.

💡 강사의 실무 팁!
"어? 그냥 글자 회전하려면 transform: rotate(90deg) 쓰면 되는 거 아닌가요?" 라고 생각하실 수 있어요. 맞아요, 글자를 눕히는 건 transform으로도 할 수 있습니다.
하지만 writing-modetransform은 레이아웃 관점에서 엄청난 차이가 있습니다. transform은 일단 원래 가로로 자리를 차지해놓고 시각적으로만 빙그르르 돌려버리기 때문에 주변 요소들과 다 겹치고 난리가 납니다. 반면 writing-mode를 바꾸면 박스 모델 자체가 세로를 기준으로 렌더링되기 때문에, 주변 요소들을 자연스럽게 밀어내며 완벽한 세로 레이아웃을 만들 수 있습니다. 캘린더나 타임라인 같은 UI에서 세로 라벨을 만들 때 아주 유용합니다!


쓰기 모드와 블록 및 인라인 레이아웃 (Writing modes and block and inline layout)

우리는 이미 블록과 인라인 레이아웃(block and inline layout)에 대해 배웠고, 어떤 것은 블록 요소로, 어떤 것은 인라인 요소로 표시된다는 사실을 알고 있습니다. 위에서 설명한 것처럼, 블록(block)과 인라인(inline)의 개념은 물리적인 모니터 화면이 아니라 문서의 쓰기 모드(writing mode)와 결속되어 있습니다. 블록은 오직 영어나 한국어처럼 텍스트를 가로로 표시하는 쓰기 모드(horizontal-tb)를 사용할 때만 페이지의 '위에서 아래로' 쌓이게 됩니다.

예제를 보면 훨씬 명확해질 거예요. 다음 예제에는 제목(heading)과 문단(paragraph)을 포함하는 두 개의 박스가 있습니다.

  • 첫 번째 박스는 가로로 작성되고 페이지 위에서 아래로 흐르는 쓰기 모드인 writing-mode: horizontal-tb를 사용합니다.
  • 두 번째 박스는 writing-mode: vertical-rl을 사용합니다. 이것은 세로로 작성되고 오른쪽에서 왼쪽 방향으로 흐르는 쓰기 모드입니다.
<div class="wrapper">
  <div class="box horizontal">
    <h2>Heading</h2>
    <p>A paragraph demonstrating writing modes in CSS.</p>
  </div>
  <div class="box vertical">
    <h2>Heading</h2>
    <p>A paragraph demonstrating writing modes in CSS.</p>
  </div>
</div>
body {
  font-family: sans-serif;
  height: 300px;
}
.wrapper {
  display: flex;
}

.box {
  border: 1px solid #cccccc;
  padding: 0.5em;
  margin: 10px;
}

.horizontal {
  writing-mode: horizontal-tb;
}

.vertical {
  writing-mode: vertical-rl;
}

우리가 쓰기 모드를 전환할 때, 우리는 어느 방향이 블록(block) 차원이고 어느 방향이 인라인(inline) 차원인지 통째로 바꿔버린 것입니다.

  • 블록 차원(Block dimension)은 현재 사용 중인 쓰기 모드에서 블록들이 페이지에 줄줄이 쌓이는 방향을 의미합니다. (horizontal-tb에서는 위아래(수직), vertical-rl에서는 우좌(수평) 방향이 되겠죠.)
  • 인라인 차원(Inline dimension)은 문장이 흘러가는(글자들이 이어지는) 방향을 의미합니다. (horizontal-tb에서는 좌우(수평), vertical-rl에서는 위아래(수직) 방향이 됩니다.)

아래 그림은 가로 쓰기 모드(horizontal writing mode)일 때의 두 차원을 보여줍니다.

가로 쓰기 모드에서의 블록(세로)과 인라인(가로) 축을 보여주는 그림

다음 그림은 세로 쓰기 모드(vertical writing mode)일 때의 두 차원을 보여줍니다.

세로 쓰기 모드에서의 블록(가로)과 인라인(세로) 축을 보여주는 그림

나중에 CSS 레이아웃, 특히 최신 레이아웃 기법(Flexbox, Grid 등)을 배우기 시작하면 이 블록과 인라인 차원의 개념이 정말 어마어마하게 중요해집니다. 나중에 이 내용은 꼭 다시 짚고 넘어가게 될 거예요.

방향 (Direction)

쓰기 모드에 더하여, 우리는 '텍스트 방향(direction)'도 가지고 있습니다. 위에서 언급했듯이, 아랍어 같은 일부 언어들은 가로로 쓰이긴 하지만 텍스트가 '오른쪽에서 왼쪽으로(right-to-left)' 진행됩니다. 이것은 창의적이거나 디자인적인 목적으로 사용할 만한 속성은 아닙니다. (만약 무언가를 오른쪽에 정렬하고 싶다면 그걸 처리하는 다른 좋은 방법들이 많으니까요.) 하지만 CSS의 본질을 이해하는 측면에서 이 사실을 알고 있는 것은 중요합니다. 웹은 왼쪽에서 오른쪽으로 읽는 언어만을 위한 곳이 아니기 때문이죠!

이처럼 '쓰기 모드'와 '텍스트 방향'이 언제든 바뀔 수 있다는 특성 때문에, 최신 CSS 레이아웃 방식들은 더 이상 '왼쪽(left)'과 '오른쪽(right)', '위(top)'와 '아래(bottom)'라는 물리적 용어에 묶여있지 않으려 합니다. 그 대신 이들은 인라인과 블록이라는 개념을 바탕으로 '시작(start)''끝(end)'이라는 논리적인 용어를 사용하게 되었습니다. 지금 당장 이 모든 걸 완벽히 이해하려 머리 아파하지 않으셔도 됩니다. 하지만 레이아웃을 배우기 시작할 때 이 아이디어들을 마음속에 품고 있으면, CSS를 이해하는 데 정말 큰 도움이 될 것입니다.


논리적 속성과 값 (Logical properties and values)

여러분이 학습하는 이 시점에 굳이 쓰기 모드와 방향에 대해 이야기하는 이유는, 우리가 이미 화면의 물리적인 차원(top, right, bottom, left)에 단단히 묶여있는 많은 속성들을 배웠기 때문입니다. 이 물리적 속성들은 우리가 흔히 쓰는 가로 쓰기 모드에서는 아주 직관적이고 이해하기 쉽죠.

자, 다시 우리의 두 상자를 살펴볼까요? 하나는 horizontal-tb 쓰기 모드이고, 다른 하나는 vertical-rl 쓰기 모드입니다. 저는 두 상자에 모두 똑같이 물리적 속성인 width(너비)를 부여했습니다.

상자가 세로 쓰기 모드로 변경되었음에도 불구하고 이 상자는 여전히 가로 방향의 '너비(width)' 값을 유지하고 있고, 이로 인해 텍스트가 아래로 길어지면서 상자를 넘쳐흐르는(overflow) 현상이 발생하게 됩니다.

<div class="wrapper">
  <div class="box horizontal">
    <h2>Heading</h2>
    <p>A paragraph demonstrating writing modes in CSS.</p>
    <p>These boxes have a width.</p>
  </div>
  <div class="box vertical">
    <h2>Heading</h2>
    <p>A paragraph demonstrating writing modes in CSS.</p>
    <p>These boxes have a width.</p>
  </div>
</div>
body {
  font-family: sans-serif;
  height: 300px;
}
.wrapper {
  display: flex;
}

.box {
  border: 1px solid #cccccc;
  padding: 0.5em;
  margin: 10px;
  width: 100px;
}

.horizontal {
  writing-mode: horizontal-tb;
}

.vertical {
  writing-mode: vertical-rl;
}

이런 시나리오에서 우리가 진정으로 원하는 것은, 쓰기 모드가 바뀌면 그에 맞춰서 너비(width)와 높이(height)도 본질적으로 서로 뒤바뀌는 것입니다. 세로 쓰기 모드로 들어갔을 때, 우리는 박스가 가로 모드일 때 위아래로 늘어났던 것처럼 똑같이 블록(block) 방향으로 확장되기를 원하니까요.

이러한 문제를 훨씬 쉽게 해결하기 위해, CSS는 최근에 서로 매핑(mapping)되는 새로운 속성 세트를 개발해 냈습니다. 이 속성들은 widthheight 같은 물리적인(physical) 속성들을 논리적인(logical), 또는 흐름에 상대적인(flow relative) 버전으로 대체합니다.

가로 쓰기 모드에서의 width(너비)에 매핑되는 논리적 속성의 이름은 inline-size입니다. 인라인 차원(문장이 흐르는 방향)에서의 크기를 의미하죠. height(높이)에 해당하는 논리적 속성의 이름은 block-size이며, 이는 블록 차원에서의 크기입니다.

아래 예제에서 widthinline-size로 대체했을 때 어떻게 동작이 달라지는지 확인해 보세요.

<div class="wrapper">
  <div class="box horizontal">
    <h2>Heading</h2>
    <p>A paragraph demonstrating writing modes in CSS.</p>
    <p>These boxes have inline-size.</p>
  </div>
  <div class="box vertical">
    <h2>Heading</h2>
    <p>A paragraph demonstrating writing modes in CSS.</p>
    <p>These boxes have inline-size.</p>
  </div>
</div>
.wrapper {
  display: flex;
}

.box {
  border: 1px solid #cccccc;
  padding: 0.5em;
  margin: 10px;
  inline-size: 100px;
}

.horizontal {
  writing-mode: horizontal-tb;
}

.vertical {
  writing-mode: vertical-rl;
}

결과를 보시면, 첫 번째 박스는 여전히 가로 폭이 100px이지만, 세로 쓰기 모드로 변환된 두 번째 박스는 inline-size가 세로를 의미하게 되면서 세로 길이가 100px로 고정되었습니다! 이제 텍스트가 자연스럽게 블록 방향(가로 방향)으로 넘어가며 넘침 현상이 사라졌죠.

💡 강사의 실무 팁!
"어? 그럼 앞으로 width 대신 무조건 inline-size를 써야 하나요?"
아직 모든 글로벌 서비스를 다국어로 개발하는 경우가 아니라면 width를 쓰셔도 전혀 무방합니다. 다만, 글로벌 다국어(i18n)를 지원하는 거대한 프로젝트(예: 넷플릭스, 구글 등)를 진행할 때는 방향 하나 때문에 모든 CSS를 뜯어고칠 수 없으므로 이런 논리적 속성(Logical Properties)을 기본으로 사용하는 추세입니다.


논리적인 마진, 테두리, 패딩 속성 (Logical margin, border, and padding properties)

지난 두 번의 레슨에서 우리는 CSS 박스 모델과 테두리(border)에 대해 배웠습니다. 마진, 테두리, 패딩 속성들 중에는 margin-top, padding-left, border-bottom처럼 철저하게 '물리적인' 방향을 가리키는 속성들이 아주 많습니다. 너비와 높이에 대응하는 논리적 속성이 있었던 것처럼, 이 속성들에도 대응하는 매핑 속성들이 존재합니다.

margin-top 속성은 margin-block-start로 매핑됩니다. 이것은 쓰기 모드에 상관없이 항상 블록 차원의 '시작 부분(start)'에 여백을 주겠다는 의미입니다.

padding-left 속성은 padding-inline-start로 매핑됩니다. 이것은 인라인 방향이 '시작하는' 쪽에 패딩을 적용합니다. 즉, 현재 쓰기 모드에서 문장이 시작하는 위치가 되겠죠. border-bottom 속성은 border-block-end로 매핑되며, 이는 블록 차원의 '끝(end)' 부분에 테두리를 칩니다.

아래 예제에서 물리적 속성과 논리적 속성을 비교해 보실 수 있습니다.

.box에 있는 writing-mode 속성을 vertical-rl로 바꿔서 박스들의 쓰기 모드를 전환해 보세요. 물리적 속성(physical properties)을 쓴 박스는 방향이 바뀌어도 무조건 물리적인 위, 아래, 왼쪽, 오른쪽에 스타일이 고정되어 있지만, 논리적 속성(logical properties)을 쓴 박스는 쓰기 모드가 변함에 따라 스타일도 함께 마법처럼 스르륵 이동하는 것을 볼 수 있습니다.

또한, <h2> 태그에 검은색 border-bottom(아래쪽 테두리)이 있는 것도 확인해 보세요. 쓰기 모드에 상관없이 이 테두리가 항상 텍스트의 '아래쪽'에 밑줄처럼 깔리게 하려면 이 코드를 어떻게 수정해야 할까요? (정답은 border-block-end로 바꾸는 것입니다!)

<div class="wrapper">
  <div class="box physical">
    <h2>Physical Properties</h2>
    <p>A paragraph demonstrating logical properties in CSS.</p>
  </div>
  <div class="box logical">
    <h2>Logical Properties</h2>
    <p>A paragraph demonstrating logical properties in CSS.</p>
  </div>
</div>
.wrapper {
  display: flex;
  border: 5px solid #cccccc;
}

.box {
  margin-right: 30px;
  inline-size: 200px;
  writing-mode: horizontal-tb;
}

.logical {
  margin-block-start: 20px;
  padding-inline-end: 2em;
  padding-block-start: 2px;
  border-block-start: 5px solid pink;
  border-inline-end: 10px dotted rebeccapurple;
  border-block-end: 1em double orange;
  border-inline-start: 1px solid black;
}

.physical {
  margin-top: 20px;
  padding-right: 2em;
  padding-top: 2px;
  border-top: 5px solid pink;
  border-right: 10px dotted rebeccapurple;
  border-bottom: 1em double orange;
  border-left: 1px solid black;
}

h2 {
  border-bottom: 5px solid black;
}

각 테두리를 개별적으로 지정하는 모든 속성(longhands)을 고려하면 관련된 속성의 수가 엄청나게 많습니다. MDN의 논리적 속성과 값(Logical Properties and Values) 페이지에서 매핑되는 전체 속성 목록을 확인하실 수 있습니다.


논리적 값 (Logical values)

지금까지는 논리적인 속성 '이름'들에 대해 살펴보았습니다. 그런데, 속성의 '값'으로 물리적인 top, right, bottom, left를 사용하는 경우도 있죠. 이 값들 역시 논리적 값인 block-start, inline-end, block-end, inline-start로 매핑될 수 있습니다.

예를 들어, 텍스트가 이미지를 감싸며 흐르게 하려고 이미지를 왼쪽(left)으로 띄울(float) 수 있습니다. 아래 예제에 나와 있는 것처럼, 이럴 때 left 대신 inline-start를 사용할 수 있습니다.

이 예제의 쓰기 모드를 vertical-rl로 변경해서 이미지의 위치가 어떻게 변하는지 확인해 보세요. 또한 inline-startinline-end로 변경해서 float의 방향을 바꿔보세요.

<div class="wrapper">
  <div class="box logical">
    <img
      alt="star"
      src="[https://mdn.github.io/shared-assets/images/examples/big-star.png](https://mdn.github.io/shared-assets/images/examples/big-star.png)" />
    <p>
      This box uses logical properties. The star image has been floated
      inline-start, it also has a margin on the inline-end and block-end.
    </p>
  </div>
</div>
.wrapper {
  display: flex;
}

.box {
  margin: 10px;
  padding: 0.5em;
  border: 1px solid #cccccc;
  inline-size: 200px;
  writing-mode: horizontal-tb;
}

img {
  float: inline-start;
  margin-inline-end: 10px;
  margin-block-end: 10px;
}

이 예제에서도 마진(margin)이 쓰기 모드에 상관없이 항상 정확한 위치에 들어가게 만들기 위해 논리적 마진 값을 사용했습니다.


물리적 속성을 써야 할까요, 논리적 속성을 써야 할까요? (Should you use physical or logical properties?)

논리적 속성과 값은 그에 상응하는 기존 물리적 속성들보다 훨씬 나중에 등장했습니다. 그래서 브라우저에 도입된 지 그리 오래되지 않았죠. 특정 속성의 브라우저 지원 현황이 얼마나 오래전까지 거슬러 올라가는지 확인하려면 MDN 페이지 하단의 호환성 표를 확인하시면 됩니다.

만약 여러분이 다양한 쓰기 모드를 지원하는 다국어 사이트를 만드는 게 아니라면, 당분간은 직관적인 물리적 버전(top, bottom, left, right)을 사용하는 편이 더 편하실 수도 있습니다. 하지만 궁극적으로 우리는 프론트엔드 생태계가 점차 대부분의 상황에서 '논리적 버전'을 기본으로 사용하는 쪽으로 옮겨갈 것이라 예상합니다. 특히 Flexbox나 Grid 같은 최신 레이아웃 기법을 다루기 시작하면, 축을 기준으로 배치하는 이 논리적 속성들이 얼마나 합리적이고 이치에 맞는지 몸소 깨닫게 되실 거예요!


요약 (Summary)

이 레슨에서 설명한 개념들은 현대 CSS에서 점점 더 그 중요성이 커지고 있습니다. 블록(block) 차원과 인라인(inline) 차원에 대한 이해, 그리고 쓰기 모드가 변함에 따라 텍스트 흐름이 어떻게 달라지는지에 대한 이해는 앞으로 여러분이 프론트엔드를 학습하는 데 있어 아주 탄탄한 무기가 될 것입니다. 심지어 여러분이 평생 가로 쓰기 모드 하나만 사용한다고 하더라도, CSS의 핵심 철학을 깊이 이해하는 데 큰 도움을 줄 것입니다.

이전 페이지 (Test your skills: Box model) | 개요: CSS 스타일링 기초 | 다음 페이지 (Test your skills: Cascade)

profile
프론트에_가까운_풀스택_개발자

0개의 댓글