レスポンシブコンポーネント設計のためのResizeObserver

要素サイズの変化を監視するためのResizeObserverサポートを検出。コンテナクエリポリフィル、レスポンシブコンポーネント、パフォーマンスパターンを解説。

DOM

詳細な説明

ResizeObserver検出

ResizeObserverは、要素のコンテンツまたはボーダーボックスサイズが変更された時に通知し、ビューポートではなくコンテナに適応する真にレスポンシブなコンポーネントを可能にします。

検出

const hasResizeObserver =
  typeof ResizeObserver !== 'undefined';

基本的な使い方

const observer = new ResizeObserver((entries) => {
  for (const entry of entries) {
    const { width, height } = entry.contentRect;
    console.log(\`要素リサイズ: \${width}x\${height}\`);

    // 要素サイズに基づくレスポンシブ動作
    if (width < 400) {
      entry.target.classList.add('compact');
    } else {
      entry.target.classList.remove('compact');
    }
  }
});

observer.observe(document.querySelector('.widget'));

ボックスサイズオプション

const observer = new ResizeObserver((entries) => {
  for (const entry of entries) {
    // コンテンツボックスサイズ(デフォルト)
    const contentBox = entry.contentBoxSize[0];

    // ボーダーボックスサイズ(パディング+ボーダー含む)
    const borderBox = entry.borderBoxSize[0];

    console.log(
      'Content:', contentBox.inlineSize, 'x', contentBox.blockSize,
      'Border:', borderBox.inlineSize, 'x', borderBox.blockSize
    );
  }
});

ResizeObserver vs 他のアプローチ

アプローチ トリガー 粒度
window.onresize ビューポートリサイズのみ グローバル
メディアクエリ ビューポート閾値 グローバル
ResizeObserver 任意の要素サイズ変更 要素ごと
コンテナクエリ (CSS) コンテナサイズ変更 CSSのみ

パフォーマンスのヒント

  1. 重い操作のデバウンス: ResizeObserverはウィンドウリサイズ中に急速に発火する可能性がある
  2. レイアウトスラッシングの回避: コールバック内でDOMの読み取りと書き込みをバッチ処理
  3. 完了後に切断: 監視が不要になったらobserver.disconnect()またはobserver.unobserve()を呼び出す
  4. 無限ループの回避: コールバック内で監視中の要素をリサイズしない

ユースケース

レスポンシブウィジェット、ダッシュボードパネル、再利用可能なコンポーネントライブラリの構築に不可欠です。チャートのリサイズ(D3、Chart.js)、エディタパネル、画像ギャラリー、JavaScriptでのコンテナクエリのような動作の実装に使用されます。

試してみる — Browser Feature Detector

フルツールを開く