sp: とは、Androidテキスト用のスケーラブルピクセル

著者: IT Sectr 公開日: 2026-02-25 読了時間: 9 分

sp — Scale-independent Pixels、デバイスのフォントサイズ設定を考慮したAndroidのテキスト測定単位です。dpとは異なり、spはシステムフォントサイズに合わせてスケーリングされ、インターフェースのアクセシビリティを確保します。この記事では、spとdpの違いを説明し、XMLやKotlinでのtextSize設定方法を示し、Androidでのタイポグラフィに関するベストプラクティスを紹介します。

重要ポイント

  • sp — ユーザーのシステムフォント設定に応じてスケーリングされるテキスト単位
  • dp — 要素の寸法の単位、フォントサイズ変更に反応しない
  • spとdpの違い: sp = dp × scaleFactor(scaleFactorはフォント設定に依存)
  • XMLでのtextSize はspで指定: android:textSize="16sp"
  • Material Design は見出しに12sp〜34spのタイポグラフィ範囲を推奨

Androidにおけるspとは?

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 vs dp: 主な違い

spdpの違いは、Android開発者の面接や実際のコードレビューで最もよくあるトピックの1つです。どちらの単位も密度非依存ピクセル(mdpi画面では160 dpi = 1 dp = 1 px)に結びついていますが、システムフォントサイズが変わると異なる動作をします。

特性spdp
目的テキストサイズ要素の寸法、パディング、幅、高さ
フォントスケーリングあり(スケール係数)なし
密度スケーリングありあり
設定APIandroid:textSizeandroid:layout_width, layout_height, padding, margin
Material Designトークンtypescalespacing, sizing

実際によくある間違いは、テキストにdpを使用することです。テキストがdpで設定されている場合、フォントサイズが大きくなってもスケーリングされず、視力の弱いユーザーにとってインターフェースがアクセス不能になります。逆の間違いは、ボタンの高さやパディングにspを使用することです。フォントが大きくなるとボタンが「膨らみ」、レイアウトが崩れる可能性があります。

spのスケーリングの仕組み

spのスケーリングは、Android FrameworkレベルでTypedValueクラスに実装されています。変換式: sp = dp × scaledDensity(scaledDensityは画面密度とユーザーのフォントサイズ設定の両方を考慮したスケーリング係数)。

kotlin
// 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の使用

XMLレイアウトでは、spは排他的にandroid:textSize属性で使用されます。他のすべての寸法(幅、高さ、パディング、マージン、エレベーション)はdpで設定されます。ルールは簡単です: 要素がテキストを表示する場合、サイズはspで;要素がジオメトリを定義する場合、サイズはdpです。

XMLでのtextSizeの基本例

xml
<!-- 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ファイルに抽出することをお勧めします。これにより、タイポグラフィのメンテナンスが簡素化され、異なる画面構成に合わせてサイズを上書きでき、アプリケーション全体で一貫性が確保されます。

タイポグラフィトークンを含むdimens.xml

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)はサブピクセル配置のためにレンダリングを低下させます。

Kotlinでのタイポグラフィ設定

現代のAndroid開発では、テキストがspのtextSizeを介して直接設定されることはめったにありません。代わりに、MaterialTheme.typographyシステムが使用され、各スタイルが事前定義され、サイズ、太さ、行の高さ、文字間隔が含まれます。

kotlin
// 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

Jetpack Composeでは、spはTextUnit型で表され、誤って要素の寸法に使用することはできません。Dpが期待される場所にTextUnitが渡されると、Kotlinコンパイラはエラーを出します。これにより、誤ったスケーリングに関連するバグのクラス全体が排除されます。

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のベストプラクティス

spの適切な使用は、アクセシブルなAndroidアプリケーションの基盤です。以下は、Google Material DesignとAndroid Developers Guideの推奨に基づくルールです。

  • テキストには常にspを使用 — textSizeをdpやpxで設定しないでください。そうしないと、フォントを大きくしたユーザーがインターフェースを読めなくなります
  • コンテナにはdpを使用 — ボタンの高さ、パディング、カードの幅はdpにする必要があります。そうしないと、大きなフォントで要素が重なる可能性があります
  • サイズをdimens.xmlに抽出 — タイポグラフィトークンの集中管理により、リファクタリングとダークテーマのサポートが簡素化されます
  • 12sp未満のspは使用しない — 小さなテキストは、高PPIデバイスや標準フォントサイズで読みにくくなります
  • 最大フォントスケールでテスト — デバイス設定で最大フォントを有効にし、インターフェースが壊れないことを確認します

アクセシビリティの主なルール: ユーザーは機能を失うことなくフォントサイズを大きくできるべきです。アプリケーションが1.3×のフォントスケールで正しく動作する場合、基本的なアクセシビリティテストに合格します。textSizeがdpで設定され、インターフェースがスケーリングしない場合、Google Playはアプリケーションを拒否する可能性があります。

よくある質問

spとdpの違いは何ですか?

sp(scale-independent pixel)はシステムフォントサイズが変わるとスケーリングされますが、dpはスケーリングされません。spはテキストのみに使用され、dpは他のすべての要素の寸法に使用されます。変換係数: sp = dp × FONT_SCALE。

パディングにspを使用できますか?

いいえ。パディング、ボタンの高さ、カードの幅はdpで設定する必要があります。パディングにspを使用すると、フォントが大きくなったときに要素が不自然に成長し、画面の境界を超える可能性があります。

アプリがspで正しく動作することを確認するには?

Settings > Display > Font sizeを開き、最大値(Largest)に設定します。アプリケーションを起動し、すべてのテキストが読めること、要素が重ならないこと、ボタンが画面の境界を超えないことを確認します。自動化には、UiAutomatorとともにEspressoを使用します。

spで許可される最小テキストサイズは?

Material DesignはlabelSmallに最小サイズ11spを推奨しています。本文テキストには、14sp(bodyMedium)〜16sp(bodyLarge)。11sp未満のサイズは、高ピクセル密度デバイスで読みにくくなるため推奨されません。

textSizeをdpで設定するとどうなりますか?

テキストはシステムフォント設定に関係なく固定サイズで表示されます。フォントを大きくしたユーザーはそのテキストを快適に読めません。これはWCAGアクセシビリティ要件に違反し、Google Playでアプリケーションが拒否される原因となる可能性があります。

まとめ

  • sp — FONT_SCALEを介してユーザー設定に応じてスケーリングされるAndroidのフォント測定単位
  • dp — フォントサイズ変更に反応しない要素寸法の単位
  • textSize はXMLでandroid:textSize="16sp"として設定、他のすべての寸法はdp
  • MaterialTheme.typography はJetpack Composeで型安全性のためにTextUnit(.sp)を使用
  • dimens.xml — 一貫性のためのタイポグラフィトークンの集中管理
  • 最小サイズ テキスト — 11sp、本文推奨 — 14〜16sp
  • テスト 最大フォントスケールで — アクセシビリティ確認の必須手順

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください