Skip to content

Gallery grid

For showing many photos at once and letting someone pick one to open large.

Media

Live preview

Source

<ul class="dc-gallery" aria-label="3공구 9월 12일 사진 6장">
  <li class="dc-gallery__cell"><button type="button" class="dc-gallery__item"><span class="dc-sr">크게 보기 — 터파기 전경</span></button></li>
  <li class="dc-gallery__cell"><button type="button" class="dc-gallery__item"><span class="dc-sr">크게 보기 — 철근 배근</span></button></li>
  <li class="dc-gallery__cell"><button type="button" class="dc-gallery__item"><span class="dc-sr">크게 보기 — 거푸집 설치</span></button></li>
  <li class="dc-gallery__cell"><button type="button" class="dc-gallery__item"><span class="dc-sr">크게 보기 — 타설 전 점검</span></button></li>
  <li class="dc-gallery__cell"><button type="button" class="dc-gallery__item"><span class="dc-sr">크게 보기 — 양생 상태</span></button></li>
  <li class="dc-gallery__cell"><button type="button" class="dc-gallery__item"><span class="dc-sr">크게 보기 — 마감 확인</span></button></li>
</ul>
.dc-gallery {
  /* 가림막은 밝은 모드에서도 어둡다. --dc-text-on 은 다크 모드에서 검어지므로 여기엔 쓸 수 없다 */
  --dc-on-media: white;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: var(--dc-3);
  margin: 0; padding: 0; list-style: none;
  font-family: var(--dc-font);
}
.dc-gallery__cell { min-width: 0; }
.dc-gallery__item {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  min-height: 44px;
  padding: 0;
  border: 1px solid var(--dc-line);
  border-radius: var(--dc-r-sm);
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--dc-brand) 28%, var(--dc-sunken)),
    var(--dc-sunken));
  cursor: pointer;
  overflow: hidden;
  transition: transform var(--dc-fast), box-shadow var(--dc-fast);
}
.dc-gallery__cell:nth-child(3n + 2) .dc-gallery__item {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--dc-info) 28%, var(--dc-sunken)),
    var(--dc-sunken));
}
.dc-gallery__cell:nth-child(3n) .dc-gallery__item {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--dc-ok) 26%, var(--dc-sunken)),
    var(--dc-sunken));
}
.dc-gallery__item:hover { transform: translateY(-2px); box-shadow: var(--dc-sh-2); }
.dc-gallery__more {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background: color-mix(in srgb, black 28%, var(--dc-overlay));
  color: var(--dc-on-media);
  font-size: 15px; font-weight: 700;
}
.dc-gallery__cell--wide { grid-column: span 2; grid-row: span 2; }
.dc-gallery__cell--wide .dc-gallery__item { aspect-ratio: auto; height: 100%; }
.dc-gallery__fig { margin: 0; display: flex; flex-direction: column; gap: var(--dc-2); }
.dc-gallery__cap { font-size: 12px; line-height: 1.4; color: var(--dc-text-sub); }

How to use it

  • Set a minimum tile width instead of a column count, so the grid reflows on its own
  • Each tile is a thing you press — make it a button and name the photo it opens
  • Past ten or so, fold the remainder into a count on the last tile

Watch out for

  • Square crops eat faces and on-site lettering — check what the crop removes
  • Gaps under 4px erase the seams and the grid reads as one picture

Next