본문으로 건너뛰기
개발 머꼬
개발 노트CSS
hohyeon.dev17

카드마다 제목 길이가 달라 버튼 높이가 안 맞던 문제를 subgrid로 해결

  • #CSS
  • #Engineering Note
  • #Layout

문제 발생

카드 목록에서 제목이 한 줄인 카드와 두 줄인 카드가 섞이자 그 아래 요약과 버튼의 세로 위치가 카드마다 달라졌습니다. 카드 자체 높이는 그리드가 맞춰 주는데 안쪽 요소들은 제각각이었습니다.

.list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.card { display: grid; grid-template-rows: auto auto auto; }  /* 카드마다 독립 */

min-height로 제목 높이를 고정해 보기도 했지만, 언어나 폰트가 바뀌면 다시 어긋났습니다.

원인 분석

중첩된 그리드는 부모 그리드와 아무 관계가 없습니다. .card가 자체 행을 정의하는 순간, 그 행 높이는 그 카드 안의 콘텐츠로만 결정됩니다. 옆 카드가 어떤 높이를 쓰는지 알 방법이 없습니다.

subgrid는 이 단절을 없앱니다. grid-template-rows: subgrid를 주면 새 트랙을 만들지 않고 부모가 정의한 트랙을 그대로 사용합니다. 그러면 모든 카드의 제목이 부모의 같은 행에 놓이므로, 가장 긴 제목에 맞춰 그 행 전체가 늘어나고 나머지 카드도 같은 높이를 갖게 됩니다.

2023년 9월부터 모든 최신 브라우저에서 사용 가능(Baseline)합니다.

해결 방안

  1. 부모가 행을 정의하고, 카드는 그 행을 물려받습니다. 카드는 3개 행을 차지하고, 그 안에서 subgrid로 부모 트랙을 씁니다.
.list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: auto;      /* 제목 / 요약 / 액션 */
  gap: 20px;
}

.card {
  display: grid;
  grid-row: span 3;          /* 부모의 행 3개를 차지 */
  grid-template-rows: subgrid;
}
  1. 간격은 자동으로 물려받습니다. 부모의 gap이 그대로 적용되고, 필요하면 subgrid 쪽에서 덮어쓸 수 있습니다.
.card { row-gap: 8px; }      /* 부모의 20px 대신 */
  1. 줄 이름도 함께 넘어옵니다. 부모에서 [title-start]처럼 이름을 붙여 두면 손자 요소가 그 이름으로 배치될 수 있어, 숫자를 세지 않아도 됩니다.
  2. subgrid 축에는 암시적 트랙이 만들어지지 않습니다. 부모가 정의한 만큼만 존재하므로, 카드 안에 항목이 예상보다 많으면 마지막 트랙에 겹쳐 쌓입니다. 개수가 유동적인 축은 subgrid로 두지 말고 grid-auto-rows를 쓰는 편이 안전합니다.
  3. 한 축만 subgrid로 둘 수 있습니다. 열은 카드 자체 규칙을 쓰고 행만 부모를 따르는 식이 실무에서 가장 흔한 조합입니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.