🌟

Tailwind CSSでz-indexの値をマジックナンバーにしないための小ワザ

2024/04/25に公開

背景

小ネタです。

先日以下のようなバグ改修タスクでソースレビューを担当しました。

「全画面モーダルを実装したら、グローバルメニューより上に表示されてしまった。なのでz-indexを修正しました!」

我々が開発しているマナリンクでは、画面右上の自分のアイコンをクリックするとメニューが表示されます。

ところが全画面モーダルを実装したら、モーダルがメニューよりも上に表示されてしまい、モーダル表示中にメニューを操作できなくなってしまったとのこと。

最初のPull Requestの時点では、以下のような差分になっていました。

     <div
-      className={'z-50 w-full border-b border-b-gray-shadow}
+      className={'z-10 w-full border-b border-b-gray-shadow}
     >

これをレビューするときの僕の気持ちとしては、このソースを見ただけでは「そりゃあ、動くでしょうね」でOKできるのですが、せっかくなら再発防止策を考えたいところだと思いました。

z-indexはマジックナンバーになりがちです。今自分が見ているz-indexの値が、なぜその値になっているのかがわからなくなるので、いずれ値を変更することが怖くなってしまいます。

本件の再発防止策として、tailwind.config.jsにz-indexのカスタムクラスを追加することで、値ではなく目的でクラスを当てられるようにしました。

tailwind.config.jsにz-indexの拡張設定を追加

以下のように、tailwind.config.jsにz-index用の設定を追加します。

theme: {  
  extend: {  
    zIndex: {  
      sideDrawer: '10',  
      globalMenu: '100',  
      modal: '50',  
    },  
  },  
},
  • 画面の左右から出てくるようなドロワーは10
  • グローバルメニューはどんなときもユーザーが開いて欲しいときに開くべきなので100
  • モーダルはドロワーが開いていてもその上に出てほしいし、グローバルメニューはさらに上に出てきて操作ができてほしいので間の50

簡易的ではありますが、このようにUIの種別ごとにクラス名を作成することで、値を暗記することなく、用途に応じて適切なクラス名を選ぶだけで問題ない挙動が実現できます。

import { Drawer as MuiDrawer } from '@mui/material';

return (  
  <MuiDrawer  
    anchor={anchor}  
    open={isOpen}  
    onClose={onClose}  
    variant={variant}  
    hideBackdrop={hideBackdrop}  
    transitionDuration={transitionDuration}  
    classes={{  
      paper: '!z-drawer',  
    }}  
  >  
    {children}  
  </MuiDrawer>  
);
import { Menu } from '@headlessui/react';

<Menu.Items  
  className={  
    'absolute right-0 z-globalMenu bg-white py-1 shadow-lg focus:outline-none'  
  }  
>  
  <Menu.Item>
      <TextLink
          href={'https://example.com'}
          className={'block'}  
    >  
      FAQ  
    </TextLink>  
  </Menu.Item>

本件に限らず、Tailwind CSSを使っている場合は、マジックナンバーにならないように設定を随時増やしていくのがいいと思っています。

簡単ではありますが、デザインシステムがガッチガチに固まっていない環境でTailwind CSSを使っていたり、ある程度決まっていてもz-indexは設定から漏れているんだよね〜という環境でのちょっとしたTipsとしてご活用いただけますと幸いです!

参考文献

マナリンク Tech Blog

Discussion