Вэбсайт дээр Ө, Ү үсэг яагаад өөр харагддаг вэ?

4 минутад уншина

Энэ блогоо хийж байхдаа нэг сонин зүйл анзаарсан. Монгол текст ерөнхийдөө зүгээр харагдаж байсан ч Ө, Ү үсэг бусад үсгүүдээсээ арай өөр байлаа: жаахан нарийхан, жаахан нимгэн, өндөр нь ч бага зэрэг зөрүүтэй. Илт эвдэрсэн зүйл байхгүй болохоор анзаарахгүй өнгөрөхөд амархан.

Sans-serif фонт дээр ялгаа нь бага мэдэгддэг тул илүү тод харагдах serif фонт (Noto Serif) дээр үзүүлье. Фонтын файл, текст хоёулаа ижил. Зөвхөн ачаалсан арга нь өөр:

Noto Serif фонтоор бичсэн «Өвөл Үүл»: зөвхөн cyrillic хэсэгтэй үед Ө, Ү sans-serif үсгээр, cyrillic-ext нэмсэн үед фонттойгоо таарч харагдана

Дээд мөрөнд байгаа улаан Ө, Ү үсэгт serif (үсгийн үзүүрийн жижиг зураас) байхгүй. Эдгээр нь вэб фонтоос биш, системийн нөөц (fallback) фонтоос ирсэн. Энд Arial-тай төстэй фонт. Sans-serif вэб фонт дээр зөрүү нь бага ч гэсэн байсаар л байдаг: өргөн, зураас, өндөр нь өөр.

Яагаад ингэдэг вэ?

Вэб фонтыг ихэвчлэн subset гэж нэрлэгддэг жижиг файлуудад хуваадаг. Файл бүр тодорхой хэсэг тэмдэгтийг агуулна. Google Fonts, Fontsource зэрэг ихэнх хэрэгсэл ингэж хуваадаг. Ингэснээр хуудас зөвхөн өөрт хэрэгтэй тэмдэгтүүдээ татна.

Кирилл үсгийг хоёр хэсэгт хуваадаг:

SubsetUnicode муж (хялбарчилсан)Агуулдаг үсгүүд
cyrillicU+0400–045F, U+0490–0491, U+04B0–04B1Орос цагаан толгой, Ё, Ъ, украин Ґ, казах Ұ
cyrillic-extU+0460–052FӨ ө (U+04E8, U+04E9), Ү ү (U+04AE, U+04AF) болон бусад үсэг

Монгол цагаан толгой нь орос цагаан толгой дээр хоёр нэмэлт үсэг, Ө болон Ү-г нэмсэн байдаг. Энэ хоёр үсэг хоёулаа cyrillic-ext-д байдаг. Сонирхолтой нь үндсэн хэсэгт казах Ұ (U+04B0) үсэг ордог. Тэр нь Ү (U+04AE)-тэй зэрэгцээ байрлалтай ч Ү өөрөө ордоггүй.

Тэгэхээр зөвхөн cyrillic-г ачаалбал монгол 35 үсгийн 33 нь таны фонтоос, үлдсэн хоёр нь өөр газраас ирнэ.

Хөтөч яг юу хийдэг вэ?

@font-face дүрэм бүр unicode-range-тэй. Хөтөч тэмдэгт бүрийн хувьд тухайн тэмдэгтийг агуулсан фонт файлыг хайдаг:

flowchart TD
  A[Ө тэмдэгт, U+04E8] --> B{Аль нэг вэб фонт файлын unicode-range-д орох уу?}
  B -- тийм --> C[Тэр файлыг татаж ашиглана]
  B -- үгүй --> D[font-family доторх дараагийн фонтыг оролдоно]
  D --> E[Системийн нөөц фонт: Arial, Segoe UI, DejaVu Sans гэх мэт]

Энэ нь үг тус бүрээр биш, тэмдэгт тус бүрээр явагддаг. Тийм учраас үгийн бусад хэсэг таны фонтоор үлдэж, зөвхөн Ө, Ү өөр харагддаг.

Засах арга

Ямар ч технологи ашигласан дүрэм нь нэг: таны фонтын аль нэг @font-face дүрэм U+04AE–04AF (Ү ү) болон U+04E8–04E9 (Ө ө) мужийг хамарсан байх ёстой. Энэ нь ихэвчлэн cyrillic-ийн хажууд cyrillic-ext хэсгийг ачаалах, эсвэл эдгээр үсгийг агуулсан фонт файлыг тэднийг хассан unicode-range-гүйгээр ашиглах гэсэн үг.

Энгийн CSS (өөрөө байршуулсан фонт)

Фонтын файлуудаа өөрөө байршуулдаг бол өргөтгөсөн файлд зориулж бас @font-face дүрэм нэмнэ:

@font-face {
	font-family: 'MyFont';
	src: url('/fonts/myfont-cyrillic.woff2') format('woff2');
	unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
	font-family: 'MyFont';
	src: url('/fonts/myfont-cyrillic-ext.woff2') format('woff2');
	unicode-range: U+0460-052F;
}

Бүх үсгийг агуулсан ганц фонт файл ашиглаж байгаа бол unicode-range-г огт бичихгүй байж болно. Тэгвэл хөтөч тухайн файлд байгаа бүх тэмдэгтэд түүнийг ашиглана.

“subsets” тохиргоотой хэрэгслүүд

Олон хэрэгсэл аль subset хэрэгтэйг асуудаг. cyrillic гэж харсан газар бүрт хажууд нь cyrillic-ext-г нэмээрэй:

ХэрэгсэлХаана
Fontsource (subset файлууд)@fontsource/<font>/cyrillic-ext-400.css-г бас import хийнэ
Next.js next/fontsubsets: ['latin', 'cyrillic', 'cyrillic-ext']
Astro Fonts APIsubsets: ['latin', 'cyrillic', 'cyrillic-ext']
Фонт татах сайт, туслах хэрэгслүүдCyrillic-ийн хамт Cyrillic Extended-г бас сонгоно

Google Fonts холбоос

Одоогийн CSS API (fonts.googleapis.com/css2?...) фонтын бүх subset-ийг тус тусын unicode-range-тэй нь буцаадаг. Тиймээс хөтөч cyrillic-ext-г өөрөө авчихна. Асуудал ихэвчлэн тэр дүрмүүдээс заримыг нь л өөрийн CSS рүү хуулсан, эсвэл фонт өөрөө өргөтгөсөн хэсэггүй үед гардаг. Хуучин API-г &subset= параметртэй ашиглаж байгаа бол тэнд cyrillic-ext-г нэмээрэй.

Зөвхөн монгол үсэгтэй өөрийн subset хийх

cyrillic-ext дотор өөр олон хэлний үсэг бас ордог тул монгол хэлэнд хэрэгтэйгээс том. Файлын хэмжээ чухал бол fonttools ашиглаад фонтоо яг хэрэгтэй тэмдэгтүүдээр нь багасгаж болно:

pip install fonttools brotli
pyftsubset MyFont.ttf \
  --unicodes="U+0000-00FF,U+0400-045F,U+04AE-04AF,U+04E8-04E9,U+2116" \
  --flavor=woff2 --output-file=myfont-mn.woff2

Ингэснээр латин, орос цагаан толгой, Ө, Ү-г агуулсан нэг жижиг файлтай болно. Noto Serif фонтын хувьд файлын хэмжээ 712 KB (бүтэн TTF)-аас 25 KB болж буурсан.

Зөвлөгөө

Монгол сайтад фонт сонгохдоо зөвхөн Cyrillic биш, Cyrillic Extended-г дэмждэг эсэхийг нь шалгаарай. Зарим алдартай фонт зөвхөн латин үсэг дэмждэг, зарим нь кирилл дэмждэг ч нэмэлт үсгүүдгүй байдаг.

Өөрийн сайтаа яаж шалгах вэ?

  1. Хуудсаа Chrome эсвэл Edge дээр нээгээд Ө, Ү орсон үг дээр баруун товшиж Inspect гэж сонгоно.
  2. Computed таб руу орж, хамгийн доод хэсэгт байгаа Rendered Fonts-г харна.
  3. Тэнд таны вэб фонтоос гадна системийн фонт (жишээ нь Arial — 2 glyphs) харагдаж байвал зарим тэмдэгт нөөц фонт руу шилжсэн гэсэн үг.

Firefox дээр мөн ийм мэдээллийг inspector-ийн Fonts хэсгээс харж болно.

Эсвэл сайтынхаа CSS-ийг нээж, U+0460-052F мужийг агуулсан unicode-range байгаа эсэхийг хайж болно. Тийм муж бүхий @font-face дүрэм байхгүй бол Ө, Ү таны вэб фонтоос ирэхгүй байна гэсэн үг.

Товчхондоо

  • Монгол хэлэнд кирилл үсгийн хоёр хэсэг хэрэгтэй: cyrillic болон cyrillic-ext.
  • Ө, Ү нь cyrillic-ext-д байдаг. Үүнгүйгээр хөтөч энэ хоёр үсгийг чимээгүйхэн нөөц фонтоор зурна.
  • Аль нэг @font-face дүрэм Ө, Ү-г хамарсан эсэхийг шалгаарай: subset тохируулдаг газар бүрт cyrillic-ext-г нэмээд, DevTools-ийн Rendered Fonts хэсгээс баталгаажуулна.