お気持ちの表明

思考を雑に外出していきます

React Native におけるテキストの垂直中央揃え問題とその解決策

[!NOTE] この記事は筆者が下書きした内容をAIを活用して文章化し、筆者が監修して執筆しました。

React Native Advent Calendar 2025 10日目の記事です。

また、この記事は、先日の React Native Meetup #23 @サイバーエージェント で発表した内容を記事にしたものになります👏

speakerdeck.com


React Native でクロスプラットフォーム開発を行う際、テキストの垂直中央揃えが AndroidiOS で一致しないという問題に直面することがあります。iOS では意図したとおりに中央揃えされるのに、Android では上寄りや下寄りになってしまうということは稀によくあると思います。

本記事では、この問題の根本原因であるフォント描画方式の差異を明らかにし、プラットフォームごとに適切な対処法を提示します。

フォントには2つの高さ基準がある

テキストの垂直配置を理解するには、フォントが持つ2種類の高さ基準を知る必要があります。フォントには top/bottomascent/descent という、異なる目的で定義された高さの概念が存在します。

トップ(Top)とボトム(Bottom)は、フォントに含まれるすべての文字(アクセント記号などを含む)が占める可能性のある最大領域を示します。

アセント(Ascent)とディセント(Descent)は、文字が上下に占める標準的な領域を示します。これはフォントデザイナーが意図した、タイポグラフィ上の「高さ」を定義します。

プラットフォームによる描画方式の違い

iOS は ascent/descent を基準にする

iOSascent/descent を基準としてテキストを描画します。このため、多くの場合で追加の調整なしに適切な垂直中央揃えが実現されます。

Android は top/bottom を基準にする

Android には includeFontPadding というプロパティがあり、デフォルトで true に設定されています。この設定により、Androidtop/bottom を基準としてテキストを描画するため、iOS とフォントの高さに差分が生じます。

includeFontPaddingfalse に設定すると、Androidascent/descent を基準として使用し、iOS との整合性が取れるようになります。

なお、この includeFontPadding は元々、一部の言語で文字が切れないようにするための安全策として導入されたものです。しかし、Jetpack Compose など現代的な Android 開発では、このプロパティのデフォルト値が false に変更される傾向にあり、レガシーな機能となっています。

kaleidot.net

プラットフォーム別の対処法

Android での対処法

Android でテキストの垂直中央揃えを実現するには、3つの要素を組み合わせます。

1. includeFontPadding: false を設定

iOS と同じ ascent/descent 基準に切り替え、余分なパディングを削除します。

2. lineHeight を fontSize の 1.2〜1.5 倍に設定

includeFontPadding: false にすると文字が見切れることがあるため、Material Design Guideline に従って適切な lineHeight を設定します。

For larger type legibility using styles like title, headline, and display, we recommend a line height ratio of 1.2 times the type size.

For smaller body copy using styles like body and label, we recommend a line height ratio around 1.5 times the type size. If your line height is too tight, you’ll undermine the flow of the text. Too loose, and the lines won’t feel cohesive.

Typography – Material Design 3

3. textAlignVertical: 'center' で垂直中央揃え

Android 固有のプロパティで、テキストを垂直方向に明示的に中央揃えします。

const styles = StyleSheet.create({
  centeringText: {
    fontSize: 16,
    lineHeight: 24, // Material Design Guideline推奨値(1.5倍)
    includeFontPadding: false, // 余分なpaddingを消す
    textAlignVertical: 'center', // 垂直中央揃え
  },
});

iOS での対処法

iOS はデフォルトフォントであれば特別な設定は不要です。調整が必要な場合は、lineHeightfontSize と同じ値にして、フォントの上下余白を最小化します。textAlignVerticaliOS には存在しないため、上下の余白で調整します。

const styles = StyleSheet.create({
  centeringText: {
    fontSize: 16,
    lineHeight: 16, // フォントの上下余白を最低限に
  },
});

実践的な実装パターン

実際のプロジェクトでは、プラットフォーム固有の設定を Platform.select を使って管理することで、保守性の高いコードを実現できます。以下は、デフォルトスタイルと中央揃えスタイルを定義した実装例です。この実装パターンでは、default スタイルで基本的なフォント設定を定義し、centeringText スタイルで中央揃えに特化した設定を行います。Platform.select を使用することで、プラットフォーム固有の設定が明示的になり、コードの意図が明確になります。あとはこのstylingをしたText Componentを alignItem: 'center' をwrapすれば、iOS/Androidどちらも同じようにcenteringできます。

const styles = StyleSheet.create({
  default: {
    fontSize: 16,
    lineHeight: 24, // 1.5倍(Material Design Guideline推奨値)
    ...Platform.select({
      android: {
        includeFontPadding: false, // iOS との整合性を取る
      },
    }),
  },

  centeringText: {
    fontSize: 16,
    lineHeight: 24,
    ...Platform.select({
      android: {
        includeFontPadding: false,
        textAlignVertical: 'center', // Android で垂直中央揃え
      },
      ios: {
        // iOS ではデフォルトで中央揃えされるため追加設定不要
        // カスタムフォントの場合は lineHeight: 16 を検討
      },
    }),
  },
});

まとめ

React Native におけるテキストの垂直中央揃え問題は、iOSAndroid がフォントの高さ基準を異なる方法で解釈することに起因します。iOSascent/descent を基準とするのに対し、Android はデフォルトで top/bottom を基準とするため、同じコードでも表示結果が異なります。

この問題を解決するには、AndroidincludeFontPadding: false、適切な lineHeight、そして textAlignVertical: 'center' を組み合わせることで、プラットフォーム間で一貫した UI を実現できます。フォントの描画方式という基礎的な理解が、実践的な問題解決の鍵となるのです。