LoginSignup
1
0

More than 1 year has passed since last update.

react nativeで横並び、折り返し、等間隔の配置を実現するときにハマったこと nth-childもgapもだめ

Last updated at Posted at 2022-05-09

webのreactと同じノリで書こうとしたら、ネイティブアプリの洗礼を受けた話。

基本、前提

普通にcssで実装するなら、、、

  • 横並び→flex-directionのraw
  • 折り返し→wrapを設定
  • 等間隔→space-around、space-between、もしくはgap

この辺を使えばよさそうです。

space-around、space-betweenの問題

wrapした時に行ごとに等間隔にしてしまって不恰好になる。
例えば5個の要素があって、1行に3つごとおきたい場合、

.list-wrapper {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
}

.list-item {
  width: 30%;
}

などとすると3個の行と2個の行に分かれる。
その時3個は等間隔になるが、2個はその2個で等間隔になるので、5個の間隔がバラバラになってしまう。
(この場合1行目は間隔5%だけど、2列目は30%空いてしまう)

結論:wrapと組み合わせるならspace-around、space-betweenは使わない方がいい。

解決1(失敗)

gapを使おう
https://developer.mozilla.org/ja/docs/Web/CSS/gap

.list-wrapper {
  gap: 1em; 
  gap: 10px 20px; // 縦 横
}

のようにすると自動的に間隔を付けてくれる。
(もちろん端にはつけず、要素の間だけつけてくれる)

react nativeでgap使えない問題

やってみたらエラーでてどうやら使えないものだということを悟った、、、

解決2(失敗)

widthとmarginだけで解決しよう

例えば3分割したいなら、
30% 5% 30% 5% 30%で分ければ良いので

.list-item {
  width: 30%;
  &:not(:nth-child(3n)) {
    margin-right: 5%;
  }
}

という実装ができる。

react nativeでnth-child使えない問題

何とこっちも使えない。
エラーが出るのではなく、単純にnth-child部分が無視された表示になった。
どうやらnth-childのみならず、last-childとかも含めて使えないらしい。

ということでそれにあたるロジックを自分で書く必要があった。

解決3(成功)

今回はstyled-componentsでの実装。

ロジックはcss内に書くこともできるのかもしれないが、なんか上手くいかなかったのでjsx/tsx内で解決した。

方針としては解決2と似ていて、nth-childの代わりにmap時のkeyに使われるidxを使って分岐させる処理を書く。

まずはnth-childしたかったcomponentにmarginRightというpropsを追加。

{datas.map((data, idx) => {
  return (
    <YourStyledComponent marginRight={idx % 3 === 2 ? '0%' : '5%'}>
    </YourStyledComponent>
  )
})}

と三項演算子で分岐処理を実装。
idxは0スタートなので、こうすることで3n番目の要素のみmarginRightを0にできる。

これをstyled componentで受け取る。

const YourStyledComponent = styled.View<{marginRight: string}>`
  width: 30%
  margin-right: ${({marginRight}): string => marginRight}
`

これでいけました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0