Descender είναι το τμήμα ενός πεζού γράμματος που εκτείνεται κάτω από τη γραμμή βάσης (baseline) της γραμματοσειράς. Στο λατινικό αλφάβητο, τυπικά γράμματα με descender είναι τα “g”, “j”, “p”, “q”, “y”. Το μήκος του descender καθορίζει το κάτω εξέχον στοιχείο της γραμματοσειράς και είναι κρίσιμο για τον υπολογισμό του διάστιχου: χωρίς επαρκή χώρο κάτω από τη baseline, τα γράμματα με descender θα ακουμπούν την επόμενη γραμμή. Σύμφωνα με το Material Design Type Scale Guidelines (2025), η ανεπαρκής λήψη υπόψη του descender είναι μία από τις κύριες αιτίες σύγκρουσης (collision) γραμμών σε πολύγραμμο κείμενο σε κινητές συσκευές.
Κύρια σημεία
Descender είναι το τμήμα μιας γλυφής που βρίσκεται κάτω από τη γραμμή baseline. Ενώ το κύριο σώμα του γράμματος στέκεται στη baseline, το descender εκτείνεται πέρα από αυτήν, δημιουργώντας ένα χαρακτηριστικό περίγραμμα της γραμματοσειράς. Στις λατινικές γραμματοσειρές, τα γράμματα “g”, “j”, “p”, “q”, “y” έχουν κάτω στοιχεία.
Το βάθος του descender περιγράφει την απόσταση από τη baseline μέχρι το κάτω όριο της γλυφής (descender-line). Σε ποιοτικές γραμματοσειρές, αυτή η απόσταση είναι ισορροπημένη: ένα πολύ κοντό descender καθιστά τα γράμματα με descender δύσκολα αναγνωρίσιμα, ενώ ένα πολύ μακρύ δημιουργεί υπερβολικό κενό μεταξύ των γραμμών και μειώνει την πυκνότητα του κειμένου. Διαφορετικές οικογένειες γραμματοσειρών εμφανίζουν σημαντικές διαφορές στο μήκος του descender.
| Γραμματοσειρά | Descender / em-size | Παραδείγματα γραμμάτων με descender |
|---|---|---|
| SF Pro | ~0.22 | g, p — ισορροπημένη προέκταση |
| Roboto | ~0.24 | g, p — μέτριος descender |
| Playfair Display | ~0.30 | g, q — μακριά διακοσμητικά στοιχεία |
| Inter | ~0.26 | g, p — αισθητά κάτω από τη baseline |
| Noto Sans | ~0.20 | g — κοντός descender, συμπαγής |
Σύμφωνα με το Google Fonts Metrics Guide (2025), το descender θεωρείται βέλτιστο όταν το βάθος του είναι 20–25% του πλήρους μεγέθους em (1000 FUnits). Οι τιμές κάτω από 15% καθιστούν τα γράμματα με descender δύσκολα διακριτά, ενώ πάνω από 30% απαιτούν υποχρεωτική αύξηση του line-height για την αποφυγή συγκρούσεων γραμμών.
Στις ψηφιακές γραμματοσειρές, το descender αποθηκεύεται ως αρνητική τιμή στους πίνακες μετρικών. Στη μορφή OpenType, αυτά είναι τα πεδία hhea.descent (πίνακας hhea) και sTypoDescender (πίνακας OS/2). Και οι δύο τιμές είναι αρνητικές επειδή μετρώνται από τη baseline προς τα κάτω. Για το TrueType χρησιμοποιείται ο πίνακας OS/2 με το πεδίο usWinDescent — η τιμή του είναι θετική, αλλά υποδηλώνει την ίδια μετρική.
# Ανάγνωση descender από τη γραμματοσειρά μέσω 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)
# Μετατροπή σε pixel για μέγεθος γραμματοσειράς 16pt
px_per_em = 16
descent_px = abs(descent_hhea) * px_per_em / 1000 # 8 px
Η κρίσιμη διαφορά μεταξύ πλατφορμών: το iOS χρησιμοποιεί hhea.descent για απόδοση, ενώ το Android — sTypoDescender από το OS/2. Εάν αυτές οι τιμές διαφέρουν (πράγμα που συμβαίνει σε κακώς ρυθμισμένες γραμματοσειρές), το ίδιο κείμενο θα εμφανίζεται με διαφορετικό διάστιχο σε iOS και Android. Μια διαφορά 100 FUnits (περίπου 1.6 px σε μέγεθος 16 pt) είναι ήδη οπτικά αισθητή.
Σύμφωνα με την Microsoft OpenType Specification v1.9 (2025), για σωστή απόδοση μεταξύ πλατφορμών, οι τιμές hhea.descent και sTypoDescender πρέπει να είναι ίσες με ακρίβεια 50 FUnits. Κατά την επιλογή γραμματοσειράς για εφαρμογή κινητού, αυτό πρέπει να ελέγχεται μέσω του fontTools ή παρόμοιου βοηθήματος.
Στο iOS, η τιμή του descender είναι διαθέσιμη μέσω της ιδιότητας UIFont.descender. Αυτή η ιδιότητα επιστρέφει έναν αρνητικό αριθμό που δείχνει την απόσταση από τη baseline μέχρι το κάτω άκρο της γραμματοσειράς (συμπεριλαμβανομένου του descender). Για παράδειγμα, για το SF Pro σε μέγεθος 17 pt, η τιμή του descender είναι περίπου -4.2 pt. Όσο μεγαλύτερη είναι η απόλυτη τιμή, τόσο μακρύτερα είναι τα κάτω στοιχεία της γραμματοσειράς.
// Λήψη descender στο iOS μέσω UIFont
let font = UIFont.systemFont(ofSize: 17)
let descender = font.descender // ~ -4.2 pt για SF Pro 17pt
let ascender = font.ascender // ~ 16.2 pt
let lineHeight = font.lineHeight // ~ 20.4 pt
// Προσαρμοσμένη απόδοση με μετατόπιση descender
let attrString = NSAttributedString(
string: "Sample text with letter p and y",
attributes: [.font: font]
)
// Core Text: λήψη πλαισίου οριοθέτησης με descender
let ctFont = CTFontCreateWithName(
"SF Pro Text" as CFString, 17, nil
)
let descent = CTFontGetDescent(ctFont) // ~4.2 pt
Κατά τη χρήση του TextKit (NSTextStorage, NSLayoutManager), το descender λαμβάνεται αυτόματα υπόψη στο lineFragmentPadding και στο lineFragmentRect. Ωστόσο, κατά την προσαρμοσμένη απόδοση μέσω Core Graphics (draw(in:)), πρέπει να προσαρμόζετε ανεξάρτητα τις συντεταγμένες, προσθέτοντας την απόλυτη τιμή του descender στο κάτω περιθώριο του δοχείου. Εάν αυτό δεν γίνει, τα γράμματα με descender θα βγουν έξω από τα όρια απόδοσης και θα κοπούν.
Στο Android, οι μετρικές του descender είναι διαθέσιμες μέσω του Paint.FontMetrics.descent. Σε αντίθεση με το iOS, η τιμή descent είναι θετική — αυτή είναι η απόσταση από τη baseline μέχρι το κάτω όριο του κειμένου. Η ιδιότητα FontMetrics.bottom περιλαμβάνει όχι μόνο το descender, αλλά και τον πρόσθετο χώρο που συνιστάται από τον σχεδιαστή της γραμματοσειράς (leading). Για ακριβή λήψη υπόψη μόνο του descender, χρησιμοποιήστε το descent, όχι το bottom.
// Λήψη descender στο Android μέσω Paint
val paint = Paint().apply {
textSize = 17 * density
}
val metrics = paint.fontMetrics
val descent = metrics.descent // ~4.5 px για 17sp
val bottom = metrics.bottom // ~5.0 px με leading
// Προσαρμοσμένη απόδοση με μετατόπιση descender
val baseline = y
canvas.drawText("Παράδειγμα: gpq", x, baseline, paint)
// Κάτω όριο με descender
val bottomBound = baseline + descent // σωστό κάτω όριο
Στο Jetpack Compose, το descender μπορεί να ληφθεί μέσω του TextLayoutResult. Η μέθοδος getLineBottom επιστρέφει τη συντεταγμένη Y του κάτω ορίου της γραμμής, η οποία περιλαμβάνει ήδη το descender. Στην προσαρμοσμένη διάταξη γραμμών με διαφορετικά μεγέθη (π.χ., τιμή με έκπτωση και πλήρης τιμή), η στοίχηση βάσει baseline με λήψη υπόψη του descender δίνει πιο ακριβές αποτέλεσμα από τη στοίχηση βάσει κάτω άκρου.
// Compose: έλεγχος κάτω ορίου κειμένου
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)
// Έλεγχος ότι το descender δεν υπερβαίνει τα όρια του δοχείου
}
}
)
Σύμφωνα με το Google Material Design — Typography Implementation (2025), για την αποφυγή κοπής του descender σε δοχεία σταθερού ύψους, πρέπει να προστίθεται κάθετο padding τουλάχιστον ίσο με το descent της γραμματοσειράς, ανεξάρτητα από την παρουσία γραμμάτων με descender στο τρέχον κείμενο. Αυτό εγγυάται ότι κατά τη δυναμική αντικατάσταση κειμένου, η διεπαφή δεν θα σπάσει.
Σύγκρουση γραμμών (line collision) — κατάσταση κατά την οποία το descender ενός γράμματος της πάνω γραμμής τέμνει φυσικά το ascender ενός γράμματος της κάτω γραμμής. Στις κινητές διεπαφές, αυτό είναι ιδιαίτερα αισθητό σε πολύγραμμες επικεφαλίδες, κάρτες προϊόντων και μπλοκ κειμένου με μικρό διάστιχο. Το πρόβλημα επιδεινώνεται με τη χρήση γραμματοσειρών με μακρύ descender και μικρό line-height.
Το ελάχιστο line-height που αποτρέπει τις συγκρούσεις μπορεί να υπολογιστεί με τον τύπο: line-height = ascender + descender + 2 px απόθεμα. Για το SF Pro σε μέγεθος 17 pt, αυτό δίνει line-height περίπου 22.4 pt (συντελεστής ~1.32). Για το Roboto σε 16 sp — περίπου 1.35. Εάν το line-height είναι μικρότερο από αυτήν την τιμή, οι συγκρούσεις είναι εγγυημένες σε κείμενα που περιέχουν γράμματα από την ομάδα “g”, “j”, “p”, “q”, “y”.
// iOS: υπολογισμός ελάχιστου line-height για αποφυγή συγκρούσεων
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
]
)
Ιδιαίτερη προσοχή πρέπει να δίνεται κατά την εργασία με διακοσμητικές και χειρόγραφες γραμματοσειρές — το descender τους μπορεί να φτάσει το 35–40% του μεγέθους em. Τέτοιες γραμματοσειρές χρησιμοποιούνται σπάνια για κύριο κείμενο, αλλά μπορούν να εφαρμοστούν σε επικεφαλίδες. Ακόμη και μία μόνο εμφάνιση ενός γράμματος με μακρύ descender σε μια επικεφαλίδα μπορεί να προκαλέσει σύγκρουση με ένα γειτονικό στοιχείο διεπαφής.
Το πιο συνηθισμένο λάθος είναι η κοπή του descender σε κουμπιά και πεδία κειμένου. Όταν ορίζουμε το ύψος ενός κουμπιού ή πεδίου κειμένου ίσο με το line-height, χωρίς να λάβουμε υπόψη το descender, τα γράμματα με descender κόβονται στο κάτω άκρο. Αυτό είναι ιδιαίτερα αισθητό σε κουμπιά συστήματος με στρογγυλεμένες γωνίες, όπου το descender μπορεί να υπερβεί το όριο της στρογγυλοποίησης.
Σύμφωνα με την Nielsen Norman Group — Mobile Typography Research (2025), το 41% των εφαρμογών κινητού έχει τουλάχιστον μία οθόνη όπου το κείμενο με descender υπερβαίνει τα όρια του στοιχείου. Αυτό οδηγεί σε μείωση της αναγνωσιμότητας κατά 15% και αύξηση του χρόνου ολοκλήρωσης της εργασίας από τον χρήστη. Ο τακτικός έλεγχος με κείμενο που περιέχει τα γράμματα “g”, “j”, “p”, “q”, “y” βοηθά στον εντοπισμό τέτοιων προβλημάτων στα πρώτα στάδια ανάπτυξης.
Συχνές ερωτήσεις
Baseline είναι η οριζόντια γραμμή πάνω στην οποία στέκονται τα γράμματα, ενώ το descender είναι το τμήμα του γράμματος που βρίσκεται κάτω από αυτήν τη γραμμή. Η baseline είναι σταθερά για μια γραμμή, το descender είναι ιδιότητα ενός συγκεκριμένου γράμματος. Μην μπερδεύετε αυτές τις έννοιες: η baseline χρησιμοποιείται για στοίχηση, ενώ το descender επηρεάζει το διάστιχο και απαιτεί προσοχή κατά τον ορισμό του ύψους του δοχείου.
Χρησιμοποιήστε το Paint.getFontMetrics().descent για το σύστημα View ή το TextLayoutResult στο Jetpack Compose. Σε αντίθεση με το iOS, η τιμή descent στο Android είναι θετική και δείχνει την απόσταση από τη baseline μέχρι το κάτω όριο της γλυφής. Για να υπολογίσετε το πλήρες κάτω όριο της γραμμής, προσθέστε το descent στη συντεταγμένη Y της baseline.
Οι πλατφόρμες χρησιμοποιούν διαφορετικούς πίνακες μετρικών από το αρχείο γραμματοσειράς: iOS — hhea.descent, Android — os/2.sTypoDescender. Εάν αυτές οι τιμές στη γραμματοσειρά διαφέρουν, η απόδοση θα είναι διαφορετική. Ελέγχετε πάντα και τις δύο τιμές μέσω του fontTools. Οι ποιοτικές γραμματοσειρές συστήματος (SF Pro, Roboto, Noto) έχουν συνεπείς μετρικές και για τις δύο πλατφόρμες.
Ελάχιστο line-height = ascender + descender + 2 px απόθεμα. Για γραμματοσειρά συστήματος 17 pt στο iOS, αυτό είναι περίπου 22.4 pt. Στο Android για 16 sp Roboto — περίπου 22 sp. Συνιστάται η στρογγυλοποίηση στον πλησιέστερο ακέραιο και ο έλεγχος με τη δοκιμαστική συμβολοσειρά “gpq” — εάν δεν υπάρχουν συγκρούσεις, το line-height είναι επαρκές.
Ναι, αλλά με επιφυλάξεις. Οι γραμματοσειρές με μακρύ descender (Playfair Display, διακοσμητικές γραμματοσειρές) είναι αποδεκτές για επικεφαλίδες και κείμενο έμφασης, όπου το line-height μπορεί να αυξηθεί χωρίς να βλάψει τον σχεδιασμό. Για κύριο κείμενο, προτιμώνται γραμματοσειρές με descender 20–25% του μεγέθους em (SF Pro, Roboto, Inter) για εξοικονόμηση περιττού κατακόρυφου χώρου.
Συμπεράσματα
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης