sp — Scale-independent Pixels, en måttenhet för text i Android som tar hänsyn till inställningar för teckenstorlek på enheten. Till skillnad från dp skalas sp tillsammans med systemets teckenstorlek, vilket säkerställer tillgänglighet för gränssnitt. Artikeln förklarar skillnaden mellan sp och dp, visar konfiguration av textSize i XML och Kotlin, och avslöjar bästa praxis för att arbeta med typografi i Android.
Huvudpunkter
sp (scale-independent pixel) — en måttenhet för teckenstorlek i Android som automatiskt skalas enligt användarens systeminställningar. När enhetsägaren ökar teckenstorleken i inställningarna växer alla element med sp-värden proportionellt. Detta säkerställer tillgänglighet för gränssnittet för personer med nedsatt syn.
Grundförhållande: 1 sp = 1 dp vid standard teckensnittsskala 1.0 (normal). Om användaren ställer in teckensnittet Large (1.15×) blir 16 sp 18.4 fysiska pixlar. Vid teckenstorleken Small (0.85×) blir samma 16 sp 13.6 px. Skalningsmekanismen hanteras via Settings.System.FONT_SCALE på Android Framework-nivå.
Enligt Google Material Design Guidelines bör text ställas in uteslutande i sp. Undantag — fasta etiketter i komponenter där storleken är kritisk för layouten (t.ex. text inuti knappar med fast höjd). I sådana fall rekommenderas att använda dp med manuell tillgänglighetskontroll.
Skillnaden mellan sp och dp — ett av de vanligaste ämnena på intervjuer för Android-utvecklare och i verkliga code review. Båda enheterna är kopplade till density-independent pixel (160 dpi = 1 dp = 1 px på mdpi-skärm), men beter sig olika när systemets teckenstorlek ändras.
| Egenskap | sp | dp |
|---|---|---|
| Syfte | Textstorlek | Elementdimensioner, avstånd, bredd, höjd |
| Skalning med teckensnitt | Ja (scale factor) | Nej |
| Skalning med densitet | Ja | Ja |
| API för inställning | android:textSize | android:layout_width, layout_height, padding, margin |
| Material Design Token | typescale | spacing, sizing |
I praktiken är det fel att använda dp för text. Om texten är inställd i dp skalar den inte när teckensnittet förstoras, vilket gör gränssnittet otillgängligt för användare med nedsatt syn. Det omvända felet är att använda sp för knapphöjd eller avstånd: när teckensnittet förstoras kan knappen „svälla upp" och förstöra layouten.
Skalning av sp är implementerad på Android Framework-nivå i klassen TypedValue. Omräkningsformeln: sp = dp × scaledDensity, där scaledDensity är skalkoefficienten som tar hänsyn till både skärmdensitet och användarens teckensnittsinställning.
// Programmatisk hämtning av scaledDensity i Kotlin
val scaledDensity = with(context.resources) {
displayMetrics.scaledDensity
}
// Konvertera sp till px
fun spToPx(sp: Float, context: Context): Float {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
sp,
context.resources.displayMetrics
)
}
// Konvertera px till sp
fun pxToSp(px: Float, context: Context): Float {
return px / context.resources.displayMetrics.scaledDensity
}Metoden TypedValue.applyDimension — det enda korrekta sättet att konvertera sp till pixlar vid körning. Direkt multiplikation med scaledDensity är mindre tillförlitligt eftersom det inte hanterar gränsfall (nollvärden, spill). scaledDensity ändras när teckensnittsinställningarna ändras via Settings > Display > Font size.
Android tillhandahåller fem förinställda nivåer av teckensnittsskala: Small (0.85×), Default (1.0×), Large (1.15×), Largest (1.3×) och en extra nivå Very Large (>1.3×) i Android 14+. Enhetstillverkare (Samsung, Xiaomi) lägger till egna nivåer — upp till 2.0×. Minsta textstorlek i sp garanterar aldrig ett fast antal pixlar.
I XML används sp uteslutande i attributet android:textSize. Alla andra dimensioner — width, height, padding, margin, elevation — ställs in i dp. Regeln är enkel: om ett element visar text — dess storlek i sp, om ett element definierar geometri — storleken i dp.
<!-- TextView-layout med textSize i sp -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:textSize="16sp"
android:padding="12dp"
android:lineSpacingExtra="4dp" />
<!-- Använda dimens-resurser -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_body_large" />Det rekommenderas att flytta textstorlekar till filen dimens.xml. Detta förenklar underhållet av typografi, gör det möjligt att åsidosätta storlekar för olika skärmkonfigurationer och säkerställer enhetlighet i hela applikationen.
<!-- res/values/dimens.xml -->
<resources>
<!-- Material Design Type Scale -->
<dimen name="text_display_large">34sp</dimen>
<dimen name="text_display_medium">28sp</dimen>
<dimen name="text_headline_large">24sp</dimen>
<dimen name="text_headline_medium">20sp</dimen>
<dimen name="text_title_large">18sp</dimen>
<dimen name="text_body_large">16sp</dimen>
<dimen name="text_body_medium">14sp</dimen>
<dimen name="text_label_large">14sp</dimen>
<dimen name="text_label_small">11sp</dimen>
</resources>Material Design Type Scale omfattar 13 storleksnivåer — från 11sp för små etiketter till 57sp för stora displayrubriker. Android-projekt använder vanligtvis 8–10 nivåer. Alla värden bör vara multiplar av 1sp — bråktalsvärden (15.5sp) försämrar renderingen på grund av subpixelpositionering.
I modern Android-utveckling ställs text sällan in direkt via textSize i sp. Istället används systemet MaterialTheme.typography, där varje stil är fördefinierad och inkluderar storlek, vikt, radavstånd och letter-spacing.
// Anpassad typografi via Typography API
val AppTypography = Typography(
displayLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 34.sp,
lineHeight = 40.sp,
letterSpacing = 0.sp
),
headlineLarge = TextStyle(
fontWeight = FontWeight.SemiBold,
fontSize = 24.sp,
lineHeight = 32.sp
),
titleLarge = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 18.sp,
lineHeight = 24.sp
),
bodyLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
),
labelSmall = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
)Tilläggsfunktionen .sp i Jetpack Compose översätts automatiskt till scale-independent pixels. När systemets teckenstorlek ändras beräknar Compose om fontSize, lineHeight och spacing enligt den nya scaledDensity. TextUnit (klassen som representerar sp) garanterar att text skalas, medan avstånd — inte.
I Jetpack Compose representeras sp av typen TextUnit, som inte kan användas av misstag för elementdimensioner. Kotlin-kompilatorn ger ett fel om TextUnit skickas dit Dp förväntas. Detta eliminerar en hel klass av buggar relaterade till felaktig skalning.
// TextUnit i Compose — säker arbete med sp
@Composable
fun ArticleCard(title: String, description: String) {
Card(modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = title,
style = MaterialTheme.typography.titleLarge
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = description,
style = MaterialTheme.typography.bodyMedium
)
}
}
// Explicit inställning av fontSize i sp
Text(
text = "Anpassad storlek",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)I Compose finns ingen direkt motsvarighet till XML-attributet android:textSize — textstorleken ställs in via TextStyle.fontSize. MaterialTheme.typography-systemet tillhandahåller fördefinierade stilar som motsvarar Material Design Type Scale. Om en anpassad storlek behövs används literalet 20.sp — språket garanterar att detta är TextUnit, inte Dp.
Korrekt användning av sp — grunden för en tillgänglig Android-app. Nedan samlas regler baserade på rekommendationer från Google Material Design och Android Developers Guide.
Huvudregeln för tillgänglighet: användaren bör ha möjlighet att förstora teckensnittet utan att förlora funktionalitet. Om appen fungerar korrekt vid teckensnittsskala 1.3× klarar den grundläggande tillgänglighetstester. Google Play kan avvisa appen om textSize är inställd i dp och gränssnittet inte skalas.
Vanliga frågor
sp (scale-independent pixel) skalas när systemets teckenstorlek ändras, medan dp — inte. sp används endast för text, dp — för alla andra elementdimensioner. Omräkningsfaktor: sp = dp × FONT_SCALE.
Nej. Avstånd, knapphöjd, kortbredd bör ställas in i dp. Att använda sp för avstånd leder till onaturlig tillväxt av element när teckensnittet förstoras och de kan gå utanför skärmens gränser.
Öppna Settings > Display > Font size och ställ in maxvärdet (Largest). Starta appen och kontrollera att all text är läsbar, element inte överlappar och knappar inte går utanför skärmens gränser. För automatisering, använd Espresso med UiAutomator.
Material Design rekommenderar en minsta storlek på 11sp för labelSmall. För huvudtext — från 14sp (bodyMedium) till 16sp (bodyLarge). Storlekar mindre än 11sp rekommenderas inte eftersom de blir oläsliga på enheter med hög pixeldensitet.
Texten visas i fast storlek oavsett systemets teckensnittsinställningar. Användare med förstorad text kan inte bekvämt läsa sådan text. Detta bryter mot WCAG-tillgänglighetskraven och kan leda till att appen avvisas i Google Play.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också