안녕하세요! 프론트엔드 강사입니다. CSS를 공부하시다 보면, left, right 같은 익숙한 방향 대신 start, end 같은 단어가 등장해서 당황스러운 적이 있으셨을 텐데요. 이게 바로 최신 CSS의 핵심 개념 중 하나인 '논리적 속성(Logical Properties)'이랍니다!
특히 플로트(float)나 포지셔닝(positioning)을 다룰 때 이 논리적 속성을 알면, 다국어 사이트를 만들 때 정말 마법처럼 편해져요. 공식 문서의 내용을 바탕으로 제가 실무 팁까지 얹어서 아주 쉽게 풀어서 번역해 드릴게요!
CSS 논리적 속성 및 값(CSS logical properties and values) 모듈은 우리가 자주 쓰던 float과 clear의 물리적인(physical) 값들을 어떻게 논리적으로 바꿔 쓸 수 있는지 알려줍니다. 뿐만 아니라, 위치 지정 레이아웃(positioned layout) (즉, position: absolute 등)에서 사용하는 속성들에 대한 논리적 매핑(mapping)도 제공하죠. 이 가이드에서는 이것들을 어떻게 사용하는지 살펴보겠습니다.
아래 표는 이 가이드에서 다룰 논리적 속성(logical properties)과 값들이, 기존에 우리가 알던 물리적 속성(physical properties) 및 값들과 어떻게 일대일로 짝지어지는지(매핑되는지) 자세히 보여줍니다.
⚠️ 주의: 이 표는 한국어나 영어처럼 왼쪽에서 오른쪽으로 글씨를 쓰는 수평 쓰기 모드(horizontal
writing-mode, left-to-right)를 기준으로 설명하고 있습니다.
| 논리적 속성 또는 값 (Logical) | 물리적 속성 또는 값 (Physical - LTR 기준) |
|---|---|
float: inline-start | float: left |
float: inline-end | float: right |
clear: inline-start | clear: left |
clear: inline-end | clear: right |
inset-inline-start | left |
inset-inline-end | right |
inset-block-start | top |
inset-block-end | bottom |
text-align: start | text-align: left |
text-align: end | text-align: right |
이렇게 일대일로 매핑되는 속성들 외에도, 블록(block) 차원과 인라인(inline) 차원을 동시에 다룰 수 있게 되면서 만들어진 '단축 속성(shorthand properties)'들이 몇 가지 더 있습니다. 이 녀석들은 inset 속성을 제외하고는 1:1로 대응되는 과거의 물리적 속성이 없어요. 완전히 새롭고 편리한 기능이죠!
| 논리적 단축 속성 | 목적 (Purpose) |
|---|---|
inset-inline | 인라인 방향(보통 좌/우)의 시작과 끝 여백 값을 한 번에 설정합니다. (예: inset-inline: 10px 20px;) |
inset-block | 블록 방향(보통 상/하)의 시작과 끝 여백 값을 한 번에 설정합니다. |
inset | 상하좌우 4개의 값을 한 번에 설정합니다. 마치 margin이나 padding처럼 값이 1~4개 들어가는 방식과 똑같이 작동합니다. |
👨🏫 강사의 팁: > 예전에는 요소를 화면 꽉 차게 띄울 때
top: 0; bottom: 0; left: 0; right: 0;이렇게 네 줄이나 썼죠? 이제는 딱 한 줄,inset: 0;이면 끝납니다. 정말 편해졌죠? 실무에서도 아주 많이 쓰인답니다.
과거에 float와 clear 속성에 주던 물리적인 값은 left, right, both였습니다. CSS 논리적 속성 및 값 모듈에서는 left와 right를 대체하기 위해 inline-start와 inline-end라는 값을 새롭게 정의했습니다.
아래 예제를 볼까요?
첫 번째 박스는 물리적 속성인 float: left를 사용했고, 두 번째 박스는 논리적 속성인 float: inline-start를 사용해 띄웠습니다.
만약 .inner 선택자에 direction: rtl(오른쪽에서 왼쪽으로 읽는 방향)을 적용해 보면 어떻게 될까요?
left로 띄운 박스는 텍스트가 오른쪽에서 시작하든 말든 상관없이 무조건 화면 왼쪽에 찰싹 붙어 있습니다. (레이아웃 붕괴!)inline-start로 띄운 아이템은 텍스트의 방향(direction)을 똑똑하게 따라갑니다. 글씨가 오른쪽에서 시작하면 자기도 오른쪽(start 지점)으로 가서 찰싹 붙는 거죠! 여기에 writing-mode: vertical-rl(세로쓰기)까지 섞어보면, direction 값과 결합된 블록 레이아웃의 차이를 더욱 극명하게 확인하실 수 있습니다.
<div class="container">
<div class="inner">
<div class="physical box"></div>
Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce
kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter
purslane kale.
</div>
<div class="inner">
<div class="logical box"></div>
Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce
kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter
purslane kale.
</div>
</div>
body {
font: 1.2em / 1.5 sans-serif;
}
.container {
display: flex;
}
.box {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
margin: 10px;
width: 100px;
height: 100px;
}
.inner {
/* 테스트해보려면 아래 주석을 풀어보세요! */
/* direction: rtl; */
/* writing-mode: vertical-rl; */
}
.physical {
float: left;
}
.logical {
float: inline-start;
}
CSS 포지셔닝(Positioning, 예: position: absolute)을 사용하면 일반적으로 컨테이닝 블록(부모 요소)을 기준으로 요소를 배치할 수 있습니다. 즉, 요소가 원래 있었어야 할 기본 흐름(normal flow)의 위치에서부터 강제로 밀어내는(inset) 방식이죠.
요소를 뷰포트(또는 기준이 되는 부모)에 상대적으로 배치할 때, 과거에는 물리적 속성인 top, right, bottom, left를 사용했습니다.
하지만 이제 텍스트가 흐르는 방향(쓰기 모드)과 맞물려서 유연하게 위치를 잡고 싶다면, 그 대신 inset-block-start, inset-block-end, inset-inline-start, inset-inline-end를 사용하시면 됩니다!
이 속성들은 값으로 길이(px 등)나 퍼센트(%)를 받을 수 있으며, 사용자의 화면 크기와 연동되어 작동합니다.
아래 예제에서는 position: relative가 적용된 회색 점선 테두리 영역 안에 파란색 박스를 절대 위치(position: absolute)로 띄웠습니다.
top과 right를 썼고, inset-block-start와 inset-inline-end를 사용해 배치했습니다.여기서도 .inner의 writing-mode 속성을 vertical-rl로 바꾸거나 direction: rtl을 추가해 보세요. 옛날 방식(물리적)으로 짠 박스는 그 자리에 멍청하게 가만히 있지만, 최신 방식(논리적)으로 짠 박스는 텍스트의 흐름이 바뀌는 것을 감지하고 스스로 위치를 샤샥~ 변경하는 것을 볼 수 있습니다!
<div class="container">
<div class="inner">
<div class="physical box"></div>
</div>
<div class="inner">
<div class="logical box"></div>
</div>
</div>
.container {
display: flex;
}
.inner {
width: 200px;
height: 200px;
position: relative;
border: 2px dotted grey;
}
.box {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
width: 100px;
height: 100px;
}
.inner {
writing-mode: horizontal-tb;
}
.physical {
position: absolute;
top: 20px;
right: 0;
}
.logical {
position: absolute;
inset-block-start: 20px;
inset-inline-end: 0;
}
이 모듈의 다른 속성들(margin, padding 등)과 마찬가지로, inset 역시 두 개 혹은 네 개의 값을 한 번에 설정할 수 있는 단축 속성(shorthand properties)을 제공합니다.
inset — 네 방향의 값을 한 번에 설정합니다. (값의 개수에 따라 기존 물리적 매핑 방식인 top/right/bottom/left 순서대로 작동합니다.)inset-inline — 논리적인 인라인(inline) 방향의 양쪽 여백(시작과 끝)을 동시에 설정합니다.inset-block — 논리적인 블록(block) 방향의 양쪽 여백(시작과 끝)을 동시에 설정합니다.텍스트를 정렬하는 text-align 속성 역시 텍스트 방향과 연동되는 논리적 값을 가지고 있습니다. 더 이상 딱딱한 left와 right를 고집할 필요 없이, 유연한 start와 end를 사용해 보세요.
아래 예제를 보면, 첫 번째 블록은 text-align: right로 설정했고 두 번째 블록은 text-align: end로 설정했습니다. 지금은 둘 다 똑같이 오른쪽에 붙어있죠?
하지만 direction 값을 rtl로 바꿔보세요. 첫 번째 블록은 글씨가 오른쪽에서 왼쪽으로 흐르는데도 여전히 오른쪽에 찰싹 붙어있습니다. 반면, 두 번째 블록은 글씨의 시작점이 오른쪽이 되었으므로, 끝나는 지점(end)인 왼쪽으로 아주 자연스럽게 정렬을 바꿉니다!
<div class="container">
<div class="inner physical">Aligned text</div>
<div class="inner logical">Aligned text</div>
</div>
body {
font: 1.2em / 1.5 sans-serif;
}
.container {
display: flex;
}
.inner {
width: 200px;
border: 2px dotted grey;
padding: 10px;
}
.inner {
direction: ltr;
}
.physical {
text-align: right;
}
.logical {
text-align: end;
}
이런 논리적 정렬 방식은 플렉스박스나 그리드에서 start와 end를 이용해 아이템을 정렬할 때(예: justify-content: flex-start), 요소들이 물리적인 방향에 얽매이지 않고 훨씬 일관성 있게 작동하도록 만들어줍니다.
어떠신가요? start와 end, block과 inline이라는 개념만 잡으면 논리적 속성이 얼마나 유용하고 강력한 무기인지 아실 수 있을 거예요. 특히 글로벌 서비스를 준비하시거나 다국어 번역이 들어가는 사이트를 만드신다면, 처음부터 무조건 논리적 속성으로 코딩하는 습관을 들이시는 걸 강력 추천합니다!