Descender adalah bagian dari huruf kecil yang turun di bawah garis dasar (baseline) font. Dalam alfabet Latin, huruf khas dengan descender adalah “g”, “j”, “p”, “q”, “y”. Panjang descender menentukan elemen bawah font dan sangat penting untuk menghitung jarak antar baris: tanpa ruang yang cukup di bawah baseline, huruf dengan descender akan mengenai baris berikutnya. Menurut Material Design Type Scale Guidelines (2025), kurangnya pertimbangan terhadap descender adalah salah satu penyebab utama tabrakan (collision) baris dalam teks multi-baris di perangkat seluler.
Poin utama
Descender adalah bagian dari glyph yang terletak di bawah garis baseline. Sementara badan utama huruf berada di baseline, descender melampauinya, menciptakan siluet khas font. Dalam font Latin, huruf “g”, “j”, “p”, “q”, “y” memiliki elemen bawah.
Kedalaman descender menggambarkan jarak dari baseline ke batas bawah glyph (descender-line). Dalam font berkualitas, jarak ini seimbang: descender yang terlalu pendek membuat huruf dengan descender sulit dikenali, sedangkan yang terlalu panjang menciptakan ruang kosong berlebihan antar baris dan mengurangi kepadatan teks. Berbagai keluarga font menunjukkan perbedaan signifikan dalam panjang descender.
| Font | Descender / em-size | Contoh huruf dengan descender |
|---|---|---|
| SF Pro | ~0.22 | g, p — jangkauan seimbang |
| Roboto | ~0.24 | g, p — descender sedang |
| Playfair Display | ~0.30 | g, q — elemen dekoratif panjang |
| Inter | ~0.26 | g, p — terlihat di bawah baseline |
| Noto Sans | ~0.20 | g — descender pendek, kompak |
Menurut Google Fonts Metrics Guide (2025), descender dianggap optimal ketika kedalamannya 20–25% dari ukuran em penuh (1000 FUnits). Nilai di bawah 15% membuat huruf dengan descender sulit dibedakan, dan di atas 30% memerlukan peningkatan line-height secara wajib untuk mencegah tabrakan baris.
Dalam font digital, descender disimpan sebagai nilai negatif dalam tabel metrik. Dalam format OpenType, ini adalah bidang hhea.descent (tabel hhea) dan sTypoDescender (tabel OS/2). Kedua nilai negatif karena diukur dari baseline ke bawah. Untuk TrueType, digunakan tabel OS/2 dengan bidang usWinDescent — nilainya positif tetapi menunjukkan metrik yang sama.
# Membaca descender dari font melalui fontTools
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)
# Konversi ke piksel untuk ukuran font 16pt
px_per_em = 16
descent_px = abs(descent_hhea) * px_per_em / 1000 # 8 px
Perbedaan kritis antar platform: iOS menggunakan hhea.descent untuk rendering, dan Android — sTypoDescender dari OS/2. Jika nilai-nilai ini berbeda (yang terjadi pada font yang dikonfigurasi dengan buruk), teks yang sama akan ditampilkan dengan jarak baris berbeda di iOS dan Android. Perbedaan 100 FUnits (sekitar 1.6 px pada ukuran 16 pt) sudah terlihat secara visual.
Menurut Microsoft OpenType Specification v1.9 (2025), untuk rendering lintas-platform yang benar, nilai hhea.descent dan sTypoDescender harus sama dengan presisi 50 FUnits. Saat memilih font untuk aplikasi seluler, hal ini perlu diperiksa melalui fontTools atau utilitas serupa.
Di iOS, nilai descender tersedia melalui properti UIFont.descender. Properti ini mengembalikan angka negatif yang menunjukkan jarak dari baseline ke tepi bawah font (termasuk descender). Misalnya, untuk SF Pro pada ukuran 17 pt, nilai descender sekitar -4.2 pt. Semakin besar nilai absolutnya, semakin panjang elemen bawah font.
// Mendapatkan descender di iOS melalui UIFont
let font = UIFont.systemFont(ofSize: 17)
let descender = font.descender // ~ -4.2 pt untuk SF Pro 17pt
let ascender = font.ascender // ~ 16.2 pt
let lineHeight = font.lineHeight // ~ 20.4 pt
// Rendering kustom dengan offset descender
let attrString = NSAttributedString(
string: "Sample text with letter p and y",
attributes: [.font: font]
)
// Core Text: mendapatkan kotak pembatas dengan descender
let ctFont = CTFontCreateWithName(
"SF Pro Text" as CFString, 17, nil
)
let descent = CTFontGetDescent(ctFont) // ~4.2 pt
Saat menggunakan TextKit (NSTextStorage, NSLayoutManager), descender secara otomatis diperhitungkan dalam lineFragmentPadding dan lineFragmentRect. Namun, pada rendering kustom melalui Core Graphics (draw(in:)), Anda perlu menyesuaikan koordinat secara mandiri dengan menambahkan nilai absolut descender ke margin bawah container. Jika tidak dilakukan, huruf dengan descender akan keluar dari batas rendering dan terpotong.
Di Android, metrik descender tersedia melalui Paint.FontMetrics.descent. Tidak seperti iOS, nilai descent positif — ini adalah jarak dari baseline ke batas bawah teks. Properti FontMetrics.bottom mencakup tidak hanya descender, tetapi juga ruang tambahan yang direkomendasikan oleh desainer font (leading). Untuk memperhitungkan hanya descender secara akurat, gunakan descent, bukan bottom.
// Mendapatkan descender di Android melalui Paint
val paint = Paint().apply {
textSize = 17 * density
}
val metrics = paint.fontMetrics
val descent = metrics.descent // ~4.5 px untuk 17sp
val bottom = metrics.bottom // ~5.0 px dengan leading
// Rendering kustom dengan offset descender
val baseline = y
canvas.drawText("Contoh: gpq", x, baseline, paint)
// Batas bawah dengan descender
val bottomBound = baseline + descent // batas bawah yang benar
Di Jetpack Compose, descender dapat diperoleh melalui TextLayoutResult. Metode getLineBottom mengembalikan koordinat Y dari batas bawah baris, yang sudah menyertakan descender. Pada tata letak kustom baris dengan ukuran berbeda (misalnya, harga diskon dan harga penuh), perataan berdasarkan baseline dengan mempertimbangkan descender memberikan hasil yang lebih akurat daripada perataan berdasarkan tepi bawah.
// Compose: memeriksa batas bawah teks
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)
// Memeriksa descender tidak melampaui batas container
}
}
)
Menurut Google Material Design — Typography Implementation (2025), untuk mencegah pemotongan descender dalam container dengan tinggi tetap, perlu menambahkan padding vertikal setidaknya sama dengan descent font, terlepas dari keberadaan huruf dengan descender dalam teks saat ini. Ini menjamin bahwa saat penggantian teks secara dinamis, antarmuka tidak akan rusak.
Tabrakan baris (line collision) — situasi di mana descender huruf baris atas secara fisik berpotongan dengan ascender huruf baris bawah. Di antarmuka seluler, ini terutama terlihat di judul multi-baris, kartu produk, dan blok teks dengan jarak baris kecil. Masalah ini diperparah dengan penggunaan font dengan descender panjang dan line-height kecil.
Line-height minimum yang mencegah tabrakan dapat dihitung dengan rumus: line-height = ascender + descender + 2 px cadangan. Untuk SF Pro pada ukuran 17 pt, ini memberikan line-height sekitar 22.4 pt (koefisien ~1.32). Untuk Roboto pada 16 sp — sekitar 1.35. Jika line-height lebih kecil dari nilai ini, tabrakan dijamin terjadi pada teks yang mengandung huruf dari grup “g”, “j”, “p”, “q”, “y”.
// iOS: menghitung line-height minimum untuk mencegah tabrakan
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
]
)
Perlu berhati-hati saat bekerja dengan font dekoratif dan tulisan tangan — descender-nya dapat mencapai 35–40% dari ukuran em. Font semacam itu jarang digunakan untuk teks utama, tetapi dapat diterapkan pada judul. Bahkan satu kemunculan huruf dengan descender panjang dalam judul dapat menyebabkan tabrakan dengan elemen antarmuka di sekitarnya.
Kesalahan yang paling umum adalah pemotongan descender di tombol dan bidang teks. Ketika kita mengatur tinggi tombol atau bidang teks sama dengan line-height, tanpa mempertimbangkan descender, huruf dengan descender terpotong di tepi bawah. Ini terutama terlihat pada tombol sistem dengan sudut membulat, di mana descender dapat melampaui batas pembulatan.
Menurut Nielsen Norman Group — Mobile Typography Research (2025), 41% aplikasi seluler memiliki setidaknya satu layar di mana teks dengan descender melampaui batas komponen. Hal ini menyebabkan penurunan keterbacaan sebesar 15% dan peningkatan waktu penyelesaian tugas oleh pengguna. Pengujian rutin dengan teks yang mengandung huruf “g”, “j”, “p”, “q”, “y” membantu mengidentifikasi masalah tersebut pada tahap awal pengembangan.
Pertanyaan yang sering diajukan
Baseline adalah garis horizontal tempat huruf berdiri, sedangkan descender adalah bagian huruf yang berada di bawah garis ini. Baseline adalah konstanta untuk satu baris, descender adalah properti huruf tertentu. Jangan campur adukkan konsep ini: baseline digunakan untuk perataan, sedangkan descender memengaruhi jarak antar baris dan memerlukan perhatian saat mengatur tinggi container.
Gunakan Paint.getFontMetrics().descent untuk sistem View atau TextLayoutResult di Jetpack Compose. Tidak seperti iOS, nilai descent di Android positif dan menunjukkan jarak dari baseline ke batas bawah glyph. Untuk menghitung batas bawah baris penuh, tambahkan descent ke koordinat Y baseline.
Platform menggunakan tabel metrik yang berbeda dari file font: iOS — hhea.descent, Android — os/2.sTypoDescender. Jika nilai-nilai ini dalam font berbeda, rendering akan berbeda. Selalu periksa kedua nilai melalui fontTools. Font sistem berkualitas (SF Pro, Roboto, Noto) memiliki metrik yang konsisten untuk kedua platform.
Line-height minimum line-height = ascender + descender + 2 px cadangan. Untuk font sistem 17 pt di iOS, ini sekitar 22.4 pt. Di Android untuk 16 sp Roboto — sekitar 22 sp. Disarankan untuk membulatkan ke bilangan bulat terdekat dan memeriksa dengan string uji “gpq” — jika tidak ada tabrakan, line-height cukup.
Ya, tetapi dengan syarat. Font dengan descender panjang (Playfair Display, font dekoratif) dapat diterima untuk judul dan teks aksiden, di mana line-height dapat ditingkatkan tanpa merusak desain. Untuk teks utama, font dengan descender 20–25% dari ukuran em (SF Pro, Roboto, Inter) lebih disukai untuk menghemat ruang vertikal yang tidak perlu.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga