Descender mobil inkişafda — mahiyyəti, əhəmiyyəti və layouta təsiri

Müəllif: IT Sectr Dərc olunub: 2026-07-24 Oxuma vaxtı: 9 dəq

Descender — şriftin əsas xəttinin (baseline) altına enən kiçik hərfin hissəsidir. Kiril əlifbasında descender olan tipik hərflər „r”, „u”, „f”, latın əlifbasında isə „g”, „j”, „p”, „q”, „y” — dur. Descenderin uzunluğu şriftin aşağı enən elementini müəyyən edir və sətirlərarası intervalın hesablanması üçün kritik əhəmiyyət daşıyır: baseline altında kifayət qədər boşluq olmadan descender olan hərflər növbəti sətrə toxunacaq. Material Design Type Scale Guidelines (2025) məlumatlarına görə, descenderin qeyri-kafi nəzərə alınması mobil cihazlarda çoxsətirli mətndə sətirlərin toqquşmasının (collision) əsas səbəblərindən biridir.

Əsas məqamlar

  • Descender — baseline altında yerləşən hərfin aşağı enən elementi.
  • Metrika — descender UIFont.descender (iOS) və Paint.FontMetrics.descent (Android) vasitəsilə əldə edilir.
  • Line-height — descender sətrin tam hündürlüyünün hesabına daxildir və layoutda nəzərə alınmalıdır.
  • Sətir toqquşmaları — descender nəzərə alınmasa, „r”, „u”, „g” hərfləri aşağıdakı sətrə toxunur.
  • Müxtəlif şriftlər — descenderin uzunluğu qarnituralar arasında dəyişir və vizual ritmə təsir edir.

Tipoqrafiyada Descender nədir

Descender — baseline xəttinin altında yerləşən glifin hissəsidir. Hərfin əsas gövdəsi baseline üzərində dayanarkən, descender onun hüdudlarından kənara çıxaraq şriftin xarakterik siluetini yaradır. Kiril şriftlərində descender olan hərflərə „r”, „u”, „f” aid edilir — onların aşağı elementləri sətirdən aşağı enir. Latın əlifbasında da eynilə: „g”, „j”, „p”, „q”, „y” aşağı enən elementlərə malikdir.

Descenderin dərinliyi baseline-dan glifin aşağı sərhəddinə (descender-line) qədər olan məsafəni təsvir edir. Keyfiyyətli şriftlərdə bu məsafə balanslaşdırılmışdır: çox qısa descender „r” və „u” hərflərini tanımaqda çətinlik yaradır, çox uzunu isə sətirlər arasında həddindən artıq boş yer yaradaraq mətnin sıxlığını azaldır. Müxtəlif qarnituralar descenderin uzunluğunda əhəmiyyətli fərqlər nümayiş etdirir.

Qarnitura Descender / em-size Descender olan hərflərin nümunəsi
SF Pro ~0.22 r, u, g, p — balanslaşdırılmış eniş
Roboto ~0.24 r, u, g — mülayim descender
Playfair Display ~0.30 r, u, g, q — uzun dekorativ elementlər
Inter ~0.26 r, u, g — nəzərə çarpacaq dərəcədə baseline altında
Noto Sans ~0.20 r, u — qısa descender, kompakt

Google Fonts Metrics Guide (2025) məlumatlarına görə, descender dərinliyi tam em ölçüsünün (1000 FUnits) 20–25%-ni təşkil etdikdə optimal hesab olunur. 15%-dən aşağı dəyərlər descender olan hərfləri çətin seçilən edir, 30%-dən yuxarı isə sətir toqquşmalarının qarşısını almaq üçün line-height-in mütləq artırılmasını tələb edir.

Descenderin rəqəmsal metrikaları: OpenType və TrueType

Rəqəmsal şriftlərdə descender metrika cədvəllərində mənfi dəyər şəklində saxlanılır. OpenType formatında bu hhea.descent (hhea cədvəli) və sTypoDescender (OS/2 cədvəli) sahələridir. Hər iki dəyər mənfidir, çünki baseline-dən aşağıya doğru ölçülür. TrueType üçün OS/2 cədvəli usWinDescent sahəsi ilə istifadə olunur — onun dəyəri müsbətdir, lakin eyni metrikanı ifadə edir.

python
# Descenderi fontTools vasitəsilə şriftdən oxumaq
from fontTools.ttLib import TTFont

font = TTFont('Roboto-Regular.ttf')
hhea = font['hhea']
os2 = font['OS/2']

descent_hhea = hhea.descent        # -500 FUnits (Roboto)
typo_descender = os2.sTypoDescender # -500 FUnits
win_descent = os2.usWinDescent      # 500 (positive value)

# 16 pt şrift ölçüsü üçün piksellərə çevirmək
px_per_em = 16
descent_px = abs(descent_hhea) * px_per_em / 1000  # 8 px

Platformalar arasında kritik fərq: iOS render üçün hhea.descent istifadə edir, Android isə — OS/2-dən sTypoDescender. Əgər bu dəyərlər fərqlənirsə (keyfiyyətsiz konfiqurasiya edilmiş şriftlərdə belə olur), eyni mətn iOS və Android-də müxtəlif sətirlərarası intervallarla göstəriləcək. 100 FUnits fərqi (16 pt kegeldə təqribən 1.6 px) artıq vizual olaraq nəzərə çarpır.

Microsoft OpenType Specification v1.9 (2025) məlumatlarına görə, düzgün çarpaz platforma renderi üçün hhea.descent və sTypoDescender dəyərləri 50 FUnits dəqiqliklə bərabər olmalıdır. Mobil tətbiq üçün şrift seçərkən bunu fontTools və ya oxşar vasitə ilə yoxlamaq məqsədəuyğundur.

iOS-da Descender: UIFont və Core Graphics

iOS platformasında descenderin dəyəri UIFont.descender xassəsi vasitəsilə əldə edilir. Bu xassə baseline-dan şriftin aşağı kənarına (descender daxil olmaqla) qədər olan məsafəni göstərən mənfi ədəd qaytarır. Məsələn, SF Pro üçün 17 pt kegeldə descenderin dəyəri ≈ -4.2 pt olur. Ədədin modulu nə qədər böyükdürsə, şriftin aşağı enən elementləri bir o qədər uzundur.

swift
// iOS-da UIFont vasitəsilə descenderi əldə etmək
let font = UIFont.systemFont(ofSize: 17)
let descender = font.descender     // ~ SF Pro 17pt üçün -4.2 pt
let ascender = font.ascender        // ~ 16.2 pt
let lineHeight = font.lineHeight    // ~ 20.4 pt

// Descender ofseti ilə xüsusi render
let attrString = NSAttributedString(
    string: "Sample text with letter p and y",
    attributes: [.font: font]
)

// Core Text: descenderlə birlikdə bounding box almaq
let ctFont = CTFontCreateWithName(
    "SF Pro Text" as CFString, 17, nil
)
let descent = CTFontGetDescent(ctFont)  // ~4.2 pt

TextKit (NSTextStorage, NSLayoutManager) istifadə edərkən descender avtomatik olaraq lineFragmentPadding və lineFragmentRect-ə daxil edilir. Lakin Core Graphics (draw(in:)) vasitəsilə xüsusi çəkmədə koordinatları özünüz düzəltməlisiniz, descenderin modulunu konteynerin aşağı boşluğuna əlavə edərək. Bu edilməsə, descender olan hərflər çəkmə sərhədindən kənara çıxaraq kəsiləcək.

Android-də Descender: Paint və Compose

Android platformasında descenderin metrikaları Paint.FontMetrics.descent vasitəsilə əldə edilir. iOS-dan fərqli olaraq, descent dəyəri müsbətdir — bu, baseline-dan mətnin aşağı sərhəddinə qədər olan məsafədir. FontMetrics.bottom xassəsi təkcə descenderi deyil, həm də şrift dizaynerinin tövsiyə etdiyi əlavə boşluğu (leading) əhatə edir. Yalnız descenderi dəqiq nəzərə almaq üçün bottom deyil, descent istifadə edin.

kotlin
// Android-də Paint vasitəsilə descenderi əldə etmək
val paint = Paint().apply {
    textSize = 17 * density
}

val metrics = paint.fontMetrics
val descent = metrics.descent     // ~17sp üçün 4.5 px
val bottom = metrics.bottom       // ~leading ilə 5.0 px

// Descender ofseti ilə xüsusi render
val baseline = y
canvas.drawText("Nümunə: gpq", x, baseline, paint)

// Descenderlə birlikdə aşağı sərhəd
val bottomBound = baseline + descent  // düzgün aşağı sərhəd

Jetpack Compose platformasında descender TextLayoutResult vasitəsilə əldə edilə bilər. getLineBottom metodu artıq descenderi daxil edən sətrin aşağı sərhəddinin Y-koordinatını qaytarır. Müxtəlif kegelli sətirlərin xüsusi layoutunda (məsələn, endirimli qiymət və tam qiymət) descender nəzərə alınmaqla baseline üzrə hizalanma aşağı kənar üzrə hizalanmadan daha dəqiq nəticə verir.

kotlin
// Compose: mətnin aşağı sərhəddini yoxlamaq
val text = "Text with descenders: gpq"
var layoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }

Text(
    text = text,
    onTextLayout = { layoutResult = it },
    modifier = Modifier.drawBehind {
        layoutResult?.let { result ->
            val lastLine = result.lineCount - 1
            val bottom = result.getLineBottom(lastLine)
            val top = result.getLineTop(lastLine)
            // Descenderin konteyner hüdudlarını keçmədiyini yoxlayın
        }
    }
)

Google Material Design — Typography Implementation (2025) məlumatlarına görə, sabit hündürlüklü konteynerlərdə descenderin kəsilməsinin qarşısını almaq üçün cari mətndə descender olan hərflərin olmasından asılı olmayaraq, ən azı şriftin descenti qədər şaquli padding əlavə etmək lazımdır. Bu, mətn dinamik dəyişdikdə interfeysin pozulmamasına zəmanət verir.

Descender və mobil interfeyslərdə sətir toqquşmaları

Sətir toqquşması (line collision) — yuxarı sətrin hərfinin descendərinin fiziki olaraq aşağı sətrin hərfinin ascenderi ilə kəsişdiyi vəziyyətdir. Mobil interfeyslərdə bu, xüsusilə çoxsətirli başlıqlarda, məhsul kartlarında və kiçik sətirlərarası intervallı mətn bloklarında nəzərə çarpır. Uzun descenderli şriftlər və kiçik line-height istifadə edildikdə problem daha da güclənir.

Toqquşmaların qarşısını alan minimal line-height düsturla hesablana bilər: line-height = ascender + descender + 2 px ehtiyat. SF Pro üçün 17 pt kegeldə bu, line-height ≈ 16.2 + 4.2 + 2 = 22.4 pt (əmsal ~1.32) verir. Roboto üçün 16 sp kegeldə — təqribən 1.35. Əgər line-height bu dəyərdən kiçikdirsə, „r”, „u”, „g” qrupundan hərflər olan mətnlərdə toqquşmalar qaçılmazdır.

swift
// iOS: toqquşmaların qarşısını almaq üçün minimal line-height hesablayın
let font = UIFont.systemFont(ofSize: 17)
let minLineHeight = abs(font.ascender) + abs(font.descender) + 2.0

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.minimumLineHeight = minLineHeight
paragraphStyle.maximumLineHeight = minLineHeight

let attributedText = NSAttributedString(
    string: "Text with p on first line\nand y on second line",
    attributes: [
        .font: font,
        .paragraphStyle: paragraphStyle
    ]
)

Dekorativ və əlyazma şriftləri ilə işləyərkən xüsusilə diqqətli olmaq lazımdır — onların descendəri em ölçüsünün 35–40%-nə çata bilər. Belə şriftlər əsas mətn üçün nadir istifadə olunur, lakin başlıqlarda tətbiq oluna bilər. Başlıqda uzun descenderli bir hərfin belə görünməsi qonşu interfeys elementi ilə toqquşmaya səbəb ola bilər.

Descenderlə işləyərkən tipik səhvlər

Ən geniş yayılmış səhv düymələrdə və mətn sahələrində descenderin kəsilməsidir. Düymənin və ya mətn sahəsinin hündürlüyünü descenderi nəzərə almadan line-height-ə bərabər təyin etdikdə, „r”, „u” və „f” hərfləri aşağı kənardan kəsilir. Bu, xüsusilə yuvarlaq künclü sistem düymələrində nəzərə çarpır, çünki descender yuvarlaqlaşdırma sərhədindən kənara çıxa bilər.

  • Sabit hündürlüklü düymələr — düymənin hündürlüyü ceil(line-height)-ə bərabərdirsə, descender olan hərflər kəsilir. Həll yolu: yuxarı və aşağı boşluq üçün düymənin hündürlüyünü descenderin modulu qədər (17 pt sistem şrifti üçün 4–5 pt) artırın.
  • Descenderi nəzərə almayan TextField — standart UITextField və EditText descenderi nəzərə alan padding-ə malikdir, lakin xüsusi implementasiyalar tez-tez onu unudur. Kursorun və mətn blokunun „r” və „u” hərflərini kəsmədiyini yoxlayın.
  • Bir sətirdə kegellərin qarışdırılması — NSAttributedString və ya SpannableString-də müxtəlif kegelli seqmentlər varsa, böyük şriftin descendəri kiçiyinin ascenderi üzərinə düşə bilər. Kompensasiya üçün baselineOffset istifadə edin və nəticəni yoxlayın.
  • SVG-də mətn renderi — SVG-də və ya Canvas üzərində (xüsusilə web-view-da) mətn çəkərkən descender avtomatik nəzərə alınmaya bilər. Həmişə kegelin 10–15% ehtiyatı olan aşkar viewBox təyin edin.

Nielsen Norman Group — Mobile Typography Research (2025) məlumatlarına görə, mobil tətbiqlərin 41%-ində descender olan mətnin komponentin sərhədindən kənara çıxdığı ən azı bir ekran var. Bu, oxunaqlılığın 15% azalmasına və istifadəçinin tapşırığı yerinə yetirmə müddətinin artmasına gətirib çıxarır. „r”, „u”, „f” (və latın əlifbası üçün „g”, „j”, „p”) hərfləri olan mətnlə müntəzəm testinq belə problemləri inkişafın erkən mərhələlərində aşkar etməyə kömək edir.

Tez-tez verilən suallar

Descender baseline-dən nə ilə fərqlənir?

Baseline — hərflərin dayandığı üfüqi xəttdir, descender isə bu xəttin altında yerləşən hərfin hissəsidir. Baseline sətir üçün sabitdir, descender konkret hərfin xüsusiyyətidir. Bu anlayışları qarışdırmayın: baseline hizalanma üçün istifadə olunur, descender isə sətirlərarası məsafəyə təsir edir və konteynerin hündürlüyü təyin edilərkən nəzərə alınmalıdır.

Android-də şriftin descenderini necə öyrənmək olar?

View sistemi üçün Paint.getFontMetrics().descent və ya Jetpack Compose-da TextLayoutResult istifadə edin. iOS-dan fərqli olaraq, Android-də descent dəyəri müsbətdir və baseline-dan glifin aşağı sərhəddinə qədər olan məsafəni göstərir. Sətrin tam aşağı sərhəddini hesablamaq üçün descent-i baseline-in Y-koordinatına əlavə edin.

Nə üçün eyni şriftin descenderi iOS və Android-də fərqlənir?

Platformalar şrift faylından müxtəlif metrika cədvəlləri istifadə edir: iOS — hhea.descent, Android — os/2.sTypoDescender. Əgər şriftdə bu dəyərlər fərqlənirsə, render də fərqlənəcək. Hər iki dəyəri həmişə fontTools vasitəsilə yoxlayın. Keyfiyyətli sistem şriftləri (SF Pro, Roboto, Noto) hər iki platforma üçün uyğunlaşdırılmış metrikalara malikdir.

Descender toqquşmalarının qarşısını almaq üçün hansı minimal line-height lazımdır?

Minimal line-height = ascender + descender + 2 px ehtiyat. iOS-da 17 pt sistem şrifti üçün bu təqribən 22.4 pt-dir. Android-də 16 sp Roboto üçün — təqribən 22 sp. Ən yaxın tam ədədə yuvarlaqlaşdırmaq və „rufgpq” test sətri ilə yoxlamaq tövsiyə olunur — toqquşma yoxdursa, line-height kifayətdir.

Mobil tətbiqdə çox uzun descenderli şriftdən istifadə etmək olarmı?

Bəli, lakin müəyyən şərtlərlə. Uzun descenderli şriftlər (Playfair Display, dekorativ qarnituralar) başlıqlar və aksidens mətn üçün yolverilir, burada line-height dizayna zərər vermədən artırıla bilər. Əsas mətn üçün em ölçüsünün 20–25%-i descenderi olan şriftlərə (SF Pro, Roboto, Inter) üstünlük verilir ki, əlavə şaquli boşluq itməsin.

Nəticələr

  • Descender — baseline altında yerləşən hərfin aşağı enən elementi; „r”, „u”, „f” (kiril) və „g”, „j”, „p”, „q”, „y” (latın) hərflərində mövcuddur.
  • Rəqəmsal metrikalar — OpenType/TrueType formatlarında hhea.descent (iOS) və os/2.sTypoDescender (Android).
  • iOS API — UIKit üçün UIFont.descender (mənfi dəyər) və Core Text üçün CTFontGetDescent.
  • Android API — Paint.FontMetrics.descent (müsbət) və Compose-da TextLayoutResult.
  • Sətir toqquşmaları — line-height < ascender + descender + 2 px ehtiyat olduqda yaranır; „rufgpq” sətri ilə yoxlanılır.
  • Komponentlərdə kəsilmə — düymələr, mətn sahələri və xüsusi konteynerlər descenderin modulu qədər padding-ə malik olmalıdır.
  • Platforma fərqi — iOS və Android müxtəlif metrika cədvəllərindən istifadə edir, bu da şriftin hər iki platformada yoxlanılmasını tələb edir.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun