Chakra UIの横並び・縦並びしたいとき使うStack(HStack・VStack)・Flexの違いと使い分け

JavaScript

UI・コンポーネントライブラリはWebアプリを作るときに、開発はしたいけどデザインに苦手意識を持っていてなかなか進まない、そんなときに便利な存在ですが、Reactを使う人の中には「Chakra UI」を使っている人も多いんじゃないでしょうか?

ただ、Chakra UIを使い始めた人が気になるであろう点があります。

それが「Stack系の種類の多さ」と「Flexコンポーネントとの違い」です。

今回はそんな似たようなコンポーネントの違いと使い分けについてみていきたいと思います!

そもそもChakra UIって?

Chakra UIはアクセシビリティを重視したコンポーネントライブラリで、2024年4月に改正された障害者差別解消法に対するアクセシビリティ対応に有効とされるライブラリの一つです。

豊富なコンポーネントが用意されていて、レスポンシブ対応も行われている使いやすくなっています。

Chakra UIにはレイアウトを組むためのコンポーネントがいくつも用意されていて、その中の一つにStackFlexがあります。

Stackとは?

Web制作でCSSを使っている人にはFlexコンポーネントの使い方は説明を見なくてもなんとなくイメージできると思いますが、Stackコンポーネントって聞きなじみがないかもしれません。

Chakra UIの公式ドキュメントにはこんな説明が。

Stack is a layout component used to group elements together and apply a space between them.

スタックは、要素をグループ化し、それらの間にスペースを適用するために使用されるレイアウトコンポーネントです。(DeepL訳)

Chakra UI公式ドキュメント「Stack」コンポーネント

つまり、StackFlexのように横並びや縦並びをさせたいときに使うコンポーネントです。

StackとFlexってどう違うの?

StackFlexも横並びや縦並びをしたいときに使うコンポーネントと説明しましたが、じゃあどう違うん?どう使い分ければええの?って思いますよね?

まずはそれぞれの特徴を見ていきましょう。

Stack(HStack、VStack)

Stackコンポーネントには、StackHStackVStackの3種類が用意されています。

HStackVStackはそれぞれ横並びや縦並びのために特化した、言わばショートカットのようなコンポーネントです。

HStackは子要素を横並びに、StackVStackは子要素を縦並びに配置します。

StackVStackも同じじゃん!と思うかもしれませんが、そこはショートカットたる所以と言いますか、デフォルトでStackは左寄せ、VStackは中央寄せになります。(HStackも横並びのまま、垂直方向に中央寄せとなります。)

Flex

Flexコンポーネントは言わずもがな、デフォルトで横並びになるコンポーネントです。

ただStackと異なるのは、使えるプロパティが違うという点とデフォルトでの子要素間の余白です。

例えば、Stack系では子要素間の余白を指定するspacing属性(CSSでいうgapプロパティ)が使えますが、Flexでは使えません。

逆にFlexではflexレイアウト専用のプロパティのショートハンドが用意されていて、flexDirectionならdirectionflexWrapならwrapといった、属性を省略して指定することができます。

違いがよくわからんのだが?

ここまで説明を見るとそれぞれのコンポーネントの違いがあまりないように感じますね。

それではどう使い分けるといいのでしょうか?

Chakra UIの公式ドキュメントにはこんなことが書いてあります。

The Stack component and the Flex component have their children spaced out evenly but the key difference is that the Stack won’t span the entire width of the container whereas the Flex will. Another thing to note is that the items in both Stack and Flex are aligned in the center by default.


StackコンポーネントとFlexコンポーネントは、子コンポーネントの間隔が均等ですが、重要な違いは、Stackがコンテナの幅いっぱいに配置されるのに対し、Flexはコンテナの幅いっぱいに配置されないことです。もうひとつ注意すべき点は、StackとFlexのアイテムはどちらもデフォルトで中央に配置されていることだ。(DeepL訳)

Chakra UI公式ドキュメント「Stack」コンポーネントより

Flex and Spacer vs Grid vs Stack#

The Flex and Spacer components, HStack treat children of different widths differently.

  • In HStack, the children will have equal spacing between them but they won’t span the entire width of the container.
  • With Flex and Spacer, the children will span the entire width of the container and also have equal spacing between them.

フレックスとスペーサーとグリッドとスタックの比較

FlexとSpacerコンポーネント、GridとHStackでは、異なる幅の子コンポーネントの扱いが異なります。

HStackでは、子コンポーネントの間隔は等しくなりますが、コンテナの幅全体には及びません。
Gridでは、子要素の始点の間隔は等しくなりますが、子要素間のギャップは等しくなりません。
FlexとSpacerを使用すると、子要素はコンテナの幅全体に広がり、子要素間の間隔も等しくなります。(DeepL訳)

Chakra UI公式ドキュメント「Flex」コンポーネントより

引用が長くなってしまいましたが、つまりFlexではSpacerという子要素間の余白を自動調整するコンポーネントと一緒に使うと、子要素が親要素の幅いっぱいまで広がって配置されて、Stackでは幅いっぱいまで広がらない、ということでした。

それ(Spacer)、Stackにやらせてください

が、一つ疑問に浮かぶ方もいるかもしれません。

そう、FlexSpacerをセットで、というのなら、StackSpacerをセットでは使えないのか?というところ。

実際のところ・・・使えます。

Chakra UIの公式ドキュメントにはお試し機能があるので、ぜひ下のコードをコピペして試してみてください。

import { Stack, HStack, Flex, Spacer, Box } from '@chakra-ui/react';

export const App = () => {
  return (
    <Stack spacing={4} px={4} py={16}>
      <HStack spacing='0' h={100} border="1px">
        <Box w='40px' h='40px' bg='yellow.200'>
          1
        </Box>
        <Box w='40px' h='40px' bg='tomato'>
          2
        </Box>
        <Spacer />
        <Box w='40px' h='40px' bg='pink.100'>
          3
        </Box>
      </HStack>
      <Flex border="1px" h={100} align="center">
        <Box w='40px' h='40px' bg='yellow.200'>
          1
        </Box>
        <Box w='40px' h='40px' bg='tomato'>
          2
        </Box>
        <Spacer />
        <Box w='40px' h='40px' bg='pink.100'>
          3
        </Box>
      </Flex>
    </Stack>
  )
}

サンプルコードではHStackFlexを使って横並びにしていますが、全く同じ見た目を再現できており、StackでもしっかりSpacerが使えています。

ただ、HStackにはデフォルトでgapプロパティが付与されるようになっているので、余白なしで配置したい場合には打消しのための属性指定が必要なので少し冗長になってしまいますので、その場合はFlexを使うといいでしょう。

結論

FlexStackの違いについてみてきましたがどうでしょうか?

どの場面でどれを使っても同じように再現はできるので、ここではコレ!という決まりはありません。

ですが、コンポーネントによってスタイルの打消しが必要だったり、重複したりする場合もあるので、コードが煩雑にならないように気を付けて使っていきましょう。

タイトルとURLをコピーしました