@shinyaz

HTML <details> の open 属性はCSSメディアクエリで制御できない

約1分

ブログの目次を <details> で実装していて、デスクトップでは開いた状態、モバイルでは閉じた状態にしたかった。CSSの @mediaopen 属性を切り替えられると思ったが、open はHTML属性であってCSSプロパティではないため不可能だった。

React での解決策はシンプルで、useEffect でマウント時にウィンドウ幅を判定する。

TypeScript
const [isOpen, setIsOpen] = useState(true);
 
useEffect(() => {
  setIsOpen(window.innerWidth >= 768);
}, []);
 
return (
  <details
    open={isOpen}
    onToggle={(e) => setIsOpen(e.currentTarget.open)}
  >
    <summary>目次</summary>
    {/* ... */}
  </details>
);

onToggle でユーザーの手動開閉も追跡するのがポイント。SSR時は true(開いた状態)でレンダリングされ、クライアントでモバイルなら閉じるという流れになる。

共有する

田原 慎也

田原 慎也

ソリューションアーキテクト @ AWS

AWS ソリューションアーキテクトとして金融業界のお客様を中心に技術支援を行っています。クラウドアーキテクチャや AI/ML に関する学びをこのサイトで発信しています。このサイトの内容は個人の見解であり、所属企業の公式な意見や見解を代表するものではありません。