CodeKitHub
CSSツール

React Native シャドウジェネレーター

最終更新:

React Native のシャドウはプラットフォームごとに仕組みが異なります。iOS は shadowColor、shadowOffset、shadowOpacity、shadowRadius を読み取りますが、Android はそれらをすべて無視し、代わりに独立した elevation の数値が必要です。ここでシャドウを視覚的に調整して、両プラットフォームに対応した style オブジェクトをコピーできます。New Architecture を使うアプリ向けの新しいクロスプラットフォーム boxShadow 文字列も含まれます。

iOS reads the shadow* props; Android ignores them and uses elevation instead — set both so the shadow shows up on both platforms.

このツールとは?

React Native では、シャドウはデフォルトでクロスプラットフォームではありません。iOS は4つの独立したスタイルプロパティ(shadowColor、width/height を持つ shadowOffset、0〜1 の shadowOpacity、ぼかしを表す shadowRadius)を使い、これらは Web の box-shadow と同じ CoreAnimation のシャドウ機構にマッピングされます。Android のネイティブ View システムは任意の形状のシャドウを一切サポートしておらず、elevation という単一の数値のみをサポートします。これはビューがどれだけ「浮いて」見えるかに基づいて、固定形状の Material Design ドロップシャドウを生成します。

つまり、shadowRadius/shadowOpacity を使って iOS 上で正しく見えるシャドウも、elevation を別途設定しない限り Android では何も表示されません。また elevation のシャドウ形状は iOS のように自由にカスタマイズできないため、両者が完全にピクセル単位で一致することはありません。New Architecture を有効にした React Native 0.74 以降では、CSS と同じ構文を使うクロスプラットフォームの boxShadow スタイルプロパティも利用できます。

なぜこれを使うのか?

  • オフセット、ぼかし、不透明度、色を調整しながらライブプレビューで確認できるので、値を推測してアプリを再ビルドして確認する必要がありません。
  • iOS のシャドウプロパティ、Android の elevation、新しいクロスプラットフォームの boxShadow 文字列を一度に取得でき、3つの異なる API を調べる手間が省けます。
  • elevation はぼかし/不透明度から自動計算されない独立したコントロールです。Android の elevation とシャドウの見た目のマッピングは iOS のシャドウプロパティを直接変換したものではないためで、視覚的に一致するよう自分で調整する必要があります。このツールでは両者を並べて比較しながら調整できます。
  • 無料・即時生成で、1つの style オブジェクトとしてそのままコピーできます。

使い方

  1. オフセット X/Y、ぼかし半径、不透明度、シャドウの色を調整すると、プレビューボックスがリアルタイムに更新されます。
  2. 意図したシャドウの強さに視覚的に一致するまで、Android の elevation 数値を別途調整します。
  3. 「Copy」をクリックして、iOS プロパティ、Android の elevation、boxShadow 文字列を含む完全な style オブジェクトをコピーします。
  4. そのオブジェクトをコンポーネントの StyleSheet に貼り付け、既存の View スタイルと展開・マージして使います。

入力

オフセット (0, 4)、ぼかし 8、不透明度 0.25、黒、elevation 5

出力

shadowColor: '#000000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 5, boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.25)'

shadowRadius はプレビューに表示されるぼかし値の半分に設定されます。これは CSS のぼかし半径と iOS の shadowRadius の実際の対応関係に合わせたものです。

よくある質問

Android でシャドウが表示されないのはなぜですか?

shadowColor/shadowOffset/shadowOpacity/shadowRadius プロパティは iOS 専用です — Android のネイティブレンダリングはこれらを単純に無視します。Android でシャドウを表示させるには、elevation プロパティ(正の数値)も設定する必要があります。

Android のシャドウを iOS と完全に同じ見た目にできますか?

完全には無理です — elevation は Android 組み込みの Material Design シャドウ形状を生成しますが、iOS のシャドウのように色・オフセットの方向・ぼかしを個別に設定することはできません。elevation の数値を調整して視覚的に近い強さにすることはできますが、従来の shadow/elevation API ではプラットフォーム間でピクセル単位の完全一致は実現できません。

boxShadow プロパティとは何ですか?代わりに使えますか?

boxShadow は React Native 0.74 で追加された、真にクロスプラットフォームな新しいスタイルプロパティです(New Architecture が必要)。CSS の box-shadow と同じ文字列構文を使い、iOS と Android で同一に動作します。アプリの React Native バージョンとアーキテクチャが対応していれば、4つの iOS プロパティと elevation の代わりにこの1つのプロパティだけを使うことができます。本番環境で利用する前に、RN のバージョンと New Architecture の有効化状況を確認してください。

なぜ shadowRadius は設定したぼかし値の半分になるのですか?

ライブプレビューは CSS の box-shadow を使用しており、同じ数値でもぼかし値は iOS の shadowRadius よりおよそ2倍広がります。生成されるコードでは shadowRadius をぼかし値の半分に設定することで、プレビューで見えるシャドウが iOS の実際の描画結果と一致するようにしています。ぼかし値をそのままコピーすると、iOS 上のシャドウはプレビューより明らかに柔らかく大きく見えてしまいます。

これらのスタイルを適用するのに Platform.select は必要ですか?

いいえ — 生成されたコードのように、iOS の shadow* プロパティと Android の elevation を1つの style オブジェクトにまとめても問題ありません。各プラットフォームは自分に関係ないプロパティを単純に無視するだけです。Platform.select が必要なのは、プラットフォームごとに本当に異なるシャドウデザインにしたい場合だけで、警告を避けるためではありません(そもそも警告は出ません)。

elevation を設定したのに Android でシャドウが表示されません。なぜですか?

最も多い2つの原因があります。1つはビューに backgroundColor が設定されていないこと(Android の elevation シャドウはビューの不透明な背景から投影されるため、透明なビューは何も投影しません)。もう1つは親要素に overflow: 'hidden' が設定されていてシャドウが切り取られていることです。elevation の値自体を疑う前に、まずビューに単色の背景色を設定し、祖先要素の overflow 設定を確認してください。

関連ツール