논리적 속성

Logical properties

`left`·`right` 대신 `inline-start`·`inline-end`처럼 "글의 흐름 방향" 기준으로 쓰는 속성. 언어가 RTL로 바뀌거나 세로쓰기가 되면 자동으로 따라옵니다.

다른 이름: CSS Logical Propertiesinset-inline-startmargin-inline
···
html
<div class="wrap">
  <div class="row" id="demo">
    <div class="col">
      <b class="lbl">physical</b>
      <div class="box phys"><span class="accent"></span><i class="ln"></i><i class="ln"></i></div>
    </div>
    <div class="col">
      <b class="lbl">logical</b>
      <div class="box logi"><span class="accent"></span><i class="ln"></i><i class="ln"></i></div>
    </div>
  </div>
  <div class="dirtag" id="dirtag">dir: ltr</div>
</div>
css
.wrap{display:flex;flex-direction:column;align-items:center;gap:12px;width:min(94%,440px)}
.row{display:flex;flex-wrap:wrap;justify-content:center;gap:16px;width:100%}
.col{display:flex;flex-direction:column;gap:6px;flex:1;min-width:150px}
.lbl{font:700 10px/1 ui-monospace,monospace;color:var(--muted);text-align:center}
.box{position:relative;height:96px;border:1px solid var(--line);border-radius:8px;background:var(--surface);
  padding:10px;display:flex;flex-direction:column;gap:6px;overflow:hidden}
.accent{position:absolute;top:0;bottom:0;width:6px;background:var(--accent-2)}
.phys .accent{left:0}
.logi .accent{inset-inline-start:0}
.ln{display:block;height:8px;border-radius:3px;background:var(--line);width:60%;transition:margin .6s}
.phys .ln{margin-left:16px}
.logi .ln{margin-inline-start:16px}
.dirtag{font:700 11px/1 ui-monospace,monospace;color:var(--accent-2);background:var(--surface);
  border:1px solid var(--line);border-radius:6px;padding:4px 8px}
js
const demo = document.getElementById('demo');
const dirtag = document.getElementById('dirtag');
let rtl = false;
setInterval(() => {
  rtl = !rtl;
  demo.setAttribute('dir', rtl ? 'rtl' : 'ltr');
  dirtag.textContent = 'dir: ' + (rtl ? 'rtl' : 'ltr');
}, 1800);

`margin-left`·`left`·`padding-right` 같은 "물리적" 속성은 화면의 실제 방향을 그대로 가리킵니다. 아랍어·히브리어처럼 오른쪽에서 왼쪽으로 읽는(RTL) 언어로 페이지를 전환해도 `margin-left: 14px`는 여전히 화면의 왼쪽에 14px를 만듭니다 — 그런데 RTL에서 "시작"은 오른쪽이므로, 이 여백은 이제 글의 흐름과 반대편에 붙어 있는 셈이 됩니다.

논리적 속성은 화면 좌표 대신 텍스트 흐름을 기준으로 이름 붙입니다. `margin-inline-start`는 "글이 시작되는 쪽"의 여백으로, LTR에서는 왼쪽에, RTL에서는 오른쪽에 자동으로 나타납니다. `inset-inline-start`(=RTL에 따라 좌우가 바뀌는 `left`/`right`), `padding-block`(위아래, `top`/`bottom`에 대응)도 같은 원리입니다 — `inline`은 글자가 흐르는 축, `block`은 줄이 쌓이는 축을 뜻합니다.

세로쓰기(`writing-mode: vertical-rl` 등, 전통 일본어·한자 조판)에서는 `inline`과 `block`이 아예 가로·세로를 서로 바꿔 가리킵니다. 그래서 논리적 속성으로 작성해두면 언어·방향·조판 모드가 바뀌어도 값을 하나도 손대지 않고 레이아웃이 알아서 따라옵니다 — 다국어 서비스에서는 사실상 필수에 가깝습니다.

언제 쓰나

제품이 아랍어·히브리어처럼 RTL 언어를 지원할 계획이 있다면 `margin-left`/`right`, `left`/`right`, `padding-left`/`right`를 쓰는 습관 자체를 처음부터 논리적 속성으로 바꾸는 게 낫습니다. 지원 언어가 전부 LTR이고 계획도 없다면 급하지 않습니다.