• #CSS
  • #レスポンシブ
  • #Vue
  • #Miller Columns
  • #iPad
  • #eurekapu
開発eurekapu-nuxt4メモ

MillerViewerのレスポンシブ対応修正

モバイルで画像が消えた。ブラウザのDevToolsで要素を追い詰めると、MillerViewer側の:deep()が犯人だった。デスクトップ用のスタイルがモバイルのTheaterViewerまで貫通し、.theater-mobiledisplay: none !importantで叩き潰していた。ここから始まって、iPad Proのレイアウト調整、revertされたPR #1の再実装まで一気に片付けた。

モバイルで画像が非表示になるバグ

症状

モバイル表示でTheaterViewerの画像が完全に消えていた。テキスト部分だけが表示され、肝心のスライド画像が見えない。

原因

MillerViewer.vueの:deep()によるCSSオーバーライドが、スコープを超えてTheaterViewerのモバイルレイアウトに影響していた。

/* MillerViewer.vue 内の問題のスタイル */
:deep(.theater-mobile) {
  display: none !important;
}

:deep()はVueのscoped CSSを子コンポーネントに貫通させる。MillerViewerがデスクトップ表示で.theater-mobileを非表示にしたかっただけなのに、モバイル時にもこのルールが生きていて、TheaterViewerが自前で切り替えるモバイルレイアウトごと消してしまっていた。

修正

:deep()のオーバーライドを.millerクラス(デスクトップモード時のみ付与されるクラス)にスコープした。モバイルではMillerViewerが非表示になりTheaterViewerのデフォルトスタイルがそのまま使われるので、:deep()が干渉しなくなる。

/* 修正後: .miller内でのみオーバーライドが効く */
.miller :deep(.theater-mobile) {
  display: none !important;
}

修正は1行だが、影響範囲の特定に時間がかかった。DevToolsのComputed Stylesでdisplay: noneの出所を辿り、MillerViewer.vueのscoped styleに行き着くまで何層ものコンポーネントを掘った。

PR #1 のrevert問題

修正を進める中で、以前PR #1で入れたはずの変更がrevertされていることに気づいた。gitログを遡って確認すると、別の作業ブランチのマージ時に巻き戻っていた。

手動で差分を確認し、PR #1の変更内容を再実装した。

iPad Pro フォーカスモード時の2カラムレイアウト

課題

iPad Pro (1366px) でフォーカスモードを使うと、テキスト(caption)と画像が縦に積まれてしまい、画面の横幅を活かせていなかった。1366pxあれば左右に並べる余裕がある。

実装

テキストを左、画像を右に配置する2カラムレイアウトを実装した。

ブレークポイントの調整:

当初はmax-width: 1200pxでモバイルレイアウトに切り替えていたが、iPad Proの1366pxがこの閾値を超えてデスクトップ扱いになるのに、フォーカスモード時のレイアウトは考慮されていなかった。ブレークポイントをmax-width: 1400pxに引き上げ、iPad Proの画面幅をカバーした。

@media (min-width: 1400px) {
  /* デスクトップ: 2カラム(テキスト左・画像右) */
}
@media (max-width: 1399px) {
  /* タブレット以下: 縦積み */
}

テキストの垂直中央配置:

2カラムにしたとき、captionが上端に張り付いていた。画像の高さに対してテキストが少ないので、上に寄ると下に空白が目立つ。

/* Before: 上端に張り付く */
.caption {
  align-self: start;
}
/* After: 画像の中央に揃う */
.caption {
  align-self: center;
}

align-self: centerに変えたら、テキストが画像の垂直中央に揃い、左右のバランスが取れた。

学んだこと

  • :deep()のスコープ漏れは目視で気づきにくい。デスクトップでは正常に見えるのにモバイルで壊れるパターンは、:deep()が画面幅に関係なく全てのDOM階層に適用されるために起きる。親コンポーネントのレイアウトモードでスコープを絞る癖をつけたい
  • ブレークポイントを決めるとき、「何pxか」より「どのデバイスの、どの使い方をカバーするか」から逆算すると、数値の根拠が明確になる。1400pxという数字はiPad Proの1366pxにマージンを足した結果であって、キリのいい数字を選んだわけではない
  • PRがrevertされていないか、マージ後に一度diffを確認する手順を入れた方がいい。今回は偶然気づいたが、気づかなければモバイルのバグが残り続けていた