React Nativeアプリのマークアップにおいても、要素を上下左右に中央寄せにする場合、もちろんスタイルシートによって配置する。この点はWebアプリと変わらない。
しかしReact Nativeのスタイル適用の特徴は、JavaScript記法であること、および梱包要素のボックスモデルのdisplay値はFlexboxであることだろう。
まず「JavaScript記法であること」においては、CSSプロパティ名の単語の先頭を大文字にしなければならない。font-size
はfontSize
と書く。いわゆるキャメルケースと呼ばれる記法のことである。
そして「ボックスモデルのdisplay値がFlexboxであること」においては、それほど弊害もなくいつも通りのCSSの知識が役立つことだろう。しかしflex-direction
のデフォルト値がcolumn
である点がややこしい。
このエントリーでは、React Nativeの記法で要素を上下左右に中央揃えする方法を紹介したい。
テキストを上下左右に中央寄せ
import React from 'react';
import { StyleSheet, SafeAreaView, Text } from 'react-native';
export default function App() {
return (
<SafeAreaView style={ styles.container }>
<Text>この文章はダミーです。</Text>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}
});
ここでは<SafeAreaView />
に対して、3つのスタイルを適用している。
まずflex: 1,
。これは要素サイズをスクリーン縦横幅いっぱいにしている。この指定がなければ、内包要素の高さを保持することになる。たとえば<SafeAreaView />
が空要素であるならば、高さ0pxということだ。
つづいてalignItems: 'center',
では、横方向に対して中央寄せをしている。そしてjustifyContent: 'center',
が縦方向だ。
お気づきだろう。Flexboxの主軸の向きが縦軸時の指定であると。そう。WebアプリにおけるCSSだとデフォルトの主軸は、alignItemsは縦方向で、justifyContentは横方向だった。そしてflex-direction: column;
として縦軸にするとalignItemsが横方向で、justifyContentが縦方向の指定に変化することを思い出せる。
このようにReact Nativeの梱包要素のボックスモデルのdisplay値はFlexboxであり、デフォルトで縦軸になっているのである。
すこしややこしいが、そのようなものだと覚えてもらえると助かる。
画像を上下左右に中央寄せ
import React from 'react';
import { StyleSheet, SafeAreaView, Image } from 'react-native';
const thumb = require('./assets/horse.jpg');
export default function App() {
const assetImg = Image.resolveAssetSource(thumb);
return (
<SafeAreaView style={ styles.container }>
<Image
style={[styles.thumbnail, {
transform: [
{ translateX: - assetImg.width / 2 },
{ translateY: - assetImg.height / 2 },
]
}]}
source={thumb} />
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
thumbnail: {
position: 'absolute',
top: '50%',
left: '50%',
}
});
画像を上下左右に中央寄せする程度のことは、前述の「テキストを上下左右中央寄せ」の記述で実現できることだろう。だけれど、もし上記ソースコードの<SafeAreaView />
に画像以外の内包要素が存在していて、それらはいずれも左寄せで、画像はかぶさる具合に中央寄せするなんてときは、梱包要素で中央寄せ指定ができない。
そこで画像にのみ中央寄せを施すわけだ。内約はposition: 'absolute';
で、親要素を基準にしたtop: '50%', left: '50%',
の相対位置に配置する。そしてtransformプロパティのtranslateXとtranslateYでネガティブポジションすれば、果たして中央寄せができる。
もし画像の裏にタップしたいコンテンツやスクロールしなければならないような場合は、<Image />
のpointerEvents propsにnoneを与えればタッチイベントが透き通るはずだ。
まとめ
React Nativeで要素を上下左右に中央寄せする方法の紹介だった。
梱包要素に対して適用する方法と固有要素に対して適用する方法をご覧いただいたが、いずれの方法も親要素ありきであることは覚えておきたい。そもそも親要素に高さがなければ、上下中央にはならない。したがってflex: 1;
としてスクリーンサイズに吸着させたり、
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
としたりする工夫が必要だ。
このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。