생성된 콘텐츠 및 CSS 그리드 레이아웃으로 빈 셀 스타일 지정
게시 됨: 2022-03-10일반적인 그리드 레이아웃 문제는 레이아웃 방법을 처음 접하는 사람이 콘텐츠를 포함하지 않는 그리드 셀의 스타일을 지정하는 방법을 궁금해하는 경우입니다. 현재 수준 1 사양에서는 빈 그리드 셀 또는 그리드 영역을 대상으로 지정하고 스타일을 적용할 방법이 없기 때문에 불가능합니다. 즉, 스타일을 적용하려면 요소를 삽입해야 합니다.
이 기사에서는 CSS 생성 콘텐츠를 사용하여 중복된 빈 요소를 추가하지 않고 빈 셀의 스타일을 지정하는 방법을 살펴보고 이 기술이 적합한 몇 가지 사용 사례를 보여줍니다.
BFC 자세히 살펴보기
CSS로 레이아웃을 만든 적이 있다면 BFC가 무엇인지 알 것입니다. 작동 이유와 생성 방법을 이해하는 것은 유용하며 CSS에서 레이아웃이 작동하는 방식을 이해하는 데 도움이 됩니다. 관련 기사 읽기 →
왜 우리는 이미 빈 영역을 스타일링할 수 없습니까?
그리드 사양의 시작 단락은 다음과 같이 말합니다.
“이 CSS 모듈은 사용자 인터페이스 디자인에 최적화된 2차원 그리드 기반 레이아웃 시스템을 정의합니다. 그리드 레이아웃 모델에서 그리드 컨테이너의 자식은 미리 정의된 유연하거나 고정된 크기의 레이아웃 그리드에서 임의의 슬롯에 배치할 수 있습니다."
여기에서 핵심 문구는 "그리드 컨테이너의 자식"입니다. 사양은 자식 항목을 배치할 수 있는 부모 요소에 대한 그리드 생성을 정의합니다. 다중 열 레이아웃에 있는 column-rule
속성과 같은 것을 구현하는 것까지 하지 않고 해당 그리드의 스타일을 정의하지 않습니다. 그리드 자체가 아닌 자식 항목의 스타일을 지정하므로 해당 스타일을 적용할 요소가 필요합니다.
중복 요소를 스타일링 후크로 사용
스타일에 무언가를 삽입하는 한 가지 방법은 문서에 중복 요소(예: 범위 또는 div)를 삽입하는 것입니다. 개발자는 부동 소수점을 사용하여 그리드 레이아웃을 달성하기 위해 몇 년 동안 추가 중복 "행 래퍼"를 추가했음에도 불구하고 이 아이디어를 싫어하는 경향이 있습니다. 아마도 분명히 비어 있는 요소가 래퍼 요소의 숨겨진 중복성보다 더 불쾌할 것입니다!
완전히 비어 있는 요소는 그리드 항목이 되며 이 예제에서 보여주듯이 콘텐츠가 포함된 요소처럼 배경과 테두리를 추가할 수 있습니다.
Eric Meyer는 A List Apart 기사 Faux Grid Tracks에서 의미론적 의미를 부여하지 않고 짧고 후크로 마크업에서 상당히 분명하기 때문에 b
요소를 중복 선택 요소로 사용하는 것을 옹호합니다.
몇 개의 div
또는 b
요소를 추가로 삽입하는 것은 좋은 마크업에 대한 가장 큰 범죄가 아닐 수 있으므로 필요한 경우 해당 접근 방식을 선택하는 데 잠을 자지 않을 것입니다. 웹 개발에는 더 나은 솔루션이 고안될 때까지 작업을 완료하기 위해 가장 덜 최적화된 접근 방식을 선택하는 경우가 많습니다. 그러나 가능하면 스타일시트에 안전하게 스타일을 유지하는 것을 선호합니다. 추가로 필요한 마크업에 대해 걱정할 필요 없이 스타일을 더 쉽게 재사용할 수 있습니다. 이러한 이유로 저는 생성된 콘텐츠를 찾는 경향이 있습니다. CSS로 책 서식 지정을 수행한 작업에서 매우 친숙한 것인데, 이 기능으로 작업하는 데 대부분의 시간을 할애합니다.
생성된 콘텐츠를 스타일링 훅으로 사용하기
CSS 생성 콘텐츠는 content
속성과 함께 ::before
및 ::after
CSS 의사 클래스를 사용하여 일종의 콘텐츠를 문서에 삽입합니다. 콘텐츠 를 삽입한다는 아이디어는 이것이 텍스트를 삽입하기 위한 것이라고 생각하게 할 수 있으며, 이것이 가능하지만 우리의 목적을 위해 빈 요소 를 그리드 컨테이너의 직계 자식으로 삽입하는 데 관심이 있습니다. 요소를 삽입하면 스타일을 지정할 수 있습니다.
아래 예에는 내 그리드 컨테이너가 될 포함 요소가 있고 내부에 다른 요소가 중첩되어 있습니다. 이 단일 직계 자식은 그리드 항목이 됩니다. 컨테이너에 3열, 3행 그리드를 정의한 다음 그리드 라인을 사용하여 단일 항목을 배치하여 중간 그리드 셀에 배치했습니다.
<div class="grid"> <div class="item"></div> </div>
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-gap: 10px; } .grid > * { border: 2px solid rgb(137,153,175); } .item { grid-column: 2; grid-row: 2; }
Firefox Grid Inspector를 사용하여 그리드 선을 오버레이하는 이 예를 보면 그리드의 다른 빈 셀이 어떻게 존재하는지 알 수 있지만 배경이나 테두리를 추가하려면 추가 자식을 추가해야 합니다. 집단. 이것이 바로 생성된 콘텐츠가 가능하게 하는 것입니다.
내 CSS에서 빈 문자열인 ::before
및 ::after
Grid Container에 추가합니다. 이것들은 즉시 그리드 아이템이 되고 컨테이너를 채우기 위해 늘어납니다. 그런 다음 상자에 필요한 스타일을 추가합니다. 이 경우에는 배경색을 추가하고 일반 그리드 항목처럼 배치합니다.
.grid::before { content: ""; background-color: rgb(214,232,182); grid-column: 3; grid-row: 1; } .grid::after { content: ""; background-color: rgb(214,232,182); grid-column: 1; grid-row: 3; }
이 문서에는 여전히 하나의 자식 요소만 있고 중복된 스타일 요소는 CSS에 포함되어 있습니다. 이는 스타일 지정 목적으로만 존재하기 때문에 완벽하게 합당해 보입니다.
생성된 콘텐츠 접근 방식의 한계
이 접근 방식의 명백한 문제는 오른쪽 상단 및 왼쪽 하단 그리드 셀에도 스타일을 지정하려는 경우 명확해집니다. 생성된 콘텐츠는 컨테이너의 상단과 하단에 하나씩만 적용할 수 있으며, 여러 ::before
및 ::after
의사 요소는 허용되지 않습니다. CSS 그리드 체커보드를 직접 만들고 싶다면 이 방법이 작동하지 않을 것입니다! 빈 셀 스타일을 많이 수행해야 하는 경우 가까운 장래에 위에서 설명한 "필러 B" 접근 방식이 최선의 방법일 것입니다.
생성된 콘텐츠 방식은 프로젝트에서 작업하는 미래의 개발자를 혼란스럽게 할 수도 있습니다. 컨테이너를 대상으로 하고 있으므로 해당 클래스를 다른 곳에서 재사용하면 생성된 콘텐츠를 가져오므로 원하는 경우 유용합니다. 다음 예에서 우리는 제목의 양쪽에 장식 라인을 추가했습니다. h1
의 모든 인스턴스에 이러한 라인이 있는 것이 합리적일 것입니다. 그러나 이런 일이 일어날 것이라는 사실을 알지 못한다면 매우 혼란스러울 것입니다! 컨테이너 규칙 위의 주석 줄이 여기에서 도움이 될 것입니다. 저는 요즘 패턴 라이브러리에서 작업하는 경향이 있습니다. 패턴 라이브러리는 이러한 구성 요소를 한 곳에서 깔끔하게 지원하므로 클래스가 요소에 적용될 때 어떤 일이 발생하는지 더 명확하게 만듭니다.
멋진 제목
내가 가장 좋아하는 생성 콘텐츠 트릭 중 하나는 제목 스타일을 지정하는 것입니다. 과거에는 달성하기 위해 추가 래퍼와 절대 위치 트랙이 필요한 제목 스타일을 뒤로 밀어야 했습니다. 콘텐츠가 CMS에서 가져온 경우 이러한 중복 래퍼를 추가하는 것이 불가능한 경우가 많습니다.
그리드 및 생성된 콘텐츠를 사용하면 추가 마크업을 추가하지 않고도 제목의 양쪽에 줄을 추가할 수 있습니다. 선은 사용 가능한 공간에 따라 늘어나고 줄어들며 브라우저에서 Grid를 사용할 수 없는 경우 일반 중앙 헤더로 우아하게 대체됩니다.
우리의 마크업은 단순한 h1
입니다.
<h1>My heading</h1>
h1
에 대한 규칙에서 3개의 기둥 그리드를 만듭니다. grid-template-columns
값은 1fr
의 트랙을 제공하고 auto
의 트랙과 1fr
의 최종 트랙을 제공합니다. 두 개의 1fr
트랙은 제목이 auto
크기 트랙 안에 앉는 데 필요한 공간을 차지한 후 남은 사용 가능한 공간을 공유합니다.
그리드가 없는 브라우저에서 제목이 입력되는 순서보다 center
값으로 text-align
속성을 추가했습니다.
h1 { text-align: center; display: grid; grid-template-columns: 1fr auto 1fr; grid-gap: 20px; }
이제 생성된 콘텐츠를 추가하여 제목 텍스트 앞뒤에 줄을 추가합니다. 기능 쿼리에서 이러한 규칙을 래핑하여 그리드 레이아웃이 없는 브라우저에서 이상하게 생성된 콘텐츠를 얻지 못합니다.
라인 자체는 생성된 항목의 테두리입니다.
@supports (display: grid) { h1:before, h1:after { content: ""; align-self: center; border-top: 1px solid #999; } }
그게 다야! 동일한 기술을 사용하여 스타일을 추가하거나 요소의 위 또는 아래에 있는 요소의 양쪽에 아이콘을 추가할 수 있습니다. 항목을 별도의 트랙에 배치하면 항목이 제목 텍스트와 겹치게 될 가능성이 없다는 것을 알 수 있습니다. 이는 절대 위치 지정을 사용하여 이러한 종류의 작업을 수행하려고 할 때 문제가 되는 경향이 있습니다. 또한 그리드에서 항목을 서로 정렬할 수 있는 정확한 방법의 이점이 있습니다.
이것은 아직 그리드를 사용하여 주요 재설계를 시작할 준비가 되지 않은 경우에도 활용할 수 있는 그리드 레이아웃을 사용하여 개선할 수 있는 좋은 예입니다. 그것은 간단한 제목으로 매우 멋지게 되돌아가고, 지원하는 브라우저를 가진 사람들은 추가 터치를 얻고, 모든 사람은 콘텐츠를 얻습니다. Eric Meyer는 생성된 콘텐츠를 사용하여 블록 인용 요소에 쉽게 스타일 지정 및 위치 지정이 가능한 인용문을 추가하는 유사한 접근 방식을 취했습니다.
이러한 작은 기능으로 인해 그리드 레이아웃을 사용할 생각을 하지 않는 경우가 많습니다. 내 디자인을 구현하는 방법을 알아내기 시작하면서 선택해야 할 레이아웃 방법이라는 것을 깨달았습니다. 그렇기 때문에 사람들이 그리드를 구성 요소에 대한 페이지 레이아웃으로 생각하지 말라고 권장합니다. 그렇게 하면 도움이 될 수 있는 많은 기회를 놓칠 수 있습니다.
디자인 영역에 배경 및 테두리 추가하기
생성된 콘텐츠를 사용하여 항목을 쌓을 수도 있습니다. 사실은 둘 이상의 항목이 특정 그리드 셀을 차지할 수 있다는 것입니다. 여기에는 생성된 콘텐츠와 함께 삽입된 항목이 포함될 수 있습니다.
다음 예에는 두 개의 콘텐츠 섹션과 전체 너비 항목이 있는 디자인이 있습니다. 콘텐츠 뒤에는 전체 너비 항목 아래에도 실행되는 배경이 있습니다.
마크업에는 섹션과 전체 너비 요소가 직계 자식으로 포함된 컨테이너가 있으며 선 기반 배치를 사용하여 항목을 그리드에 배치하고 있습니다.
<article class="grid"> <section class="section1"> <p>…</p> </section> <div class="full-width"> <img src=“placeholder.jpg” alt=“Placeholder”> </div> <section class="section2"> <p>…</p> </section> </article>
.grid { display: grid; grid-template-columns: 1fr 20px 4fr 20px 1fr; grid-template-rows: auto 300px auto; grid-row-gap: 1em; } .section1 { grid-column: 3; grid-row: 1; } .section2 { grid-column: 3; grid-row: 3; } .full-width { grid-column: 1 / -1; grid-row: 2; background-color: rgba(214,232,182,.5); padding: 20px 0; }
이렇게 하면 전체 너비 이미지와 두 개의 콘텐츠 섹션이 배치된 레이아웃이 제공됩니다. 그러나 섹션에 배경을 추가하면 section
과 전체 너비 이미지 사이의 row-gap
위에서 중지됩니다.
.section { background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); }
grid-row-gap
을 제거하고 공간을 만들기 위해 패딩을 사용하면 여전히 전체 너비 패널 아래에서 실행되는 배경 효과를 사용할 수 없습니다.
여기에서 생성된 콘텐츠를 사용할 수 있습니다. 생성된 콘텐츠 ::before
추가하고 배경색을 지정합니다. 다른 작업을 수행하지 않으면 그리드의 첫 번째 셀에 콘텐츠가 배치됩니다.
.grid::before { content: ""; background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); }
그런 다음 선 기반 위치 지정을 사용하여 콘텐츠의 위치를 지정하여 배경색을 표시해야 하는 영역을 늘릴 수 있습니다.
.grid::before { content: ""; background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); grid-column: 2 / 5; grid-row: 1 / 4; }
이 CodePen에서 전체 예제를 볼 수 있습니다.
z-index
스택 제어하기
위의 예에서 생성된 콘텐츠는 ::before
로 삽입됩니다. 이것은 다른 요소가 그 뒤에 오고 스택의 맨 아래에 있으므로 내가 원하는 위치에 나머지 콘텐츠 뒤에 표시된다는 것을 의미합니다. z-index
를 사용하여 스택을 제어할 수도 있습니다. ::before
선택자를 ::after
로 변경해 보십시오. 테두리가 이미지를 가로지르는 방식에서 볼 수 있듯이 생성된 콘텐츠 배경은 이제 모든 것 위에 놓입니다. 이것은 이제 그리드 컨테이너의 마지막 항목이 되었기 때문에 마지막으로 칠해져 "맨 위에" 나타납니다.
이를 변경하려면 이 요소에 다른 모든 요소보다 낮은 z-index
속성을 부여해야 합니다. z-index
값이 없는 경우 가장 간단한 방법은 생성된 콘텐츠에 -1
의 z-index
를 지정하는 것입니다. 이렇게 하면 가장 낮은 z-index
를 가진 항목으로 스택의 첫 번째 항목이 됩니다.
.grid::after { z-index: -1; content: ""; background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); grid-column: 2 / 5; grid-row: 1 / 4; }
이 방법으로 배경을 추가하는 것은 콘텐츠 뒤에 배경을 완전히 삭제하는 것으로 제한될 필요는 없습니다. 디자인의 일부 뒤에 색상 블록을 팝할 수 있으면 몇 가지 흥미로운 효과를 만들 수 있습니다.
이것은 사양이 미래에 해결할 수 있는 것입니까?
배경과 테두리를 추가하는 것은 CSS 그리드 사양의 누락된 기능처럼 느껴지며 작업 그룹이 커뮤니티의 많은 구성원과 함께 논의한 것입니다(토론 스레드는 GitHub에 있음).
생성된 콘텐츠로 쉽게 해결되지 않는 사용 사례가 있는 경우 해당 스레드에 생각을 추가하세요. 귀하의 의견과 사용 사례는 해당 기능에 대한 개발자의 관심이 있음을 입증하는 데 도움이 되며 또한 모든 제안이 귀하가 해야 할 일을 다루고 있는지 확인하는 데 도움이 됩니다.
더 많은 예를 들어주세요!
이 기사가 생성된 콘텐츠를 실험하도록 권장하거나 이미 예가 있는 경우 댓글에 추가하십시오. 모두가 프로덕션에서 Grid를 처음 사용하기 때문에 " 생각한 적도 없습니다! "그리드를 다른 레이아웃 방법과 결합할 때 가질 수 있는 순간입니다.