CodeZine(コードジン)

特集ページ一覧

カスタマイズ性と生産性を両立する、React向けのUライブラリ「Chakra UI」の魅力的な部品【中編】

現場で役立つ! React向けライブラリ詳説 第7回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2021/11/26 11:00

 前回はChakra UIのどんな特性が生産性に寄与しているのかを解説しました。今回はReact向けのUIライブラリとしてのChakra UIに、どんな部品が用意されているのか見ていきます。実用的な多くのコンポーネントやHooksは、きっとWebアプリケーションを組み上げる際の助けとなることでしょう。

目次

対象読者

  • JavaScriptとWeb開発の基礎に理解がある方
  • Reactを用いたJavaScriptアプリケーション開発の経験者

前提環境

 筆者の検証環境は以下の通りです。

  • macOS Big Sur 11.5.2
  • Node.js 16.11.1/npm 8.0.0
  • React 17.0.2
  • react-scripts 4.0.3
  • @chakra-ui/react 1.6.10

Webアプリ制作時に嬉しいコンポーネントとHooks

 前回に引き続き、今回もChakra UIについて解説します。Chakra UIは、React向けのUIライブラリとしては後発の部類ですが、Webアプリケーション制作で必要となるコンポーネントを多く備えていることからか、たくさんの採用事例が現れました。最近だとメルカリShopsのフロントエンド実装で採用されたのが記憶に新しいですね。

 どんなコンポーネントやHooksの存在が魅力的なのか、今回と次回の2回に分けて解説していきます。公式ドキュメントのジャンル分けをもとに、次のように基礎編と応用篇に分けて解説します。

  • 基礎編(今回)
    • レイアウトに関するコンポーネント
    • テキスト表示に関するコンポーネント
    • メディア表示に関するコンポーネント
  • 応用編(次回)
    • フォームに関するコンポーネント
    • データ表示に関するコンポーネント
    • フィードバックに関するコンポーネント
    • オーバーレイに関するコンポーネント
    • データの表示・非表示切り替えに関するコンポーネント
    • ナビゲーションに関するコンポーネント
    • 便利なHooks

 基礎編では、デスクトップアプリやモバイルアプリを開発する文脈でも基礎とされることが多い、レイアウト、テキスト表示、画像表示について主に扱います。応用編では、特定の目的に特化したコンポーネントについて解説します。また、React Hooksで作られた便利なインターフェースも用意されていますが、こちらは応用編で扱います。

レイアウトに関するコンポーネント

 それではまず、レイアウトに関するコンポーネントを見ていきましょう。表1の9種類があります。

表1:レイアウトに関するコンポーネント
コンポーネント 概要
Aspect Ratio 縦横比を維持した領域を作る。
Box コンポーネントを囲んだ領域を作る。
Center 中身を中央寄せで配置する。
Container 大きな画面の中で中央寄せのコンテンツ表示領域を作る。
Flex Flexboxが有効になったBox。
Grid CSS Grid Layoutが有効になったBox。
Simple Grid 複雑でない形でCSS Grid Layoutを扱う。
Stack 縦または横の一方向に要素を並べる。
Wrap flex-wrapが有効になった領域を作る。

 代表的なものについて解説します。

CSSに組み込まれているレイアウトシステム

 Chakra UIには、<Flex><Grid>など、CSSに元々あるレイアウトシステムをそのまま扱うためのコンポーネントがいくつか存在しています。ここで簡単に、CSSに組み込まれたレイアウトシステムについて解説しておきましょう。

 1つ目は主に<Flex>で利用できる Flexbox (フレックスボックス)です。これはCSSでdisplay: flexを指定した要素の中で利用できます。Flexboxは「要素を1方向に並べる」という特性を持ったレイアウトシステムです。縦方向、または横方向のどちらかに要素を並べることができます。中央寄せ・左寄せ・右寄せ・上寄せ・下寄せといった調整が柔軟に行えるため、重宝されています。また、<Wrap>コンポーネントでは、Flexboxのflex-wrap: wrapという指定が有効になっています。これは、Flexboxで要素を並べていく中で親要素の端にぶつかってしまった場合に、折り返して次の段に続きが並ぶというものです。これもまた重宝されています。

 2つ目は主に<Grid>で利用できる CSS Grid Layout (シーエスエスグリッドレイアウト)です。これはCSSでdisplay: gridを指定した要素の中で利用できます。CSS Grid Layoutは「要素を格子上に並べる」という特性を持ったレイアウトシステムです。<table>要素と少し似ていますが、<table>要素は表データを表現するのを目的としているのに対して、こちらは要素を並べることに特化しており、どんな要素でも並べることができます。Webサイトのレイアウト定義(ヘッダー、フッター、メニュー、メインなど)を並べる際には活躍すると思います。

 MDNのドキュメントにより詳しい情報があるので、気になる方は以下をご覧ください。

Box

 基本となるのが<Box>です。基本的に<div>としてレンダリングされることもあり、<div>に近い使い方をします(リスト1)。

[リスト1]Box
<Box w="100px" h="100px" bgColor="teal.400" p="2">
  I am Box.
</Box>

 単に<div>を使う場合との違いとして、スタイルを属性で定義するChakra UIらしい機能が利用できます。今回は「高さ100px、幅100px、背景色はティールの400番、paddingは"2"(0.5rem)」というスタイルを付けました。リスト1を表示すると、図1のようになります。

図1:Box
図1:Box

 属性で設定したスタイル通りの見た目になりましたね。

Container

 さて、小さい領域は<Box>やそこから派生したコンポーネントを扱いますが、ページの一番外側を扱うコンポーネントとして、<Container>が用意されています(リスト2)。

[リスト2]Container
<Container py="3" maxW="600px">
  <Box />
  {/* 各種コンテンツ */}
</Container>

 リスト2を使うと、図2のように、最大の幅を決めてコンテンツを表示できます。

図2:Container
図2:Container

 画面サイズが大きく横長になった現代では、左右に余白を設けて、中央にコンテンツの表示領域を設けることが一般的になりました。<Container>maxWidth属性(maxWとも書ける)で指定した幅で子要素を表示できる、便利なコンポーネントです。デフォルトでは60文字を表す60chの幅になっています。

 <Container>の魅力はこれだけではありません。Chakra UIは全体的にレスポンシブデザインへの対応が容易になるように設計されており、<Container>をスマートフォンで表示した場合、つまりmaxWidthより狭い幅で表示した場合には子要素がスマートフォンの幅まで狭まります(図3)。

図3:Containerをスマートフォンで表示する
図3:Containerをスマートフォンで表示する

 この特性を活用して、Chakra UIでのUI実装では基本的に<Container>の子要素の幅が最大幅となるようにコンテンツのスタイルを組むことが多くなります。以降のサンプルコードの実行例では、基本的に各コンポーネントは<Container>に包まれていることとします。

Center

 次は<Center>です。子要素を中央に寄せて表示します(リスト3)。昔からHTMLを触っている方は<center>要素と近い動きをするといえばわかりやすいかもしれませんが、このコンポーネントでは<center>要素を使わず、Flexboxで中央寄せを実現しています。

[リスト3]Center
<Center w="full" h="200" borderWidth="1px">
  <Box w="100px" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
</Center>

 わかりやすさのためにborderWidth="1px"を付けてあります。リスト3を表示すると、図4のようになります。

図4:Center
図4:Center

 Boxが領域の中央に表示されました。後述する<Flex>でも実現可能ではありますが、手軽に中央寄せを実現する手段として重宝するので、覚えておくとよいでしょう。

Stack

 アプリケーションを作っていると、要素を縦や横の一方向に並べたくなることがよくあります。それを簡便に行うためのコンポーネントが<Stack>です。用途に合わせて、次の3種類が用意されています。

  • VStack:子要素を縦方向に並べる
  • HStack:子要素を横方向に並べる
  • Stack:子要素を縦方向や横方向に並べる

 最も汎用的なのが<Stack>で、そこから並べる方向限定したのが<VStack><HStack>という立場になっています。それぞれの動作を見ていきましょう(リスト4)。

[リスト4]Stack
{/* (1) VStackの例 */}
<VStack spacing="3">
  <Box w="full" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
  <Box w="full" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
  <Box w="full" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
</VStack>
{/* (2) HStackの例 */}
<HStack spacing="3">
  <Box w="full" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
  <Box w="full" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
  <Box w="full" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
</HStack>
{/* (3) Stackの例 */}
<Stack direction={["column", "row"]} spacing="3">
  <Box w="full" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
  <Box w="full" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
  <Box w="full" h="100px" bgColor="teal.400" p="2">I am Box.</Box>
</Stack>

 まずは(1)の<VStack>ですが、「V」は「Vertical」を表しており、子要素を縦方向に並べる機能を持っています。表示すると図5のようになります。

図5:VStack
図5:VStack

 縦方向に並びましたね。spacing="3"を付けたことで、子要素の間に0.75remの隙間ができています。Stack系のコンポーネントを使う大きな利点として、このように簡単に隙間を空けられるというものがあります。

 次は(2)の<HStack>です。「H」は「Horizontal」を表しており、子要素を横方向に並べる機能を持っています。表示すると図6のようになります。

図6:HStack
図6:HStack

 今度は横方向に並びました。<VStack>と同様に、要素間に隙間ができています。それでは最後に、(3)の<Stack>を見てみましょう。<Stack>direction要素にdirection="column"direction="row"といったflex-directionの値を指定することで、子要素を並べる方向を制御できます。

 それだけならば<VStack><HStack>でも代用できるのですが、少し特殊な記法として、direction={["column", "row"]}のように配列を与えて、レスポンシブ対応をさせることもできます。配列の第一要素はスマートフォンでの設定、第二要素がデスクトップでの設定です。そのため、(3)のように書くだけで、図7、図8のようにデスクトップとスマートフォンで別方向に要素を並べることができるのです。

図7:デスクトップでのStackの表示
図7:デスクトップでのStackの表示
図8:スマートフォンでのStackの表示
図8:スマートフォンでのStackの表示

 Stack系のコンポーネントを上手に使い分けることで、要素を並べるUIを短時間で実装できそうですね。

Aspect Ratio

 このジャンルで一番の変わり種は、この<AspectRatio>です。子要素を特定の縦横比で表示します。リスト5の例を見てみましょう。

[リスト5]Aspect Ratio
<HStack spacing="5">
  <AspectRatio w="200px" ratio={4 / 3} bgColor="pink.300">{/* (1) */}
    <Box>Width: 200px</Box>
  </AspectRatio>
  <AspectRatio w="160px" ratio={4 / 3} bgColor="pink.300">{/* (2) */}
    <Box>Width: 160px</Box>
  </AspectRatio>
  <AspectRatio w="120px" ratio={4 / 3} bgColor="pink.300">{/* (3) */}
    <Box>Width: 120px</Box>
  </AspectRatio>
</HStack>
<AspectRatio w="full" ratio={16 / 9} bgColor="pink.300" mt="5">{/* (4) */}
  <Box>Width: full</Box>
</AspectRatio>

 <AspectRatio>ratio(比率)属性に分数(に見える割り算)を渡すことで比率を設定します。計算結果が1より大きければ横長に、小さければ縦長に、ちょうど1なら正方形になります。(1)、(2)、(3)の例では、どれも4:3の比率で横幅だけを変えました。(4)の例では、横幅は親要素の幅いっぱいにしつつ、16:9の比率になるようにしました。すると、図9のように表示されます。

図9:AspectRatio
図9:AspectRatio

 Box側では特にサイズを指定していませんが、指定した比率と大きさになりました。動画ウィジェットを埋め込むときなどに重宝することになるでしょう。

その他のコンポーネント

 他にもコンポーネントはありますが、特定のCSSを扱うだけなので、簡単な紹介だけにさせてください。<Flex>display: flexが有効になっているだけで、ほとんど<Box>と同じ機能です。<Wrap>も同様で、こちらはさらにflex-wrapが有効になっています。flex-wrapspacingの組み合わせは便利なので、重宝することになるでしょう。

 <Grid>display: gridが有効になっている<Box>です。CSS Grid Layoutに準拠したグリッド表示ができます。<SimpleGrid><Grid>を少し簡便に扱えるようにしたものです。

 ここまで解説したコンポーネント群を利用すれば、大抵のレイアウトをすんなりと組むことができるでしょう。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:現場で役立つ! React向けライブラリ詳説

著者プロフィール

  • WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5