🥷

Chakra UIでモーダルの中にTableContainerを入れた場合にスマホ表示でモーダルの左右にマージンを持たせる方法

2022/09/30に公開1

小ネタというかメモです。

前提

Chakra UIのモーダルはデフォルトの挙動だとスマホで表示したときに画面幅いっぱいのサイズで表示されます。

<Modal isOpen={isOpen} onClose={onClose} size="6xl">
  <ModalOverlay />
  <ModalContent>
    <ModalHeader>Test</ModalHeader>
    <ModalCloseButton />
    <ModalBody pb="1.5rem">
      test
    </ModalBody>
  </ModalContent>
</Modal>
PC スマホ

限られた表示領域を最大限活用したいという意図のように思えますが、個人的には見た目がちょっと好みでないので、基本的に左右に 1rem ずつとか適当にマージンをつけるようにしています。

  <Modal isOpen={isOpen} onClose={onClose} size="6xl">
    <ModalOverlay />
-   <ModalContent>
+   <ModalContent mx="1rem">
      <ModalHeader>Test</ModalHeader>
      <ModalCloseButton />
      <ModalBody pb="1.5rem">
        test
      </ModalBody>
    </ModalContent>
  </Modal>

問題

しかし、このようにマージンを設定していても、ModalBody の中で TableContainer を使うと意図どおりの表示になりません。

<Modal isOpen={isOpen} onClose={onClose} size="6xl">
  <ModalOverlay />
  <ModalContent mx="1rem">
    <ModalHeader>Test</ModalHeader>
    <ModalCloseButton />
    <ModalBody pb="1.5rem">
      <TableContainer>
        <Table>
          <Thead>
            <Tr>
              <Th>To convert</Th>
              <Th>into</Th>
              <Th isNumeric>multiply by</Th>
            </Tr>
          </Thead>
          <Tbody>
            <Tr>
              <Td>inches</Td>
              <Td>millimetres (mm)</Td>
              <Td isNumeric>25.4</Td>
            </Tr>
            <Tr>
              <Td>feet</Td>
              <Td>centimetres (cm)</Td>
              <Td isNumeric>30.48</Td>
            </Tr>
            <Tr>
              <Td>yards</Td>
              <Td>metres (m)</Td>
              <Td isNumeric>0.91444</Td>
            </Tr>
          </Tbody>
        </Table>
      </TableContainer>
    </ModalBody>
  </ModalContent>
</Modal>

このようにモーダルの幅が画面幅いっぱいになってしまった上に、

右に 1rem 分の余分な余白ができてしまい、全体が横スクロールできる状態になってしまいました。

解決策

強引ですが、以下のようにすることで解決できます。

  <Modal isOpen={isOpen} onClose={onClose} size="6xl">
    <ModalOverlay />
    <ModalContent mx="1rem">
      <ModalHeader>Test</ModalHeader>
      <ModalCloseButton />
      <ModalBody pb="1.5rem">
-       <TableContainer>
+       <TableContainer w="calc(100vw - 42px - 2rem)"> {/* 42px: ModalBodyの左右のpaddingが21pxずつだったのでハードコード */}
          <Table>
            {/* 略 */}
          </Table>
        </TableContainer>
      </ModalBody>
    </ModalContent>
  </Modal>

あるいは、ModalBody のデフォルトの左右の余白をなくしてしまってもよいでしょう。(僕はこっち派です)

  <Modal isOpen={isOpen} onClose={onClose} size="6xl">
    <ModalOverlay />
    <ModalContent mx="1rem">
      <ModalHeader>Test</ModalHeader>
      <ModalCloseButton />
-     <ModalBody pb="1.5rem">
+     <ModalBody px={0} pb="1.5rem">
-       <TableContainer>
+       <TableContainer w="calc(100vw - 2rem)">
          <Table>
            {/* 略 */}
          </Table>
        </TableContainer>
      </ModalBody>
    </ModalContent>
  </Modal>

GitHubで編集を提案

Discussion

とーやとーや
<ModalContent maxW="95vw">

でもやりたいこと実現できるかもしれません!
参考までに。