Descender è la parte di una lettera minuscola che si estende al di sotto della linea di base (baseline) del carattere. In alfabeto latino, le lettere tipiche con descender sono “g”, “j”, “p”, “q”, “y”. La lunghezza del descender determina l’elemento discendente del carattere ed è criticamente importante per il calcolo dell’interlinea: senza spazio sufficiente sotto la baseline, le lettere con descender entreranno in collisione con la riga successiva. Secondo le Material Design Type Scale Guidelines (2025), la considerazione insufficiente del descender è una delle principali cause di collisione delle righe nel testo su più righe sui dispositivi mobili.
Punti chiave
Descender è la parte di un glifo situata sotto la linea di base. Mentre il corpo principale della lettera poggia sulla baseline, il descender si estende oltre, creando la sagoma caratteristica del carattere. Nell’alfabeto latino, le lettere con descender includono “g”, “j”, “p”, “q”, “y” — i loro elementi inferiori scendono sotto la riga.
La profondità del descender descrive la distanza dalla baseline al bordo inferiore del glifo (descender-line). Nei caratteri di qualità, questa distanza è bilanciata: un descender troppo corto rende le lettere con descender difficili da riconoscere, mentre un descender troppo lungo crea spazio vuoto eccessivo tra le righe e riduce la densità del testo. Diversi tipi di carattere mostrano differenze significative nella lunghezza del descender.
| Tipo di carattere | Descender / em-size | Esempi di lettere con descender |
|---|---|---|
| SF Pro | ~0.22 | g, j, p, q, y — estensione bilanciata |
| Roboto | ~0.24 | g, j, p — descender moderato |
| Playfair Display | ~0.30 | g, j, p, q — lunghi elementi decorativi |
| Inter | ~0.26 | g, j, p — notevolmente sotto la baseline |
| Noto Sans | ~0.20 | g, j — descender corto, compatto |
Secondo la Google Fonts Metrics Guide (2025), un descender è considerato ottimale quando la sua profondità è del 20–25% della dimensione em completa (1000 FUnits). Valori inferiori al 15% rendono le lettere con descender difficili da distinguere, mentre valori superiori al 30% richiedono un aumento obbligatorio del line-height per prevenire collisioni di righe.
Nei caratteri digitali, il descender è memorizzato come valore negativo nelle tabelle delle metriche. Nel formato OpenType, questi sono i campi hhea.descent (tabella hhea) e sTypoDescender (tabella OS/2). Entrambi i valori sono negativi perché vengono misurati dalla baseline verso il basso. Per TrueType, viene utilizzata la tabella OS/2 con il campo usWinDescent — il suo valore è positivo ma indica la stessa metrica.
# Leggere descender dal carattere tramite 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)
# Convertire in pixel per dimensione del carattere 16pt
px_per_em = 16
descent_px = abs(descent_hhea) * px_per_em / 1000 # 8 px
La differenza critica tra le piattaforme: iOS utilizza hhea.descent per il rendering, mentre Android utilizza sTypoDescender da OS/2. Se questi valori differiscono (cosa che accade in caratteri mal configurati), lo stesso testo verrà visualizzato con interlinee diverse su iOS e Android. Una differenza di 100 FUnits (circa 1,6 px per una dimensione del carattere di 16 pt) è già visivamente percepibile.
Secondo la Microsoft OpenType Specification v1.9 (2025), per un rendering cross-platform corretto, i valori hhea.descent e sTypoDescender devono essere uguali con una precisione di 50 FUnits. Quando si sceglie un carattere per un’applicazione mobile, questo deve essere verificato tramite fontTools o un’utilità simile.
In iOS, il valore del descender è disponibile tramite la proprietà UIFont.descender. Questa proprietà restituisce un numero negativo che indica la distanza dalla baseline al bordo inferiore del carattere (incluso il descender). Ad esempio, per SF Pro a 17 pt, il valore del descender è di circa -4,2 pt. Maggiore è il valore assoluto, più lunghe sono le estensioni inferiori del carattere.
// Ottenere descender su iOS tramite UIFont
let font = UIFont.systemFont(ofSize: 17)
let descender = font.descender // ~ -4,2 pt per SF Pro 17pt
let ascender = font.ascender // ~ 16,2 pt
let lineHeight = font.lineHeight // ~ 20,4 pt
// Rendering personalizzato con offset del descender
let attrString = NSAttributedString(
string: "Sample text with letter p and y",
attributes: [.font: font]
)
// Core Text: ottenere il bounding box con descender
let ctFont = CTFontCreateWithName(
"SF Pro Text" as CFString, 17, nil
)
let descent = CTFontGetDescent(ctFont) // ~4,2 pt
Quando si utilizza TextKit (NSTextStorage, NSLayoutManager), il descender viene automaticamente considerato in lineFragmentPadding e lineFragmentRect. Tuttavia, quando si esegue il rendering personalizzato tramite Core Graphics (draw(in:)), è necessario regolare manualmente le coordinate aggiungendo il valore assoluto del descender al margine inferiore del contenitore. Se non lo si fa, le lettere con descender supereranno i limiti di rendering e verranno tagliate.
In Android, le metriche del descender sono disponibili tramite Paint.FontMetrics.descent. A differenza di iOS, il valore descent è positivo — rappresenta la distanza dalla baseline al bordo inferiore del testo. La proprietà FontMetrics.bottom include non solo il descender ma anche lo spazio aggiuntivo raccomandato dal progettista del carattere (leading). Per un calcolo preciso del solo descender, utilizzare descent anziché bottom.
// Ottenere descender su Android tramite Paint
val paint = Paint().apply {
textSize = 17 * density
}
val metrics = paint.fontMetrics
val descent = metrics.descent // ~4,5 px per 17sp
val bottom = metrics.bottom // ~5,0 px con leading
// Rendering personalizzato con offset del descender
val baseline = y
canvas.drawText("Esempio: gpq", x, baseline, paint)
// Limite inferiore con descender
val bottomBound = baseline + descent // limite inferiore corretto
In Jetpack Compose, il descender può essere ottenuto tramite TextLayoutResult. Il metodo getLineBottom restituisce la coordinata Y del bordo inferiore della riga, che include già il descender. Quando si esegue il layout personalizzato di stringhe con diverse dimensioni del carattere (ad esempio, un prezzo scontato e un prezzo pieno), l’allineamento sulla baseline considerando il descender fornisce un risultato più preciso rispetto all’allineamento sul bordo inferiore.
// Compose: verificare il limite inferiore del testo
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)
// Verificare che il descender non superi i limiti del contenitore
}
}
)
Secondo Google Material Design — Typography Implementation (2025), per evitare il taglio del descender nei contenitori con altezza fissa, è necessario aggiungere un padding verticale pari almeno al descent del carattere, indipendentemente dal fatto che il testo corrente contenga o meno lettere con descender. Ciò garantisce che l’interfaccia non si rompa quando il testo viene sostituito dinamicamente.
Una collisione di righe è una situazione in cui il descender di una lettera della riga superiore si incrocia fisicamente con l’ascender di una lettera della riga inferiore. Nelle interfacce mobili, questo è particolarmente evidente nelle intestazioni multi-riga, nelle schede prodotto e nei blocchi di testo con interlinea ridotta. Il problema è aggravato dall’uso di caratteri con descenders lunghi e line-height piccolo.
Il line-height minimo che previene le collisioni può essere calcolato con la formula: line-height = ascender + descender + 2 px di margine. Per SF Pro a 17 pt, questo dà un line-height di circa 16,2 + 4,2 + 2 = 22,4 pt (un coefficiente di ~1,32). Per Roboto a 16 sp, circa 1,35. Se il line-height è inferiore a questo valore, le collisioni sono garantite nei testi contenenti lettere con descender.
// iOS: calcolare il line-height minimo per prevenire collisioni
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
]
)
Occorre prestare particolare attenzione quando si lavora con caratteri decorativi e manoscritti — il loro descender può raggiungere il 35–40% della dimensione em. Questi caratteri sono raramente usati per il testo del corpo, ma possono essere applicati nelle intestazioni. Anche una singola occorrenza di una lettera con descender lungo in un’intestazione può causare una collisione con un elemento dell’interfaccia vicino.
L’errore più comune è il taglio del descender in pulsanti e campi di testo. Quando impostiamo l’altezza di un pulsante o di un campo di testo uguale al line-height senza considerare il descender, le lettere con descender vengono tagliate sul bordo inferiore. Ciò è particolarmente evidente nei pulsanti di sistema con angoli arrotondati, dove il descender può superare il limite del raggio d’angolo.
Secondo Nielsen Norman Group — Mobile Typography Research (2025), il 41% delle applicazioni mobili ha almeno una schermata in cui il testo con descenders supera i limiti del componente. Ciò porta a una diminuzione del 15% della leggibilità e a un aumento del tempo di completamento delle attività da parte dell’utente. Test regolari con testo contenente lettere con descender aiutano a identificare questi problemi nelle fasi iniziali dello sviluppo.
Domande frequenti
Baseline è la linea orizzontale su cui poggiano le lettere, mentre il descender è la parte della lettera situata sotto questa linea. La baseline è una costante per la riga, il descender è una proprietà di una lettera specifica. Non confondere questi concetti: la baseline viene utilizzata per l’allineamento, mentre il descender influisce sull’interlinea e deve essere considerato quando si imposta l’altezza del contenitore.
Utilizzare Paint.getFontMetrics().descent per il sistema View o TextLayoutResult in Jetpack Compose. A differenza di iOS, il valore descent su Android è positivo e indica la distanza dalla baseline al bordo inferiore del glifo. Per calcolare il limite inferiore completo della riga, aggiungere descent alla coordinata Y della baseline.
Le piattaforme utilizzano tabelle metriche diverse dal file del carattere: iOS utilizza hhea.descent, Android utilizza os/2.sTypoDescender. Se questi valori differiscono nel carattere, il rendering sarà diverso. Verificare sempre entrambi i valori tramite fontTools. I caratteri di sistema di qualità (SF Pro, Roboto, Noto) hanno metriche coerenti per entrambe le piattaforme.
Il minimo line-height = ascender + descender + 2 px di margine. Per un carattere di sistema di 17 pt su iOS è di circa 22,4 pt. Su Android per Roboto 16 sp — circa 22 sp. Si raccomanda di arrotondare al numero intero più vicino e testare con una stringa di prova di lettere con descender — se non ci sono collisioni, il line-height è sufficiente.
Sì, ma con delle riserve. I caratteri con descender lungo (Playfair Display, tipi di carattere decorativi) sono accettabili per intestazioni e testo enfatizzato dove il line-height può essere aumentato senza compromettere il design. Per il testo del corpo, sono preferiti caratteri con un descender del 20–25% della dimensione em (SF Pro, Roboto, Inter) per non sprecare spazio verticale.
Riassunto
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche