카드마다 제목 길이가 달라 버튼 높이가 안 맞던 문제를 subgrid로 해결
문제 발생
카드 목록에서 제목이 한 줄인 카드와 두 줄인 카드가 섞이자 그 아래 요약과 버튼의 세로 위치가 카드마다 달라졌습니다. 카드 자체 높이는 그리드가 맞춰 주는데 안쪽 요소들은 제각각이었습니다.
.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)합니다.
해결 방안
- 부모가 행을 정의하고, 카드는 그 행을 물려받습니다. 카드는 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;
}- 간격은 자동으로 물려받습니다. 부모의
gap이 그대로 적용되고, 필요하면 subgrid 쪽에서 덮어쓸 수 있습니다.
.card { row-gap: 8px; } /* 부모의 20px 대신 */- 줄 이름도 함께 넘어옵니다. 부모에서
[title-start]처럼 이름을 붙여 두면 손자 요소가 그 이름으로 배치될 수 있어, 숫자를 세지 않아도 됩니다. - subgrid 축에는 암시적 트랙이 만들어지지 않습니다. 부모가 정의한 만큼만 존재하므로, 카드 안에 항목이 예상보다 많으면 마지막 트랙에 겹쳐 쌓입니다. 개수가 유동적인 축은 subgrid로 두지 말고
grid-auto-rows를 쓰는 편이 안전합니다. - 한 축만 subgrid로 둘 수 있습니다. 열은 카드 자체 규칙을 쓰고 행만 부모를 따르는 식이 실무에서 가장 흔한 조합입니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.