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

grid-row: 1 / -1이 첫 줄만 차지한 이유 — -1은 암시적 그리드가 아니라 명시적 그리드의 끝이다

  • #CSS
  • #Engineering Note
  • #Layout

문제 발생

목록 줄 오른쪽 끝에 시간을 세로 가운데로 두려고 했습니다. 왼쪽은 분류 줄과 제목 줄이 자동 배치로 두 행을 만들고, 시간은 두 행을 모두 차지하게 했습니다.

.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
}

.row time {
  grid-column: 2;
  grid-row: 1 / -1;
  align-self: center;
}

시간이 가운데가 아니라 첫 줄 높이 안에 갇혀 14px 위로 치우쳤습니다. 눈으로는 "살짝 위"로만 보여서 한참 지나쳤습니다.

원인 분석

-1은 그리드의 끝이 아닙니다. 명세와 MDN이 같은 문장으로 말합니다 — 음수 정수가 주어지면 명시적 그리드의 끝 가장자리에서 거꾸로 셉니다. 명시적 그리드는 grid-template-rows/grid-template-columns(또는 grid-template-areas)로 정의한 트랙입니다. 자동 배치가 만들어 낸 행은 암시적 그리드라 여기에 들어가지 않습니다.

이 코드에는 grid-template-rows가 없습니다. 명세는 이 경우도 정의해 둡니다 — 이 속성들이 명시적 트랙을 하나도 정의하지 않아도 명시적 그리드는 각 축에 선을 하나는 갖습니다. 행 축의 명시적 선은 1번 하나뿐이고, 끝에서 센 -1도 그 선입니다. grid-row: 1 / -1은 결국 1 / 1, 시작과 끝이 같은 선이라 한 칸짜리 배치가 되고 시간은 첫 행에만 놓입니다.

해결 방안

  1. 행을 명시적으로 선언합니다. 그러면 -1이 실제 마지막 선을 가리킵니다.
.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
}
  1. 행 수를 모른다면 span을 씁니다. grid-row: 1 / span 2는 명시적 그리드와 무관하게 두 행을 차지합니다. 다만 실제 행 수가 셋이면 마지막 행은 빠지니, 행 수가 고정된 줄에서 씁니다.

  2. 확인은 좌표로 합니다. 줄의 세로 가운데와 시간의 세로 가운데 y를 함께 재면 14px 차이가 숫자로 드러납니다. 눈으로 보면 정렬 오차와 구분되지 않습니다.

const row = el.getBoundingClientRect();
const time = el.querySelector("time").getBoundingClientRect();
console.log((row.top + row.bottom) / 2 - (time.top + time.bottom) / 2);
  1. grid-column: 1 / -1로 전체 폭을 차지하게 하는 코드도 같은 규칙입니다. 열은 보통 grid-template-columns로 선언하니 우연히 잘 동작할 뿐입니다. 열을 repeat(auto-fill, …)로 만들었다면 그것도 명시적 트랙이라 -1이 맞게 동작하지만, 암시적으로 늘어난 열은 세지 않습니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

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