ParagraphStyle — Concetti chiave, proprietà e utilizzo

Autore: IT Sectr Pubblicato: 2026-07-25 Tempo di lettura: 10 min

ParagraphStyle è un insieme di parametri di formattazione che definiscono l'aspetto visivo di un paragrafo di testo. Nello sviluppo mobile, ParagraphStyle include allineamento (left, center, right, justified), interlinea, rientro della prima riga, spaziatura tra paragrafi e direzione del testo. Secondo le Material Design Typography Guidelines (2025), l'uso coerente di ParagraphStyle su tutti gli schermi dell'applicazione garantisce un ritmo tipografico uniforme e riduce il rumore visivo durante il passaggio tra le sezioni.

Punti chiave

  • ParagraphStyle — oggetto di impostazioni di formattazione del paragrafo: allineamento, rientro, spaziatura.
  • Piattaforme — iOS: NSMutableParagraphStyle, Android: ParagraphStyle (Compose) / Layout (View), Flutter: TextStyle.
  • Allineamento — left per il testo principale, center per i titoli, justified per il formato libro.
  • Rientro — firstLineHeadIndent (rientro prima riga), paragraphSpacing (spaziatura tra paragrafi).
  • Localizzazione — ParagraphStyle tiene conto della direzione del testo (LTR/RTL) per diverse lingue.

Cos'è ParagraphStyle in tipografia

ParagraphStyle (stile di paragrafo) è un insieme di regole di formattazione applicabili a uno o più paragrafi di testo. A differenza degli stili di carattere (bold, italic, font-size) che agiscono a livello di singoli caratteri, ParagraphStyle gestisce le macro-proprietà: posizionamento del testo nel contenitore, spaziatura tra righe e paragrafi, direzione di scrittura e regole di sillabazione.

Storicamente, il concetto di ParagraphStyle proviene dai sistemi di desktop publishing (QuarkXPress, PageMaker, InDesign), dove ogni paragrafo aveva il proprio insieme di parametri. Nello sviluppo mobile, questo approccio si è trasformato in API software: NSMutableParagraphStyle su iOS, le classi ParagraphStyle e LineBreakStyle in Android, e parametri come textAlign e textHeightBehavior in Flutter. Tutti servono a uno scopo — gestire la formattazione del paragrafo attraverso il codice, senza essere legati a un motore di testo specifico.

Secondo Bringhurst — The Elements of Typographic Style (2024), una corretta configurazione di ParagraphStyle è la base della cultura tipografica dell'interfaccia. Se il carattere tipografico e la dimensione del font definiscono la «voce» del testo, lo stile di paragrafo definisce il suo «respiro»: ritmo, pause e accenti. Nelle interfacce mobili dove lo spazio è limitato, un ParagraphStyle corretto consente di includere più informazioni senza perdere leggibilità.

Proprietà principali di ParagraphStyle

ParagraphStyle include diversi gruppi di proprietà, ciascuno responsabile di un aspetto specifico della formattazione. Esaminiamo i parametri chiave disponibili nelle API mobili. L'allineamento è il parametro principale che determina la posizione orizzontale del testo. Su iOS è disponibile NSTextAlignment, su Android — Layout.Alignment, in Flutter — TextAlign.

ProprietàiOS (NSMutableParagraphStyle)Android (Compose)Flutter (TextStyle)
AllineamentoalignmenttextAligntextAlign
Rientro sinistroheadIndenttextIndent (in Compose)
Rientro destrotailIndent
Rientro prima rigafirstLineHeadIndenttextIndent (firstLine)
Spaziatura tra paragrafiparagraphSpacingparagraphStyle (lineHeight)
Spaziatura prima del paragrafoparagraphSpacingBefore
Direzione del testobaseWritingDirectionTextDirection (Compose)textDirection
Modalità interruzione rigalineBreakModeoverflow (TextStyle)overflow (TextStyle)

È importante capire che non tutte le proprietà sono disponibili su tutte le piattaforme nella stessa misura. Ad esempio, il rientro della prima riga (firstLineHeadIndent) è completamente supportato solo su iOS tramite NSMutableParagraphStyle. In Android, si utilizza SpannableString con LeadingMarginSpan a questo scopo, e in Flutter — RichText con TextSpan personalizzato e padding. Nello sviluppo multipiattaforma (Flutter, React Native), alcune proprietà di ParagraphStyle devono essere emulate tramite contenitori o Spacer.

ParagraphStyle su iOS: NSMutableParagraphStyle

Su iOS, lo strumento principale per lavorare con lo stile di paragrafo è la classe NSMutableParagraphStyle — una sottoclasse di NSParagraphStyle. Fornisce un set completo di proprietà per gestire la formattazione del paragrafo e viene applicata tramite NSAttributedString. NSMutableParagraphStyle viene utilizzato non solo in UILabel e UITextView, ma anche in Core Text tramite CTParagraphStyle.

swift
// iOS: configurazione completa di ParagraphStyle
let paragraphStyle = NSMutableParagraphStyle()

// Allineamento
paragraphStyle.alignment = .justified     // giustificato

// Rientro
paragraphStyle.headIndent = 16          // rientro sinistro
paragraphStyle.tailIndent = -16         // rientro destro (negativo)
paragraphStyle.firstLineHeadIndent = 32 // rientro prima riga

// Spaziatura tra paragrafi
paragraphStyle.paragraphSpacing = 12    // dopo il paragrafo
paragraphStyle.paragraphSpacingBefore = 8 // prima del paragrafo

// Altezza riga
paragraphStyle.minimumLineHeight = 24
paragraphStyle.maximumLineHeight = 24

let attributes: [NSAttributedString.Key: Any] = [
    .font: UIFont.systemFont(ofSize: 16),
    .paragraphStyle: paragraphStyle
]

let label = UILabel()
label.attributedText = NSAttributedString(
    string: "This paragraph has a custom ParagraphStyle.\n\nSecond paragraph with 12 pt spacing.",
    attributes: attributes
)

In SwiftUI non esiste un equivalente diretto di NSMutableParagraphStyle — invece viene utilizzata una combinazione di modificatori: .multilineTextAlignment() per l'allineamento, .lineSpacing() per l'interlinea. Per il rientro della prima riga e la spaziatura tra paragrafi in SwiftUI, è necessario utilizzare Text + padding o AttributedString (disponibile da iOS 15+), che supporta NSParagraphStyle tramite attributi.

swift
// SwiftUI: AttributedString con ParagraphStyle (iOS 15+)
var attributed: AttributedString = """
This is the first paragraph with indent.

This is the second paragraph with 12 pt spacing.
"""

let ps = NSMutableParagraphStyle()
ps.paragraphSpacing = 12
ps.firstLineHeadIndent = 20

let container = AttributeContainer()
    .paragraphStyle(ps)

attributed.mergeAttributes(container)

Text(attributed)
    .font(.body)

Secondo Apple — Text Programming Guide (2025), NSMutableParagraphStyle supporta fino a 14 diversi parametri di formattazione. È importante ricordare che tailIndent viene impostato come valore negativo rispetto alla larghezza del contenitore, mentre headIndent è positivo. Questo comportamento non ovvio causa spesso errori tra gli sviluppatori iOS principianti.

ParagraphStyle su Android: sistema View e Compose

Su Android, l'approccio a ParagraphStyle differisce tra il sistema View e Jetpack Compose. Nel sistema View classico, i parametri del paragrafo vengono impostati tramite attributi XML di TextView (android:textAlignment, android:lineSpacingExtra) o tramite SpannableString con implementazioni dell'interfaccia ParagraphStyle dal pacchetto android.text.style.

kotlin
// Sistema Android View: ParagraphStyle tramite SpannableString
val text = "First paragraph with settings.\n\nSecond paragraph."
val spannable = SpannableString(text)

// Allineamento giustificato
spannable.setSpan(
    AlignmentSpan.Standard(Layout.Alignment.ALIGN_NORMAL),
    0, text.length,
    Spannable.SPAN_PARAGRAPH
)

// Rientro prima riga tramite LeadingMarginSpan
spannable.setSpan(
    LeadingMarginSpan.Standard(0, 20),
    0, text.indexOf('\n'),
    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)

textView.text = spannable

In Jetpack Compose, ParagraphStyle viene gestito tramite parametri di TextStyle. textAlign viene utilizzato per l'allineamento, lineHeight (in sp o em) per l'interlinea, e textIndent per il rientro della prima riga. Compose supporta anche LineBreak per un controllo preciso delle interruzioni di riga (Simple, Heading, Paragraph), particolarmente utile per testo multilingue.

kotlin
// Jetpack Compose: ParagraphStyle tramite TextStyle
Text(
    text = "Primo paragrafo con stile personalizzato.

Secondo paragrafo con rientro.",
    style = TextStyle(
        textAlign = TextAlign.Justify,
        lineHeight = 24.sp,
        textIndent = TextIndent(firstLine = 16.sp),
        lineBreak = LineBreak.Paragraph
    )
)

Secondo Android Developers — Compose ParagraphStyle (2025), quando si utilizza TextIndent in Compose, è importante impostare firstLine in sp (non in dp), poiché il rientro della prima riga deve scalare con il testo. Se il rientro viene impostato in dp, all'aumentare della dimensione del carattere, il rientro della prima riga diventerà visivamente più piccolo, rompendo le proporzioni tipografiche.

ParagraphStyle su Flutter: TextHeightBehavior e StrutStyle

In Flutter, il paradigma ParagraphStyle non è separato in una classe dedicata — invece viene utilizzata una combinazione di parametri TextStyle e classi aggiuntive. L'allineamento viene impostato tramite TextAlign, l'interlinea tramite height (senza unità), e TextHeightBehavior controlla i rientri visibili della prima e dell'ultima riga.

dart
// Flutter: ParagraphStyle tramite parametri Text
Text(
    'Paragrafo stilizzato in Flutter.

Secondo paragrafo con rientri.',
    style: TextStyle(
        fontSize: 16,
        height: 1.5,
        leadingDistribution: TextLeadingDistribution.proportional,
    ),
    textAlign: TextAlign.justify,
    textHeightBehavior: TextHeightBehavior(
        applyHeightToFirstAscent: true,
        applyHeightToLastDescent: true,
    ),
)

Per scenari più complessi, Flutter offre l'uso di RichText con TextSpan e WidgetSpan personalizzati. Questo consente di combinare testo con widget inline (icone, immagini) in un unico paragrafo, mantenendo regole di formattazione uniformi. Tuttavia, questo approccio richiede il controllo manuale delle interruzioni di riga e non supporta la sillabazione automatica.

dart
// Flutter: RichText con formattazione paragrafo personalizzata
RichText(
    text: TextSpan(
        style: TextStyle(fontSize: 16, height: 1.5),
        children: [
            TextSpan(text: 'First paragraph with icon '),
            WidgetSpan(
                child: Icon(Icons.star, size: 16),
                alignment: PlaceholderAlignment.middle,
            ),
            TextSpan(text: '\n\nSecond paragraph after spacing.'),
        ],
    ),
)

Secondo Flutter Documentation — Text Widget (2025), TextHeightBehavior è un parametro chiave per la corretta visualizzazione di ParagraphStyle in Flutter. Se applyHeightToFirstAscent è impostato su false, il rientro superiore della prima riga viene ignorato e il testo «si attacca» al bordo superiore del contenitore. Questo è utile per i titoli, ma indesiderabile per il testo principale.

ParagraphStyle e localizzazione: LTR/RTL e caratteristiche regionali

ParagraphStyle deve tenere conto della direzione di scrittura per ogni lingua. Nelle app mobili con supporto per arabo, ebraico o urdu (scrittura da destra a sinistra, RTL), rientri e allineamento devono essere speculari. iOS supporta il passaggio automatico tramite baseWritingDirection = .natural, Android tramite TextDirection, Flutter tramite textDirection.

La configurazione dell'allineamento per le lingue RTL richiede particolare attenzione. Se in modalità LTR headIndent imposta il rientro sinistro, in RTL diventa automaticamente il rientro destro. Tuttavia, non tutte le implementazioni gestiscono correttamente questa transizione quando l'allineamento viene specificato esplicitamente (NSTextAlignment.left invece di NSTextAlignment.natural). Secondo Google Internationalization Guide (2025), per le app multilingue usa sempre l'allineamento naturale e verifica i rientri in entrambe le disposizioni.

kotlin
// Android: supporto RTL in ParagraphStyle
val textView = TextView(context)

// Abilita supporto RTL automatico
textView.textDirection = View.TEXT_DIRECTION_LOCALE
textView.textAlignment = View.TEXT_ALIGNMENT_TEXT_START

// Spannable con supporto RTL
val spannable = SpannableString(arabicText)
spannable.setSpan(
    AlignmentSpan.Standard(Layout.Alignment.ALIGN_NORMAL),
    0, arabicText.length,
    Spannable.SPAN_PARAGRAPH
)

Le caratteristiche regionali includono anche regole diverse per il rientro della prima riga. Nella tipografia europea, il rientro della prima riga (firstLineHeadIndent) è uno standard per la separazione dei paragrafi. Nella tipografia giapponese e cinese, il rientro della prima riga viene utilizzato anch'esso, ma la sua dimensione può differire (di solito 1 em contro 1,5 em nella tradizione europea). Per la tipografia araba, il rientro della prima riga è raro — i paragrafi sono più spesso separati da spaziatura verticale.

Errori comuni quando si lavora con ParagraphStyle

L'errore più comune è utilizzare ParagraphStyle solo tramite attributi globali del campo di testo senza considerare la formattazione diversa dei singoli paragrafi. In un UILabel o TextView con più paragrafi separati da , ParagraphStyle viene applicato uniformemente a tutto il testo, a meno che non si utilizzi testo attribuito con stili diversi per ogni paragrafo.

  • Ignorare paragraphSpacingBefore — molti sviluppatori impostano paragraphSpacing ma dimenticano paragraphSpacingBefore. Per il primo paragrafo di un blocco, paragraphSpacingBefore consente di impostare un margine superiore senza creare un contenitore aggiuntivo. Questo è particolarmente utile per elenchi con titoli.
  • Allineamento fisso (left/right) invece di natural — se l'app supporta lingue RTL, utilizzare NSTextAlignment.left o TextAlign.Start invece di natural porta a una visualizzazione errata nelle lingue araba ed ebraica.
  • Mancata verifica della modalità di interruzione riga — in contenitori stretti (elenchi, barre laterali), un lineBreakMode errato porta al troncamento delle parole. Usa byWordWrapping e verifica le parole lunghe nel contesto della lingua specifica.
  • Mescolare Spannable con diversi ParagraphStyle — quando si imposta Spannable con SPAN_PARAGRAPH, è importante calcolare correttamente i confini dei paragrafi. La mancata corrispondenza delle posizioni di inizio/fine con i confini effettivi del paragrafo porta all'ignoramento dello stile.
  • Allineamento della linea di base dimenticato — quando si utilizza ParagraphStyle con un lineHeight fisso (minimumLineHeight), assicurati che l'allineamento del testo alla linea di base sia attivato. Su iOS, si utilizza label.baselineAdjustment = .alignBaselines.

Secondo UX Collective — Common Typography Bugs in Mobile Apps (2025), i problemi con ParagraphStyle costituiscono il 18% di tutti i bug tipografici nelle applicazioni mobili. I casi più critici sono quando un paragraphSpacing errato porta alla sovrapposizione del testo su righe diverse o quando le lingue RTL vengono visualizzate con rientri LTR. Si consiglia di creare test unitari per ogni parametro di ParagraphStyle con stringhe di test in diverse lingue.

Domande frequenti

In cosa ParagraphStyle differisce da TextStyle in iOS?

NSMutableParagraphStyle gestisce la formattazione del paragrafo (allineamento, rientro, interlinea), mentre TextStyle gestisce gli attributi del carattere (font, colore, dimensione). Entrambi vengono applicati tramite NSAttributedString. ParagraphStyle agisce a livello di paragrafo, TextStyle a livello di carattere. Più istanze di TextStyle possono esistere in un paragrafo, ma solo un ParagraphStyle per paragrafo.

Come impostare il rientro della prima riga in Jetpack Compose?

In Jetpack Compose, il rientro della prima riga viene impostato tramite TextIndent all'interno di TextStyle: TextStyle(textIndent = TextIndent(firstLine = 16.sp)). Il valore deve essere in sp per scalare con il testo. Per testo multilinea, il rientro si applica a ogni riga che inizia un nuovo paragrafo (carattere ). Per il primo paragrafo, il rientro viene sempre applicato.

Come configurare la spaziatura tra paragrafi in SwiftUI?

In SwiftUI non esiste un equivalente diretto di paragraphSpacing. Per la spaziatura tra paragrafi, usa AttributedString (iOS 15+) con NSMutableParagraphStyle e la proprietà paragraphSpacing. Oppure separa i paragrafi tramite Text("...\n\n...") e aggiungi .padding() tra i blocchi di testo. Per scenari tipografici complessi, usa NSAttributedString tramite UILabelRepresentable.

Perché paragraphSpacing non funziona in Android TextView?

TextView in Android non ha una proprietà paragraphSpacing — viene impostata tramite SpannableString con LeadingMarginSpan o tramite un LineBackgroundSpan personalizzato. Per l'interlinea usa setLineSpacing; per la spaziatura tra paragrafi, separa i paragrafi con un aggiuntivo o usa un contenitore composito di più istanze TextView.

In che modo ParagraphStyle influisce sull'accessibilità delle app mobili?

Un ParagraphStyle corretto migliora l'accessibilità: una paragraphSpacing sufficiente aiuta gli utenti con disturbi cognitivi a distinguere meglio i confini dei paragrafi. WCAG 2.2 raccomanda la separazione visiva dei paragrafi (rientro o spaziatura). ParagraphSpacing non deve essere inferiore a 1,5 × line-height. Per le lingue RTL, verifica che il rientro sia speculare correttamente.

Riepilogo

  • ParagraphStyle — insieme di regole di formattazione del paragrafo: allineamento, rientro, interlinea e spaziatura tra paragrafi.
  • iOS — NSMutableParagraphStyle con 14+ parametri, applicato tramite NSAttributedString; in SwiftUI — AttributedString (iOS 15+).
  • Android View — SpannableString con implementazioni di ParagraphStyle (AlignmentSpan, LeadingMarginSpan).
  • Android Compose — TextStyle.textAlign, lineHeight, textIndent e LineBreak per il controllo delle interruzioni di riga.
  • Flutter — combinazione di TextStyle.height, TextAlign, TextHeightBehavior e StrutStyle per fissare l'altezza della riga.
  • Localizzazione — usa allineamento naturale per il supporto delle lingue RTL; verifica i rientri in entrambe le disposizioni.
  • Errori comuni — allineamento fisso invece di naturale, mancata attenzione a paragraphSpacingBefore, lineBreakMode errato per contenitori stretti.

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.

Discuti il progetto

Leggi anche