RTL·다국어 UI 설계: 아랍어·히브리어 시장을 위한 레이아웃 반전 설계

UX 디자인

RTL 디자인다국어 UI현지화국제화CSS Logical Properties

이 글은 누구를 위한 것인가

  • 중동·이스라엘 시장 진출을 위해 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에 달아보고 레이아웃이 올바르게 뒤집히는지 확인하는 습관이 중요하다.