CSS 석조술을 위한 대안 제안

Chrome팀은 웹에서 석재 벽식 유형 레이아웃을 구현하고자 합니다. 하지만 최근 WebKit 게시물에서 제안한 대로 CSS 그리드 사양의 일부로 구현하는 것은 실수라고 생각합니다. 또한 WebKit 게시물은 아무도 제안하지 않은 masonry 버전에 대해 논쟁을 벌였습니다.

따라서 이 게시물에서는 Chrome에서 CSS 그리드 레이아웃 사양의 일부로 masonry를 구현하는 것에 관해 우려하는 이유를 설명하고 대체 제안서가 정확히 무엇을 사용 설정하는지 명확히 설명하는 것을 목표로 합니다. 간단히 말해,

  • Chrome팀은 개발자가 원하는 기능인 masonry를 차단 해제하기 위해 최선을 다하고 있습니다.
  • 그리드 사양에 마노리지를 추가하는 것은 마노리지를 그리드로 간주하는지 여부와는 다른 이유로 문제가 됩니다.
  • 그리드 사양 외부에서 masonry를 정의해도 masonry의 여러 트랙 크기 또는 정렬이나 간격과 같은 속성 또는 그리드 레이아웃에 사용되는 기타 기능을 사용할 수 있습니다.

masonry가 그리드의 일부여야 하나요?

Chrome팀은 masonry가 display: masonry (또는 더 나은 이름이 결정되면 다른 키워드)를 사용하여 정의되는 별도의 레이아웃 메서드여야 한다고 생각합니다. 이 게시물의 뒷부분에서 코드에서 어떻게 표시되는지 몇 가지 예를 확인할 수 있습니다.

격자 레이아웃 외부에서 격자 배열을 정의하는 것이 더 나은 이유는 두 가지가 있습니다. 레이아웃 성능 문제가 발생할 수 있고 격자 배열과 격자 모두 한 레이아웃 방법에서는 적합하지만 다른 방법에서는 적합하지 않은 기능이 있다는 사실입니다.

성능

그리드와 masonry는 브라우저가 크기와 배치를 처리하는 방식에 있어서는 정반대입니다. 그리드가 배치되면 모든 항목이 레이아웃 앞에 배치되며 브라우저는 각 트랙에 무엇이 있는지 정확하게 알 수 있습니다. 이렇게 하면 그리드에서 매우 유용한 복잡한 내재 크기 조정이 가능합니다. masonry를 사용하면 항목이 레이아웃된 대로 배치되며 브라우저는 각 트랙에 있는 항목 수를 알 수 없습니다. 이는 모든 고유 크기 트랙 또는 모든 고정 크기 트랙에 문제가 되는 것은 아니지만 고정 트랙과 고유 트랙을 혼합하는 경우에는 문제가 됩니다. 이 문제를 해결하려면 브라우저에서 측정값을 가져오기 위해 가능한 모든 방법으로 모든 항목을 배치하는 사전 레이아웃 단계를 실행해야 합니다. 그리드가 클 경우 레이아웃 성능 문제가 발생할 수 있습니다.

따라서 그리드에서 흔히 하는 것처럼 트랙 정의가 grid-template-columns: 200px auto 200px인 석재 레이아웃을 사용하면 문제가 발생하기 시작합니다. 하위 그리드를 추가하면 이러한 문제가 지수적으로 증가합니다.

대부분의 사용자는 이 문제가 발생하지 않는다는 주장이 있지만, 실제로 매우 큰 그리드를 사용하는 사용자가 있다는 것은 이미 잘 알고 있습니다. 대체 접근 방식이 있는 경우 사용 방식에 제한이 있는 항목을 출시하고 싶지 않습니다.

각 레이아웃 메서드에서 적절하지 않은 항목은 어떻게 처리하나요?

flexbox와 grid가 CSS의 일부가 되었을 때 개발자들은 이러한 요소가 일관되지 않게 작동한다고 느끼는 경우가 많았습니다. 이러한 불일치는 블록 레이아웃에 기반한 레이아웃 작동 방식에 대한 오래된 가정 때문입니다. 시간이 지남에 따라 개발자들은 서식 지정 컨텍스트를 이해하기 시작했습니다. 그리드 또는 플렉스 서식 컨텍스트로 전환하면 일부 동작이 다르게 작동합니다. 예를 들어 flexbox는 1차원적이므로 flexbox를 사용할 때는 일부 정렬 메서드만 사용할 수 있습니다.

격자를 masonry로 번들로 묶으면 형식 지정 컨텍스트와 형식 지정 컨텍스트별로 상자 정렬 사양에 정의된 정렬 속성 등의 사용 가능 여부 간의 명확한 연결이 끊어집니다.

앞서 설명한 성능 문제를 해결하기 위해 masonry에서 혼합된 내장 및 고정 트랙 정의를 불법으로 만들기로 결정한 경우 그리드 레이아웃의 매우 일반적인 패턴이 masonry에는 작동하지 않는다는 점에 유의해야 합니다.

교차 제약 조건은 없지만 그리드에서 유효하지 않은 상태로 유지해야 하므로 masonry에 적합한 패턴(예: grid-template-columns: repeat(auto-fill, max-content))도 있습니다. 다음은 다르게 동작할 것으로 예상되거나 유효한 값이 다른 속성의 목록입니다.

  • grid-template-areas: masonry에서는 masonry가 아닌 방향의 초기 행만 지정할 수 있습니다.
  • grid-template: 모든 차이를 고려해야 합니다.
  • 법적 값의 차이로 인해 grid-template-columnsgrid-template-rows의 크기 조정 값을 추적합니다.
  • grid-auto-flow는 masonry에 적용되지 않으며 masonry-auto-flow는 그리드에 적용되지 않습니다. 병합하면 사용 중인 레이아웃 메서드로 인해 잘못된 문제가 발생합니다.
  • 그리드에는 4개의 게재위치 속성 (grid-column-start 등)이 있고 masonry에는 2개만 있습니다.
  • 그리드는 justify-*align-* 속성 6개를 모두 사용할 수 있지만 Masonry는 Flexbox와 같은 하위 집합만 사용합니다.

또한 개발자가 grid-with-masonry 또는 grid-without-masonry에서 유효하지 않은 값을 사용하여 발생하는 모든 새 오류 사례에서 발생하는 상황을 지정해야 합니다. 예를 들어 grid-template-columns: masonry 또는 grid-template-rows: masonry를 사용하는 것은 유효하지만 둘 다 한 번에 사용하는 것은 유효하지 않습니다. 두 가지를 동시에 사용하면 어떻게 되나요? 모든 브라우저에서 동일한 작업을 실행할 수 있도록 이러한 세부정보를 지정해야 합니다.

지금과 미래에 사양 관점에서는 이 모든 것이 복잡해집니다. 모든 것이 masonry를 고려하고 masonry에서 작동하는지 여부를 확인해야 합니다. 개발자의 관점에서도 혼란스러울 수 있습니다. display: grid를 사용하고 있음에도 불구하고 masonry를 사용하기 때문에 일부 작업이 작동하지 않는다는 점을 기억해야 하는 이유는 무엇인가요?

대안 제안서

이미 언급했듯이 Chrome팀은 그리드 사양 외부에서 masonry를 정의하고자 합니다. 그렇다고 해서 열 크기가 동일한 매우 간단한 레이아웃 메서드로 제한되는 것은 아닙니다. WebKit 게시물의 모든 데모는 계속 가능합니다.

기존 석조 레이아웃

대부분의 사람들은 석조 레이아웃이라고 하면 크기가 같은 여러 열이 있는 레이아웃을 떠올립니다. 이는 다음 CSS를 사용하여 정의되며, 이 CSS는 상응하는 그리드 번들 버전보다 줄이 적은 코드가 필요합니다.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

크기가 동일한 트랙

다양한 열 너비에 그리드 유형 트랙 크기 사용

앞서 언급한 내장 및 고정 트랙 크기 혼합 문제 외에도 그리드에서 원하는 모든 트랙 크기를 사용할 수 있습니다. 좁은 열과 넓은 열이 반복되는 패턴인 WebKit 블로그 게시물의 예와 같은 경우입니다.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
  gap: 1rem;
}

넓고 좁은 크기의 트랙 패턴

masonry의 추가 트랙 크기

그리드는 2차원 레이아웃 방법이므로 그리드에서는 허용되지 않는 추가 트랙 크기 조정 옵션이 있습니다. 이는 masonry에서 유용하지만 그리드에서 작동하지 않으면 혼란스러울 수 있습니다.

max-content 크기의 트랙 자동 채우기

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, max-content);
  gap: 1rem;
}

auto 크기의 트랙을 자동으로 채우면 동일한 크기의 트랙이 생성되며 가장 큰 트랙을 수용할 수 있도록 자동으로 크기가 조절됩니다.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
  gap: 1rem;
}

자동 크기 조절된 트랙이 있는  masonry

콘텐츠가 열을 확장하도록 허용하고 석재 레이아웃에 항목 배치

별도의 석재 쌓기 사양에 열을 확장하는 콘텐츠를 포함하지 않을 이유가 없습니다. masonry-track 속성을 사용할 수 있습니다. masonry-trackmasonry-track-startmasonry-track-end의 약어로, masonry 레이아웃에서는 요소를 확장할 수 있는 크기가 하나뿐이기 때문입니다.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
}

.span-2 {
  masonry-track: span 2; /* spans two columns */
}

.placed {
  masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

배치된 항목과 확장된 항목이 있는  masonry

masonry 트랙을 채택한 하위 masonry 또는 하위 그리드

이는 별도의 석재 벽돌 쌓기 사양으로 지원할 수 있으며, 이때도 내장 및 고정 크기 트랙이 혼합된 것은 허용되지 않습니다. 정확한 모양은 정의해야 합니다. 이 방법이 작동하지 않을 이유가 없습니다.

결론

상호 운용성 있게 제공할 수 있는 사양을 완성하고자 합니다. 하지만 Google은 지금과 미래에 잘 작동하고 개발자가 신뢰할 수 있는 방식으로 이를 수행하고자 합니다. 설명된 성능 문제를 해결하는 유일한 방법은 두 번째 문제인 masonry에서 그리드의 일부가 잘못된 문제를 악화시키는 것입니다. 이는 좋은 해결책이 아닙니다. 특히 다른 항목을 명확하게 구분하면서 원하는 모든 그리드 기능을 사용할 수 있는 경우에는 더욱 그렇습니다.

의견이 있는 경우 Issue 9041에서 토론에 참여하세요.

이 게시물 검토 및 관련 논의를 위해 도움을 주신 브라무스, 탭 앳킨스-비트너, 우나 크라벳스, 이안 킬패트릭, 크리스 해럴슨님께 감사드립니다.