React Native でライブラリを使っていて style の上書きがうまくできないことがあります。配列によるスタイル指定が機能しなかったり。
今回は margin の上書きが出来なかったことから色々試してみたという内容です。
バニラで書いてると気づきやすいですが、フレームワーク+ライブラリの状態だとハマりやすいので気を付けましょう。
効かないスタイル変更の原因
今回の対象は react-native-elements の ButtonGroup です。
こんな感じで margin:0 の普通のボタングループを作成します。
|
1 2 3 4 5 6 7 8 9 10 |
<ButtonGroup onPress={onPress} selectedIndex={idx} buttons={buttons} containerStyle={{ margin:0, }} textStyle={{ fontSize: 16, textAlign: "center" }} selectedButtonStyle={styles.selected} /> |
親Viewにくっつく形のボタングループにしたかったのですが、マージンが残ります、

padding, border, widthなどいじりまわすも、やはりmarginの問題でした。
ソースを見ると、該当箇所はこう。
|
1 2 3 4 5 6 7 8 |
<View {...attributes} style={StyleSheet.flatten([ styles.container, vertical && styles.verticalContainer, containerStyle && containerStyle, ])} > |
styles.container はこうなってます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const styles = { ... , container: { marginHorizontal: 10, marginVertical: 5, borderColor: '#e3e3e3', borderWidth: 1, flexDirection: 'row', borderRadius: 3, overflow: 'hidden', backgroundColor: '#fff', height: 40, }, ... } |
通常のCSSだと margin-top の後ろに margin を指定すると上書きできますが、このmarginHorizontalやmarginVerticalは上書きできませんでした。
とりあえず対処方法は簡単です。問題のスタイルを0にします。
|
1 2 3 4 5 6 7 8 9 10 11 |
<ButtonGroup onPress={onPress} selectedIndex={idx} buttons={buttons} containerStyle={{ marginHorizontal: 0, marginVertical: 0, }} textStyle={{ fontSize: 16, textAlign: "center" }} selectedButtonStyle={styles.selected} /> |
![]()
borderTop だけ残して色々いじるとこういう感じになります。

下の4つがボタングループでタブ化したメニューになります。
marginの上書きについて
なんで上書きできないのかもう少し掘り下げてみましょう。
単純な正方形のViewを2つ作ってスタイルがどう上書きされるか見ます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
import React from "react"; import { StyleSheet, View } from "react-native"; export default function App() { return ( <View style={styles.container}> <View style={styles.s1}> <View style={[styles.s2, styles.margin3]} /> </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", alignItems: "center", justifyContent: "center", }, s1: { width: 100, height: 100, backgroundColor: "red" }, s2: { width: 20, height: 20, backgroundColor: "green" }, margin1: { margin: 10, marginHorizontal: 50, }, //marginHorizontal > margin margin1b: { marginHorizontal: 50, margin: 10, }, // = 1 margin2: { marginLeft: 5, marginHorizontal: 50, margin: 10, }, //marginLeft > marginHorizontal > margin margin2b: { marginHorizontal: 50, marginLeft: 5, margin: 10, }, // = 2 margin2c: { marginHorizontal: 50, margin: 10, marginLeft: 5, }, // = 2 margin3: { marginStart: 10, marginEnd: 10, marginLeft: 20, marginRight: 20, marginTop: 20, marginBottom: 20, marginHorizontal: 50, marginVertical: 50, margin: 100, }, }); |

こんな感じの優先順位があって後ろに書くだけでは上書きできないです。
左:marginStart > marginLeft > marginHorizontal > margin
下:marginBottom > marginHorizontal > margin
より細かい指定方法が上位(かつStart, End > Left, Right)のようです。
これは padding も同様でした。
ちゃんと上書きするために
面倒ですがライブラリの実装を見て同じプロパティを上書きするのが一番良いと思いますが普通に面倒くさいです。
margin や padding は string 指定ができるので、複数指定や !important など出来ないかと試行錯誤してみたけど良い方法は見つからなかった。
とりあえずの処置なら最も強い要素で上書きするのが簡単です。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
const styles = StyleSheet.create({ reset: { marginStart: 0, marginEnd: 0, marginTop: 0, marginBottom: 0, paddingStart: 0, paddingEnd: 0, paddingTop: 0, paddingBottom: 0, }, }); |