이 글은 누구를 위한 것인가
- 중동·이스라엘 시장 진출을 위해 RTL 버전을 만들어야 하는 팀
- CSS에서 RTL 지원하는 방법을 모르는 웹 개발자
- Figma에서 RTL 디자인을 효율적으로 하고 싶은 디자이너
들어가며
RTL 지원은 "텍스트 방향만 바꾸는 것"이 아니다. 레이아웃 전체가 거울처럼 뒤집히고, 아이콘 방향도 바뀌며, 숫자 포맷도 달라진다. CSS Logical Properties를 쓰면 LTR/RTL을 CSS 하나로 처리할 수 있다.
이 글은 bluefoxdev.kr의 국제화 UI 설계 가이드 를 참고하여 작성했습니다.
1. RTL vs LTR 차이점
[RTL 레이아웃 변환 규칙]
미러링 필요한 것:
레이아웃 방향: 좌→우 흐름이 우→좌로
여백: margin-left ↔ margin-right
패딩: padding-left ↔ padding-right
텍스트 정렬: left → right
플렉스 방향: row → row-reverse (자동 처리됨)
아이콘: 방향성 있는 아이콘 (화살표, 뒤로가기)
스크롤바: 오른쪽 → 왼쪽
미러링 불필요:
시계 방향 회전 아이콘 (새로고침, 설정)
로고, 브랜드 에셋
숫자 (아랍-인도 숫자 제외)
이미지 (상황에 따라 다름)
체크박스, 라디오 버튼 (✓ 방향 고정)
[아랍어 숫자 표기]
표준 아랍어: ٠١٢٣٤٥٦٧٨٩ (아랍-인도 숫자)
혼용: 국제 숫자(0-9)를 그대로 쓰는 경우 많음
통화: 숫자는 LTR, 통화 기호는 오른쪽
2. CSS Logical Properties로 RTL 지원
/* 기존 방식 (LTR/RTL 별도 작성 필요) */
.card {
margin-left: 16px;
padding-left: 24px;
border-left: 2px solid blue;
text-align: left;
}
[dir="rtl"] .card {
margin-left: 0;
margin-right: 16px;
padding-left: 0;
padding-right: 24px;
border-left: none;
border-right: 2px solid blue;
text-align: right;
}
/* CSS Logical Properties 방식 (하나로 처리) */
.card {
margin-inline-start: 16px; /* LTR: margin-left, RTL: margin-right */
padding-inline-start: 24px; /* LTR: padding-left, RTL: padding-right */
border-inline-start: 2px solid blue;
text-align: start; /* LTR: left, RTL: right */
}
/* 기타 Logical Properties */
.element {
/* 크기 */
inline-size: 300px; /* width (horizontal) */
block-size: 200px; /* height (vertical) */
/* 여백 */
margin-block: 16px; /* top/bottom */
margin-inline: 24px; /* left/right (방향 인식) */
/* 위치 */
inset-inline-start: 0; /* left in LTR, right in RTL */
inset-block-start: 0; /* top */
}
/* HTML dir 속성 설정 */
/* <html dir="rtl" lang="ar"> */
/* React에서 */
document.documentElement.dir = i18n.language === "ar" ? "rtl" : "ltr";
3. RTL 아이콘 미러링
// 방향성 있는 아이콘은 RTL에서 수평 미러링
function DirectionalIcon({ name, ...props }: IconProps) {
const { direction } = useDirection(); // 'ltr' | 'rtl'
const mirrorableIcons = [
"arrow-right", "arrow-left", "chevron-right", "chevron-left",
"back", "forward", "send", "attachment", "quote",
"indent", "outdent", "bullet-list",
];
const shouldMirror = direction === "rtl" && mirrorableIcons.includes(name);
return (
<Icon
name={name}
style={shouldMirror ? { transform: "scaleX(-1)" } : undefined}
{...props}
/>
);
}
// 다국어 텍스트 길이 대응
// 독일어는 영어보다 30-40% 길고, 핀란드어는 50-60% 더 길다
// 버튼, 레이블에 최소/최대 너비 설정 필수
const buttonStyles = {
minWidth: "80px", // 너무 짧은 텍스트 대응
maxWidth: "240px", // 너무 긴 텍스트 대응
whiteSpace: "nowrap", // 또는 "normal"로 줄바꿈 허용
overflow: "hidden",
textOverflow: "ellipsis",
};
마무리
RTL 지원에서 가장 많은 시간이 드는 것은 초기 설정이다. 처음부터 CSS Logical Properties를 쓰면 나중에 RTL 지원 추가가 훨씬 쉬워진다. 프로젝트 초기에 dir="rtl"을 HTML에 달아보고 레이아웃이 올바르게 뒤집히는지 확인하는 습관이 중요하다.