Localization LTR RTL 처리

KoJaem·2024년 5월 30일

다국어 지원을 할때 꼭 고려해야하는것이 있는데,
그건 바로 LTR, RTL 지원이다.

간단하게 설명해보자면,

LTR 은 왼쪽에서 오른쪽으로 읽는것 이고,

RTL 은 오른쪽에서 왼쪽으로 읽는것이다.

참고로 RTL을 사용하는 언어로는 ar(아랍어), he(히브리어) 등이 있다.


이해를 위해 예시 사진을 하나 첨부하자면 아래와 같다.

위 사진과 같이 정렬이 왼쪽과 오른쪽이 반대가 된다.
아이콘의 좌우가 바뀌지는 않는다.
당연하다고 생각할 수 있지만, 방향을 가리키는 아이콘은 바뀌어야한다.

예시 사진을 하나 더 첨부해보면,

위 사진에서 왼쪽은 LTR, 오른쪽은 RTL 인데,
방향을 가리키는 아이콘이 좌, 우가 바뀌지 않으면 RTL 에서 오른쪽을 가리키고 있어야한다.
RTL 에서 뒤로가기 버튼을 앞으로가기 버튼으로 만들고 싶다면 냅둬도 된다(?)

위 내용에 들에 대해 더 자세히 알고싶으면 아래 주소를 참고하면 된다. (+사진출처)
https://m2.material.io/design/usability/bidirectionality.html#mirroring-layout

아무튼 이러한 내용들에 대해 고려했던 내용들을 공유하고자 글을 쓰게 되었다.
(이 글은 TailwindCss 를 사용하시는 분들에게 더 도움이 될 것 같다.)


코드설명

  • tailwindCss를 사용할 때 pl, pr, ml, mr과 같은 className 을 많이 사용하는데,
    이 경우에는 LTRRTL의 경우 왼쪽과 오른쪽 값이 제대로 적용되지 않는다.

Example)

pl-[200px] (LTR)

pl-[200px] (RTL)


사진과 같이 pl-[200px], ml-[200px] 등의 값은
dir 에 의해 자동으로 적용되지 않는다

따라서 LTR, RTL의 값에 따라 CSS를 다음과 같이 수정해야한다.

<div
     ref={contentRef}
     className={`${dir === 'ltr' ? 'pl-[200px]' : 'pr-[200px]'} 
     //...
     `}>{/* ~~~ */}</div>

실제로 이런식으로 작성되어 있는 레포지토리를 봤는데,
전체 코드에 이와 같은 코드를 추가하는 것은 유지보수적으로 매우 좋지 않아보였다.

다행히 CSS 에서는 이걸 쉽게 해주는 (나름 최신문법) 속성이 있다.

inline-start, inline-end 문법

ps-[200px] (LTR)

pe-[200px] (RTL)

위와 같이 ps, pe, ms, me와 같은 속성을 사용하면 자동으로 LTR RTL이 변경된다.

따라서 pl, pr 보다는 ps, pe 등의 코드를 사용하여 LTR 및 RTL을 지원해야 한다.

  • pl, pr, ml, mr (x)
  • ps, pe, ms, me (o)

CSS 속성 값으로는
padding-inline-start, padding-inline-end,
margin-inline-start, margin-inline-end 이다.

브라우저 호환성은 아래에서 확인하자
https://caniuse.com/?search=padding-inline-start


📝 참고

LTR, RTL 은 padding, margin 뿐만 아니라 position, border, rounded, translate, icon, swiper 등에서도 고려해야할 점들이 있다.

필요한 작업 내용

(하단에 요약본이 있습니다. 아래글은 설명을 같이해서 내용이 많습니다)

  1. pl → ps , pr → pe , ml → ms , mr → me 처리

  2. absolute 에서 left → start , right → end 처리

  3. 화살표 Icon 처럼 방향을 가리키는 아이콘을
    dir 에 따라 방향 반대로 가져오는 커스텀 아이콘을 만들어서 조건부 렌더링하거나,
    rtl:rotate-180 처리하기
    아래 코드는 <ArrowLeftIcon /><CustomchevronLeftIcon /> 으로 만드는 코드이다.

export CustomchevronLeftIcon = () => {
  return dir === 'ltr' ? <ArrowLeftIcon /> : : <ArrowRightIcon />
}
  1. border-left, border-right 같은것들 border-start, border-end 로 처리하기

  2. rounded-l-[9px] , rounded-r-[9px]과 같은것들 rounded-s-[9px] ,rounded-e-[9px]로 처리하기

    ❗️ rounded 관련 주의할점

    rounded-tl-[9px] , rounded-tr-[9px] 과 같은 값들도 있다는것을 잊지말기

    tailwindCSS 에서 rounded-ts, rounded-te 를 지원하지 않으므로 ltr: , rtl 조건처리하기

    단, 위 방법대로 조건부 처리할때 또 주의할 사항이 있는데

    ltr:md:rounded-tr-xl rtl:md:rounded-tl-xl lg:rounded-none

    위와 같은 코드가 있는 경우에 반응형 사이즈가 lg 이상인 경우에도 lg:rounded-none 이 아닌, ltr:md:rounded-tr-xl 이 더 우선순위에 잡히게 된다.

    (className 순서 이슈 아님. 아래 두 코드에서 동일하게 발생)
    ltr:md:rounded-tr-xl rtl:md:rounded-tl-xl lg:rounded-none
    lg:rounded-none ltr:md:rounded-tr-xl rtl:md:rounded-tl-xl

    따라서 !important 처리하거나 lg:!rounded-none

    ltr: rtl: 코드를 추가해줘야한다. ltr:rounded-none ,rtl:~~~

    또는, tailwindcSS-rtl 플러그인 다운받으면 rounded-ts, rounded-te 사용 가능하다고 하는데, 나는 rounded-tl, rounded-tr 등을 사용하는 코드가 매우 적어서 사용해보진 않았다.)
    https://github.com/20lives/tailwindcss-rtl#readme

  1. absolute 중앙정렬할때 translate-x-[-50%] 와 같은것을 사용했다면
    ltr:translate-x-[-50%] , rtl:translate-x-[50%] 와 같이 처리하기
    -translate-x-8 와 같은것을 사용했다면 ltr:-translate-x-8 ,rtl:translate-x-8 와 같이 처리하기
  1. Swiper 에서 dir 처리가 새로고침하기 전까지 제대로 반영 안되는 현상이 일어난다면 key 값에 dir 값을 추가해주면 해결 가능하다.

내용요약

  1. plps , prpe , mlms , mrme
  2. absolute position 을 사용할때 left -> start, right -> end
  3. 방향을 가리키는 아이콘은 ltr, rtl 값에 따라 반대로 출력하기
  4. border-left -> border-start, border-right -> border-end
  5. rounded-l-[9px] -> rounded-s-[9px], rounded-r-[9px] -> rounded-e-[9px]
  6. translate-x-[-50%] -> ltr:translate-x-[-50%] rtl:translate-x-[50%] (상황에 맞게 사용).
  7. LTR, RTL 이 변경되고나서 새로고침을 하기전에 Swiper 가 제대로 동작하지 않을 수 있는데, 이럴땐 key 값에 dir 값을 같이 넣어주면 된다.





제가 놓친부분이 있거나, 더 좋은 팁이 있다면 댓글로 공유 부탁드립니다!

추가 (25.08.20)

같이 사이드 프로젝트를 하는 디자이너분께서 영어는 한 단어가 다음줄로 넘어가는 경우 - (하이픈) 을 표시하는 경우가 많다고 알려주셨다.
참고로 이분은 영국에서 유학하신 외국인보다 영어 잘하는 한국인 이다.

이런 느낌이라고 한다.

영어 책에서도 기본적으로 다 그렇게 표기된다고 하셔서, 기본적인 기능이구나 생각하여 css MDN을 찾던 중 hyphens 이라는 속성을 알게되었다.

다음에 다국어지원을 추가적으로 할일이 생기면 꼭 적용해봐야겠다.

profile
고재민

0개의 댓글