i-Vinci TechBlog
株式会社i-Vinciの技術ブログ

MUI 入門編 ~ Grid レイアウトでレスポンシブなフォトギャラリーをつくってみた ~

はじめましてー 夢は世界中のチーズを食べつくす、チーズ大好きエンジニアの Ten です!

画面の実装では、レスポンシブ対応が当たり前となりましたね。

ただ、一口にレスポンシブ対応って言っても、色んな実装パターンがあります。

今日はその中の Grid レイアウトを MUI を使ってフォトギャラリーをつくりながら簡単にご紹介してみたいと思います。

MUI(v5 ~ Material UI から名称変更)は、
Material Design(2014 年に Google が提唱したデザイン)を取り入れた UI ライブラリです。

※この記事で学べること

  • MUI Grid の考え方をざっくりわかるようになる
  • MUI Grid の基本の使い方
  • MUI Grid でレスポンシブ対応の実装

今回作るものはこちらから確認(いじいじ)できるので、始める前にチェックしてみてくださいね~


環境


1. 新規プロジェクト作成

npx create-react-app my-mui-pg-app --template typescript

インストールが完了したら、MUI のライブラリをインストールします。今回、レンダリングエンジンは styled-components にします。(既定は emotion)

yarn add @mui/material @mui/styled-engine-sc styled-components

公式の手順を従い、package.jsonに下記を追記します。

 {
+  "resolutions": {
+    "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
+  },
  },

※公式ドキュメントには下記の修正も記載されていますが、デフォルトの dependency が既に@mui/styled-engine-scとなっているため、今回は下記の修正をとばします。

 {
   "dependencies": {
-    "@mui/styled-engine": "latest"
+    "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
   },

さて、ここまでできたら、アプリを起動してみます。

yarn install
yarn start

おなじみの React ロゴが回っているので特に問題はなさそうですねー


2. 実装する

MUI の Grid レイアウトは、

  • Grid container
  • item

上記の 2 要素から構成されます。

デフォルトでは Grid container を 12 のカラムに分け、その中で item 要素を配置していきます。

import { Box, Grid, Paper } from '@mui/material';

import { photos } from '../data/photo';

const Component: React.FC = () => {
  return (
    <Box sx={{ width: '70%', margin: '20px auto' }}>
      <Grid container spacing={2}>
        {photos.map((photo, index) => (
          <Grid item xs={4} key={index}>
            <Paper
              component="img"
              src={photo}
              sx={{ width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }}
            ></Paper>
          </Grid>
        ))}
      </Grid>
    </Box>
  );
};

export default Component;

まず、item のxsProps を4に設定しました。12÷4=3のため、縦 3 列に並んでくれましたね。


レスポンシブ対応

続いて、画面幅の切替による並び方を変えてみたいと思います。

今回は、
MUI デフォルトで提供するブレイクポイントの値を使用します。

Props ブレイクポイント 画面幅 列の数
xs 0px ~899px* 1 列
md 900px 900~1199px 2 列
lg 1200px 1200px~ 3 列

注記* 設定されているブレイクポイントより大きいものがない場合、値がそのまま適用されます。そのため、今回の場合、xsの範囲はmdの「900px 未満」となります。

ソースは下記の通りに変更します。

import { Box, Grid, Paper } from '@mui/material';

import { photos } from '../data/photo';

const Component: React.FC = () => {
  return (
    <Box sx={{ width: '70%', margin: '20px auto' }}>
      <Grid container spacing={2}>
        {photos.map((photo, index) => (
-          <Grid item xs={4} key={index}>
+          <Grid item xs={12} md={6} lg={4} key={index}>
            <Paper
              component="img"
              src={photo}
              sx={{ width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }}
            ></Paper>
          </Grid>
        ))}
      </Grid>
    </Box>
  );
};

export default Component;

それぞれの item にxsmdlgの Props に値を渡してあげると、画面幅によって、列の数がレスポンシブに変わります。

1200px

900px

899px

おまけ

ここまでは、MUI デフォルトの 12 カラムで実装してきました。

さらに、ブレークポイントによって、異なるカラム数を指定することもできます。

例えば、画面幅が 1200px 以上のときだけ縦 9 列に並べてみたいときに、Grid container 要素に、columnsProps を追加します。

(今回使う写真は 9 枚なので、横一行の想定で縦 9 列としています)

ブレークポイントそれぞれに、計算に使用するカラム数をオブジェクトで渡してあげれば OK!

import { Box, Grid, Paper } from '@mui/material';

import { photos } from '../data/photo';

const Component: React.FC = () => {
  return (
    <Box sx={{ width: '70%', margin: '20px auto' }}>
-      <Grid container spacing={2}>
+      <Grid container spacing={2} columns={{ xs: 12, md: 12, lg: 9 }}>
        {photos.map((photo, index) => (
-          <Grid item xs={12} md={6} lg={4} key={index}>
+          <Grid item xs={12} md={6} lg={1} key={index}>
            <Paper
              component="img"
              src={photo}
              sx={{ width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }}
            ></Paper>
          </Grid>
        ))}
      </Grid>
    </Box>
  );
};

export default Component;

さて、画面はどんな感じなったのでしょうか?👀

1200px

うん、横一行にきれいに並んでくれましたね~


今回は MUI の Grid レイアウトを簡単なフォトギャラリーを作りながら紹介させていただきました。

いかがでしたでしょうか?

MUI Grid レイアウトには、またまた本記事で紹介きれないほど、便利なプロパティたちが満載です ✨✨

もっと知りたい!という方は、ぜひ公式ドキュメントをのぞいてみてくださいね~

最後までお読みいただき、ありがとうございました!