아랍어 RTL 웹은(는) 무엇을 하나요?
아랍어 페이지가 자연스럽게 읽히고, 375px에서 레이아웃이 올바르게 표시되며, 숫자, URL 또는 영어 단어가 절대 뒤섞이지 않도록 하는 체크리스트입니다. 작업과 관련된 모든 섹션을 적용한 후 최종 체크리스트를 실행하세요.
1. 방향 및 언어
- 루트 요소:
<html lang="ar" dir="rtl">을 HTML에 작성합니다(자바스크립트로 추가하지 않음). 첫 번째 페인트가 이미 RTL이 되도록 합니다. dir을 CSSdirection: rtl로 대체하지 마십시오.dir속성은 양방향 텍스트(bidi), 양식 컨트롤 및 스크린 리더도 제어합니다.- 아랍어 페이지 내의 영어 블록:
<p lang="en" dir="ltr">. 사용자가 입력하는 텍스트(이름, 댓글, 채팅)는dir="auto"를 사용합니다.
2. 논리적 속성을 사용한 레이아웃
물리적 left/right는 절대 반전되지 않습니다. 논리적 속성을 사용하면 하나의 스타일시트가 두 방향 모두에서 작동합니다.
| 사용 금지 | 사용 권장 |
|---|---|
margin-left, padding-right | margin-inline-start, padding-inline-end |
left: 0, right: 0 | inset-inline-start: 0, inset-inline-end: 0 |
text-align: left | text-align: start |
border-left | border-inline-start |
border-top-left-radius | border-start-start-radius |
float: left | float: inline-start |
- Flexbox와 grid는 이미
dir을 따릅니다. RTL에서flex-direction: row는 오른쪽에서 시작합니다. RTL을 "고치기" 위해row-reverse를 절대 추가하지 마십시오. transform: translateX(),background-position및 box-shadow 오프셋은 물리적 속성입니다. 필요한 경우:dir(rtl)또는[dir="rtl"]로 반전시킵니다.- Tailwind:
ms-*,me-*,ps-*,pe-*,start-*,end-*,text-start및rtl:/ltr:변형을 사용합니다.
3. 아랍어 웹 폰트
- 아랍어용으로 디자인된 글꼴군을 선택하십시오(IBM Plex Sans Arabic, Noto Naskh Arabic, Noto Sans Arabic, Tajawal, Cairo, Almarai, Readex Pro). Aref Ruqaa와 같은 장식용 글꼴은 제목에만 사용하십시오.
- WOFF2 파일을 자체 호스팅하십시오. 타사 요청이 없고, 오프라인에서 작동하며, 폰트 CDN으로 정보가 유출되지 않습니다. 라이선스를 확인하십시오(OFL은 자체 호스팅을 허용합니다).
font-display: swap을 사용하고unicode-range로 아랍어와 라틴어 파일을 분할하여 각 페이지가 필요한 것만 다운로드하도록 하십시오:
@font-face { font-family: 'Plex'; font-weight: 400; font-display: swap;
src: url(plex-400-ar.woff2) format('woff2');
unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200E, U+FB50-FDFF, U+FE70-FEFC; }
@font-face { font-family: 'Plex'; font-weight: 400; font-display: swap;
src: url(plex-400-lat.woff2) format('woff2');
unicode-range: U+0000-00FF, U+2000-206F; }
body { font: 400 17px/1.75 'Plex', 'Segoe UI', Tahoma, sans-serif; }
- 아랍어는 구별 부호(diacritics)와 내림자(descenders)를 위해 더 큰 줄 높이(1.6~1.8)와 라틴 텍스트보다 약간 더 큰 글꼴 크기가 필요합니다.
- 아랍어에
letter-spacing을 절대 사용하지 마십시오(글자 연결이 끊어짐).text-transform이나 가짜 이탤릭을 사용하지 마십시오. 좁은 열에서text-align: justify를 피하십시오. - tatweel(U+0640)로 단어를 늘리지 마십시오. 검색 및 복사-붙여넣기가 손상됩니다.
4. Bidi: 숫자, URL 및 아랍어 내 영어
유니코드 bidi 알고리즘은 숫자 및 라틴 텍스트 옆의 중립 문자를 재정렬합니다. RTL 문단의 두 가지 고전적인 버그:
- 전화번호
+966 55 123 4567이 숫자 그룹이 역순으로 표시됨:4567 123 55 +966. - 시간 범위
10:00 - 12:00이12:00 - 10:00으로 표시됨.
수정 방법:
- 방향을 알 수 없는 삽입 값 주변에
<bdi>사용:مرحبًا <bdi>${userName}</bdi>، أهلًا بك. - 항상 LTR인 값에
dir="ltr"사용:<span dir="ltr">+966 55 123 4567</span>, URL, 이메일, 파일 경로, IBAN,<code dir="ltr">,<pre dir="ltr">. - 반복 패턴에 대한 CSS:
.num, .code { unicode-bidi: isolate; }.<bdi>는 기본적으로 격리(isolate)합니다. - 이메일, URL 및 전화번호 입력:
<input type="email" dir="ltr">. - 마크업이 불가능한 경우(문서 제목, 알림, 일반 문자열), 유니코드 격리 문자 사용: FSI U+2068 ... PDI U+2069, 또는 알려진 LTR 텍스트의 경우 LRI U+2066 ... PDI.
5. 숫자: 페이지당 하나의 체계
- 라틴 숫자
0-9또는 아랍-인도 숫자٠-٩(U+0660~U+0669) 중 하나를 선택하여 표, 차트 및 날짜를 포함한 페이지 전체에 일관되게 사용하십시오. - 혼합은 독자를 혼란스럽게 하며(둘 다 있는 표는 실수처럼 보임), 검색("15"가 "١٥"와 일치하지 않음), 정렬 및 스프레드시트로의 복사-붙여넣기를 손상시킵니다.
- 페르시아 숫자
۰-۹(U+06F0~U+06F9)는 다른 코드 포인트입니다. 섞어 사용하지 마십시오. Intl기본값은 로케일과 엔진 버전에 따라 다릅니다. Node 24에서ar-SA는 아랍-인도 숫자로 형식화되는 반면, 일반ar은 라틴 숫자를 제공합니다. 번호 매기기 체계를 명시적으로 설정하십시오:new Intl.NumberFormat('ar-SA-u-nu-latn')또는'ar-SA-u-nu-arab'.- 아랍-인도 숫자의 경우 소수 구분 기호는
٫(U+066B)이고 천 단위 구분 기호는٬(U+066C)입니다. - 실제 함정: 아랍-인도 숫자 옆에 구분 기호로 사용된 가운데 점(U+00B7)은 아랍-인도 0(U+0660)처럼 보이며, 이 역시 작은 점입니다. "12, 구분 기호, 3"은 "1203"으로 읽힙니다. 대신 아랍어 쉼표 «،», 슬래시 또는 추가 간격(CSS
gap)으로 구분하십시오.
6. 아랍어 문장 부호
,;?대신،(U+060C),؛(U+061B) 및؟(U+061F)를 사용하십시오. 마침표와!는 공유됩니다.- 문장 부호 앞에 공백을 두지 말고, 뒤에 한 칸의 공백을 두십시오: «كيف حالك؟» ( «كيف حالك ؟»아님).
- 페이지당 하나의 인용 스타일(«...» 또는 "...")을 선택하십시오.
7. 아이콘 및 미러링
방향이나 순서를 나타내는 아이콘을 미러링하십시오: 뒤로 및 다음 화살표, 목록 및 이동 경로의 셰브론, 스테퍼 및 진행 방향, "보내기", 텍스트 들여쓰기 및 목록 아이콘.
미러링하지 마십시오: 로고 및 브랜드 마크, 미디어 컨트롤(재생, 되감기, 빨리 감기), 시계 및 타이머, 확인 표시, 사진 및 라틴 문자나 숫자를 포함하는 아이콘.
:dir(rtl) .icon-dir { transform: scaleX(-1); } /* opt-in 클래스, 절대 전역으로 사용 금지 */
8. 아랍어 키보드의 숫자 입력
type="number"보다<input inputmode="decimal" autocomplete="off">를 선호하십시오. number 입력의 값은 ASCII 숫자로만 유효하므로 아랍-인도 숫자는 빈 문자열로 반환될 수 있으며, 스피너도 추가됩니다.- 사용자는
٠-٩, 아랍어 소수 구분 기호٫, 때로는 페르시아 숫자를 입력합니다.Number()로 변환하기 전에 정규화하십시오:
function parseArabicNumber(raw) {
const s = String(raw ?? '').trim()
.replace(/[٠-٩]/g, (d) => d.charCodeAt(0) - 0x0660)
.replace(/[۰-۹]/g, (d) => d.charCodeAt(0) - 0x06F0)
.replace(/٫/g, '.')
.replace(/٬/g, '');
if (s === '') return null; // Number('')는 0이므로 먼저 비어 있는지 확인
const n = Number(s);
return Number.isFinite(n) ? n : NaN;
}
parseArabicNumber('٩٥٫٥'); // 95.5
- 입력된
,를 어떻게 처리할지(소수점 또는 천 단위 구분 기호) 결정하고 문서화하십시오. - 유효성 검사 메시지를 아랍어로 표시하고,
aria-invalid를 설정하며,aria-describedby로 메시지를 연결하십시오. - 아랍어 이름을
new Intl.Collator('ar').compare로 정렬하십시오. 검색의 경우 쿼리와 데이터 모두에서 알레프 형태(أ إ آ를 ا로)를 정규화하고, tashkeel 및 tatweel을 제거하십시오.
9. 테스트
- 375px 너비(가능하면 320px)에서 테스트하십시오.
document.documentElement.scrollWidth <= innerWidth를 확인하십시오. - 제목과 버튼에서 «والمستشفيات» 또는 «باستخداماتها»와 같은 긴 아랍어 단어(연결된 문자 포함)를 테스트하십시오. 제목과 카드에는
overflow-wrap: anywhere를, flex 및 grid 자식에는min-width: 0을 사용하십시오. - 로렘 입숨이 아닌 영어와 숫자가 혼합된 실제 아랍어 콘텐츠를 사용하십시오.
- iOS의 Safari와 Android의 Chrome에서 확인하고, 200% 줌과 키보드 포커스 순서(Tab이 오른쪽에서 왼쪽으로 이동)를 확인하십시오.
10. [hidden] 함정
hidden 속성은 사용자 에이전트 display: none일 뿐입니다. .card { display: flex }와 같은 작성자 규칙이 이를 재정의하므로 el.hidden = true가 조용히 작동을 멈춥니다. 기본 스타일시트에 다음을 추가하십시오:
[hidden] { display: none !important; }
최종 체크리스트
- 소스에
<html lang="ar" dir="rtl">이 있는지 확인 - 새 CSS에 물리적 left/right 속성이 남아 있지 않은지 확인
- 자체 호스팅된 아랍어 폰트,
font-display: swap,unicode-range분할 - 전화번호, URL, 코드 및 사용자 이름이 격리되었는지 확인
- 하나의 숫자 체계; 아랍-인도 숫자 옆에 가운데 점 없음
- 아랍어 문장 부호, 앞에 공백 없음
- 방향성 아이콘만 미러링됨
- 숫자 입력이
٠-٩및٫을 수용하는지 확인 - 375px에서 가로 스크롤 없음; 긴 단어 줄바꿈 처리
-
[hidden] { display: none !important; }가 있는지 확인