sp — Scale-independent Pixels、デバイスのフォントサイズ設定を考慮したAndroidのテキスト測定単位です。dpとは異なり、spはシステムフォントサイズに合わせてスケーリングされ、インターフェースのアクセシビリティを確保します。この記事では、spとdpの違いを説明し、XMLやKotlinでのtextSize設定方法を示し、Androidでのタイポグラフィに関するベストプラクティスを紹介します。
重要ポイント
sp(scale-independent pixel)— ユーザーのシステム設定に応じて自動的にスケーリングされるAndroidのフォントサイズ測定単位です。デバイスの所有者が設定でフォントサイズを大きくすると、sp値を持つすべての要素が比例して大きくなります。これにより、視覚障害のある人々のためのインターフェースのアクセシビリティが確保されます。
基本比率: 標準フォントスケール1.0(通常)では1 sp = 1 dp。ユーザーがフォントをLarge(1.15×)に設定すると、16 spは18.4物理ピクセルになります。Smallフォントサイズ(0.85×)では、同じ16 spが13.6 pxになります。スケーリングメカニズムは、Android FrameworkレベルでSettings.System.FONT_SCALEを通じて管理されます。
Google Material Designガイドラインによると、テキストは排他的にspで指定する必要があります。例外は、レイアウトにとってサイズが重要なコンポーネント内の固定ラベルです(例: 高さ固定ボタン内のテキスト)。そのような場合、手動アクセシビリティ制御付きでdpを使用することをお勧めします。
spとdpの違いは、Android開発者の面接や実際のコードレビューで最もよくあるトピックの1つです。どちらの単位も密度非依存ピクセル(mdpi画面では160 dpi = 1 dp = 1 px)に結びついていますが、システムフォントサイズが変わると異なる動作をします。
| 特性 | sp | dp |
|---|---|---|
| 目的 | テキストサイズ | 要素の寸法、パディング、幅、高さ |
| フォントスケーリング | あり(スケール係数) | なし |
| 密度スケーリング | あり | あり |
| 設定API | android:textSize | android:layout_width, layout_height, padding, margin |
| Material Designトークン | typescale | spacing, sizing |
実際によくある間違いは、テキストにdpを使用することです。テキストがdpで設定されている場合、フォントサイズが大きくなってもスケーリングされず、視力の弱いユーザーにとってインターフェースがアクセス不能になります。逆の間違いは、ボタンの高さやパディングにspを使用することです。フォントが大きくなるとボタンが「膨らみ」、レイアウトが崩れる可能性があります。
spのスケーリングは、Android FrameworkレベルでTypedValueクラスに実装されています。変換式: sp = dp × scaledDensity(scaledDensityは画面密度とユーザーのフォントサイズ設定の両方を考慮したスケーリング係数)。
// KotlinでのscaledDensityのプログラムによる取得
val scaledDensity = with(context.resources) {
displayMetrics.scaledDensity
}
// spからpxへの変換
fun spToPx(sp: Float, context: Context): Float {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
sp,
context.resources.displayMetrics
)
}
// pxからspへの変換
fun pxToSp(px: Float, context: Context): Float {
return px / context.resources.displayMetrics.scaledDensity
}TypedValue.applyDimensionメソッドは、実行時にspをピクセルに変換する唯一の正しい方法です。scaledDensityによる直接乗算は、エッジケース(ゼロ値、オーバーフロー)を処理しないため信頼性が低くなります。scaledDensityは、Settings > Display > Font sizeを介してフォント設定を変更すると変化します。
Androidには5つの事前定義されたフォントスケールレベルがあります: Small(0.85×)、Default(1.0×)、Large(1.15×)、Largest(1.3×)、およびAndroid 14+の追加のVery Largeレベル(>1.3×)。デバイスメーカー(Samsung、Xiaomi)は独自のレベルを追加します—最大2.0×まで。spの最小テキストサイズは、固定ピクセル数を保証するものではありません。
XMLレイアウトでは、spは排他的にandroid:textSize属性で使用されます。他のすべての寸法(幅、高さ、パディング、マージン、エレベーション)はdpで設定されます。ルールは簡単です: 要素がテキストを表示する場合、サイズはspで;要素がジオメトリを定義する場合、サイズはdpです。
<!-- spでtextSizeを使用したTextViewレイアウト -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:textSize="16sp"
android:padding="12dp"
android:lineSpacingExtra="4dp" />
<!-- dimensリソースの使用 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_body_large" />テキストサイズはdimens.xmlファイルに抽出することをお勧めします。これにより、タイポグラフィのメンテナンスが簡素化され、異なる画面構成に合わせてサイズを上書きでき、アプリケーション全体で一貫性が確保されます。
<!-- 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には13のサイズレベルが含まれています—小さなラベル用の11spから大きなディスプレイ見出し用の57spまで。Androidプロジェクトは通常8〜10レベルを使用します。すべての値は1spの倍数である必要があります—小数値(15.5sp)はサブピクセル配置のためにレンダリングを低下させます。
現代のAndroid開発では、テキストがspのtextSizeを介して直接設定されることはめったにありません。代わりに、MaterialTheme.typographyシステムが使用され、各スタイルが事前定義され、サイズ、太さ、行の高さ、文字間隔が含まれます。
// 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
)
)Jetpack Composeの拡張関数.spは、自動的にスケール非依存ピクセルに変換されます。システムフォントサイズが変更されると、Composeは新しいscaledDensityに従ってfontSize、lineHeight、spacingを再計算します。TextUnit(spを表すクラス)は、テキストがスケーリングされる一方でパディングがスケーリングされないことを保証します。
Jetpack Composeでは、spはTextUnit型で表され、誤って要素の寸法に使用することはできません。Dpが期待される場所にTextUnitが渡されると、Kotlinコンパイラはエラーを出します。これにより、誤ったスケーリングに関連するバグのクラス全体が排除されます。
// ComposeでのTextUnit — 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
)
}
}
// spでのfontSizeの明示的設定
Text(
text = "カスタムサイズ",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)ComposeにはXML属性android:textSizeの直接の同等物はありません—テキストサイズはTextStyle.fontSizeを介して設定されます。MaterialTheme.typographyシステムは、Material Design Type Scaleに対応する事前定義されたスタイルを提供します。カスタムサイズが必要な場合は、20.spリテラルが使用されます—言語はこれがTextUnitでありDpではないことを保証します。
spの適切な使用は、アクセシブルなAndroidアプリケーションの基盤です。以下は、Google Material DesignとAndroid Developers Guideの推奨に基づくルールです。
アクセシビリティの主なルール: ユーザーは機能を失うことなくフォントサイズを大きくできるべきです。アプリケーションが1.3×のフォントスケールで正しく動作する場合、基本的なアクセシビリティテストに合格します。textSizeがdpで設定され、インターフェースがスケーリングしない場合、Google Playはアプリケーションを拒否する可能性があります。
よくある質問
sp(scale-independent pixel)はシステムフォントサイズが変わるとスケーリングされますが、dpはスケーリングされません。spはテキストのみに使用され、dpは他のすべての要素の寸法に使用されます。変換係数: sp = dp × FONT_SCALE。
いいえ。パディング、ボタンの高さ、カードの幅はdpで設定する必要があります。パディングにspを使用すると、フォントが大きくなったときに要素が不自然に成長し、画面の境界を超える可能性があります。
Settings > Display > Font sizeを開き、最大値(Largest)に設定します。アプリケーションを起動し、すべてのテキストが読めること、要素が重ならないこと、ボタンが画面の境界を超えないことを確認します。自動化には、UiAutomatorとともにEspressoを使用します。
Material DesignはlabelSmallに最小サイズ11spを推奨しています。本文テキストには、14sp(bodyMedium)〜16sp(bodyLarge)。11sp未満のサイズは、高ピクセル密度デバイスで読みにくくなるため推奨されません。
テキストはシステムフォント設定に関係なく固定サイズで表示されます。フォントを大きくしたユーザーはそのテキストを快適に読めません。これはWCAGアクセシビリティ要件に違反し、Google Playでアプリケーションが拒否される原因となる可能性があります。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。