メイソンリー・ギャラリー

高さがバラバラな写真を石積みのように詰めるメイソンリーグリッド。ホバーやフォーカスで各カードにキャプションが浮かび上がり、軽くズームして写真集のような余韻を演出します。

#css#gallery

ライブデモ

コード

HTML
<!-- メイソンリー・ギャラリー: 高さバラバラの石積みグリッド。hoverでキャプション表示+軽いズーム -->
<div class="mh" aria-label="作品ギャラリー(メイソンリーレイアウト)">
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1015/500/650" alt="断崖から見下ろすフィヨルド" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Fjord Cliff</span><span class="mh__s">断崖とフィヨルド</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1025/500/380" alt="毛布にくるまる犬" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Cozy Pup</span><span class="mh__s">毛布にくるまる犬</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1039/500/560" alt="緑の渓谷に流れる滝" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Valley Falls</span><span class="mh__s">渓谷に流れる滝</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1043/500/500" alt="渓谷の森と静かな水面" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Quiet Grove</span><span class="mh__s">静かな森と水面</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1035/500/700" alt="虹のかかる渓谷の滝" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Rainbow Falls</span><span class="mh__s">虹のかかる滝</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1074/500/360" alt="野生のライオンの横顔" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Lion Portrait</span><span class="mh__s">ライオンの横顔</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1015/500/420" alt="断崖の縁からの眺め" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Cliff Edge</span><span class="mh__s">断崖の縁</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1039/500/330" alt="滝つぼのクローズアップ" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Falls Detail</span><span class="mh__s">滝つぼのディテール</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1025/500/600" alt="毛布で丸くなる犬" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Blanket Nap</span><span class="mh__s">毛布でひと休み</span></figcaption>
  </figure>
</div>
CSS
* { box-sizing: border-box; }
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  background: #efe9df;
  font-family: "Segoe UI", system-ui, sans-serif;
  padding: clamp(14px, 3vw, 28px);
}

.mh {
  width: min(96vw, 780px);
  columns: 3 180px;
  column-gap: clamp(8px, 1.6vw, 14px);
}
@media (max-width: 620px) { .mh { columns: 2 140px; } }

.mh__item {
  position: relative;
  margin: 0 0 clamp(8px, 1.6vw, 14px);
  break-inside: avoid;
  border-radius: 12px;
  overflow: hidden;
  background: #d8d0c2;
  box-shadow: 0 8px 20px -12px rgba(60, 50, 35, .35);
  cursor: pointer;
}
.mh__item img {
  display: block;
  width: 100%;
  height: auto;
  transform: scale(1);
  filter: saturate(.95) brightness(.98);
  transition: transform .5s cubic-bezier(.2, .7, .2, 1), filter .4s ease;
}
.mh__item:hover img,
.mh__item:focus-visible img { transform: scale(1.08); filter: saturate(1.05) brightness(1); }

.mh__cap {
  position: absolute;
  inset: auto 0 0 0;
  margin: 0;
  padding: 26px 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  color: #fff;
  background: linear-gradient(to top, rgba(24, 18, 10, .82), rgba(24, 18, 10, 0));
  transform: translateY(8px);
  opacity: 0;
  transition: transform .35s ease, opacity .35s ease;
}
.mh__item:hover .mh__cap,
.mh__item:focus-visible .mh__cap { transform: translateY(0); opacity: 1; }

.mh__t { font-size: 12.5px; font-weight: 700; letter-spacing: .04em; }
.mh__s { font-size: 10.5px; color: rgba(255, 255, 255, .82); }

.mh__item:focus-visible {
  outline: 2px solid #8a6a3d;
  outline-offset: 3px;
}
JavaScript
// このデモは CSS のみで完結(hover/focus でキャプション表示とズーム)。JSは不要。

🤖 AIエージェント用プロンプト

このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「メイソンリー・ギャラリー」の効果を追加してください。

# 追加してほしい効果
メイソンリー・ギャラリー(画像 & ギャラリー)
高さがバラバラな写真を石積みのように詰めるメイソンリーグリッド。ホバーやフォーカスで各カードにキャプションが浮かび上がり、軽くズームして写真集のような余韻を演出します。

# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】

# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- メイソンリー・ギャラリー: 高さバラバラの石積みグリッド。hoverでキャプション表示+軽いズーム -->
<div class="mh" aria-label="作品ギャラリー(メイソンリーレイアウト)">
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1015/500/650" alt="断崖から見下ろすフィヨルド" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Fjord Cliff</span><span class="mh__s">断崖とフィヨルド</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1025/500/380" alt="毛布にくるまる犬" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Cozy Pup</span><span class="mh__s">毛布にくるまる犬</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1039/500/560" alt="緑の渓谷に流れる滝" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Valley Falls</span><span class="mh__s">渓谷に流れる滝</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1043/500/500" alt="渓谷の森と静かな水面" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Quiet Grove</span><span class="mh__s">静かな森と水面</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1035/500/700" alt="虹のかかる渓谷の滝" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Rainbow Falls</span><span class="mh__s">虹のかかる滝</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1074/500/360" alt="野生のライオンの横顔" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Lion Portrait</span><span class="mh__s">ライオンの横顔</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1015/500/420" alt="断崖の縁からの眺め" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Cliff Edge</span><span class="mh__s">断崖の縁</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1039/500/330" alt="滝つぼのクローズアップ" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Falls Detail</span><span class="mh__s">滝つぼのディテール</span></figcaption>
  </figure>
  <figure class="mh__item" tabindex="0">
    <img src="https://picsum.photos/id/1025/500/600" alt="毛布で丸くなる犬" loading="lazy">
    <figcaption class="mh__cap"><span class="mh__t">Blanket Nap</span><span class="mh__s">毛布でひと休み</span></figcaption>
  </figure>
</div>

【CSS】
* { box-sizing: border-box; }
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  background: #efe9df;
  font-family: "Segoe UI", system-ui, sans-serif;
  padding: clamp(14px, 3vw, 28px);
}

.mh {
  width: min(96vw, 780px);
  columns: 3 180px;
  column-gap: clamp(8px, 1.6vw, 14px);
}
@media (max-width: 620px) { .mh { columns: 2 140px; } }

.mh__item {
  position: relative;
  margin: 0 0 clamp(8px, 1.6vw, 14px);
  break-inside: avoid;
  border-radius: 12px;
  overflow: hidden;
  background: #d8d0c2;
  box-shadow: 0 8px 20px -12px rgba(60, 50, 35, .35);
  cursor: pointer;
}
.mh__item img {
  display: block;
  width: 100%;
  height: auto;
  transform: scale(1);
  filter: saturate(.95) brightness(.98);
  transition: transform .5s cubic-bezier(.2, .7, .2, 1), filter .4s ease;
}
.mh__item:hover img,
.mh__item:focus-visible img { transform: scale(1.08); filter: saturate(1.05) brightness(1); }

.mh__cap {
  position: absolute;
  inset: auto 0 0 0;
  margin: 0;
  padding: 26px 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  color: #fff;
  background: linear-gradient(to top, rgba(24, 18, 10, .82), rgba(24, 18, 10, 0));
  transform: translateY(8px);
  opacity: 0;
  transition: transform .35s ease, opacity .35s ease;
}
.mh__item:hover .mh__cap,
.mh__item:focus-visible .mh__cap { transform: translateY(0); opacity: 1; }

.mh__t { font-size: 12.5px; font-weight: 700; letter-spacing: .04em; }
.mh__s { font-size: 10.5px; color: rgba(255, 255, 255, .82); }

.mh__item:focus-visible {
  outline: 2px solid #8a6a3d;
  outline-offset: 3px;
}

【JavaScript】
// このデモは CSS のみで完結(hover/focus でキャプション表示とズーム)。JSは不要。

# 外部ライブラリ
なし(追加ライブラリ不要)

# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。