>웹 프론트엔드 >HTML 튜토리얼 >CSS 그리드 레이아웃 가이드

CSS 그리드 레이아웃 가이드

巴扎黑
巴扎黑원래의
2017-05-01 10:21:152751검색

소개

CSS 그리드 레이아웃("그리드"라고도 함)은 2차원 그리드 레이아웃을 기반으로 하는 시스템입니다. 주요 목적은 그리드를 기반으로 사용자 인터페이스를 디자인하는 방식을 변경하는 것입니다. 우리가 알고 있듯이 CSS는 항상 웹 페이지 스타일을 지정하는 데 사용되지만 잘 작동하지 않습니다. 처음에는 테이블을 사용한 다음 부동, 위치 지정 및 인라인 블록을 사용했지만 이러한 모든 방법은 본질적으로 해킹이며 구현해야 할 중요한 문제(예: 수직 센터링)가 많이 남아 있습니다. Flexbox는 특정 개선 역할을 할 수 있지만 단순한 1차원 레이아웃만 구현할 수 있으며 복잡한 2차원 레이아웃에는 적합하지 않습니다. 실제로 Flexbox와 Grid를 함께 사용하면 최상의 결과를 얻을 수 있습니다. 그리드는 웹 사이트를 만들 때 핵을 사용했던 레이아웃 문제를 해결하기 위해 특별히 제작된 최초의 CSS 모듈입니다.

이 가이드를 만들도록 영감을 준 두 가지 사항은 다음과 같습니다. 첫 번째는 Rachel Andrew의 멋진 책인 Getting Ready for CSS Grid Layout입니다. 이 책은 그리드에 대해 자세하고 명확하게 소개하고 있다. 그리드에 대한 기본 지식을 익히고 싶다면 꼭 구매해 볼 것을 권한다. 또 다른 큰 영감은 Chris Coyier의 The Complete Guide to Flexbox에서 나왔습니다. 이 책은 Flebox에 대해 배울 수 있는 훌륭한 자료입니다. 또한 Google에서 "flexbox"를 검색할 때 유사한 리소스가 많이 나타날 것이라는 점을 여기에 추가하고 싶습니다. 하지만 가장 좋은 리소스를 활용하는 것은 어떨까요?

이 가이드를 작성하는 나의 목표는 최신 버전을 기반으로 그리드 개념을 표준화하는 것입니다. 따라서 오래된 IE 구문에 대해서는 다시 언급하지 않을 것이며 사양이 성숙해짐에 따라 이 가이드를 정기적으로 업데이트하려고 노력할 것입니다.

기본 지식 및 브라우저 지원

그리드를 시작하는 것은 쉽습니다. 컨테이너 요소를 정의하고 표시: 그리드를 설정하고, Grid-template-columns 및 Grid-template-rows 속성을 사용하여 그리드의 열과 행 크기를 설정한 다음, Grid-column 및 Grid-row를 사용하면 됩니다. 속성을 사용하여 하위 요소의 크기를 그리드로 설정합니다. Flexbox와 마찬가지로 그리드 항목의 소스 순서는 중요하지 않습니다. 미디어 쿼리와 그리드를 더 잘 통합하려면 CSS의 어느 곳에나 배치할 수 있습니다. 전체 페이지 레이아웃을 정의한 다음 이를 다른 화면 너비에 맞게 완전히 재배치하고 싶다고 상상해 보세요. 이는 단 몇 줄의 CSS 코드로 수행할 수 있습니다. 그리드는 지금까지 소개된 가장 강력한 CSS 모듈 중 하나입니다.

그리드에 대해 주목해야 할 중요한 점 중 하나는 그리드가 아직 프로젝트 사용에 적합하지 않다는 것입니다. 현재 W3C에서 작업 중인 초안이며 모든 브라우저에서 기본적으로 지원되지는 않습니다. Internet Explorer 10 및 11은 이미 지원하지만 오래된 구문을 사용하여 지원합니다. 이제 시연을 위해 특수 플래그가 활성화된 Chrome, Opera 또는 Firefox를 사용하는 것이 좋습니다. Chrome에서 chrome://flags로 이동하여 '웹 실험 플랫폼 기능'을 활성화합니다. 이 방법은 Opera(opera://flags)에서도 작동합니다. Firefox에서는 레이아웃.css.grid.enabled 플래그를 활성화합니다.

다음은 브라우저 지원 표입니다(나중에 계속 업데이트하겠습니다).

Microsoft 외에도 브라우저 제조업체에서는 그리드 사양이 완성될 때까지 기다렸다가 이를 홍보하려는 것 같습니다. 이는 여러 구문을 배우는 것에 대해 걱정할 필요가 없다는 것을 의미하기 때문에 좋은 것입니다.

Grid의 사용을 기다리는 것은 시간문제일 뿐입니다. 하지만 이제는 배우기 시작해야 합니다.

중요 용어

그리드에 대해 알아보기 전에 관련 용어를 이해해야 합니다. 여기에 관련된 용어는 개념적으로 유사하기 때문에 그리드 사양의 관련 정의를 먼저 기억하지 않으면 다른 개념과 쉽게 혼동될 수 있습니다. 하지만 걱정하지 마세요. 여기에는 부동산이 많지 않습니다.

그리드 컨테이너

요소가 display:grid 속성을 설정하면 모든 그리드 항목(Grid Items)의 상위 요소가 됩니다. 다음 예에서 컨테이너는 그리드 컨테이너입니다.

아아아아

그리드 아이템

그리드 컨테이너의 자식(예: 자식 요소)입니다. 여기의 항목 요소는 모두 그리드 항목이지만 하위 항목은 포함되지 않습니다.

아아아아

그리드라인

구분선은 그리드의 구조를 형성합니다. 세로("열 눈금선") 또는 가로("행 눈금선")일 수 있으며 행이나 열의 양쪽에 존재합니다. 아래 이미지의 노란색 선은 기둥 그리드 선의 예입니다.

그리드 트랙

인접한 두 그리드 선 사이의 공간입니다. 이를 그리드의 행이나 열로 생각할 수 있습니다. 아래에는 그리드 선의 두 번째 행과 세 번째 행 사이의 그리드 트랙이 표시됩니다.

网格单元格(Grid Cell)

两个相邻的行和两个相邻的列之间的网格线空间。它是网格的一个"单位"。下面图片所示的是行网格线 1 和 2 与列网格线 2 和 3 之间的网格单元格。

网格区域(Grid Area)

四条网格线所包围的所有空间。网格区域可由任意数量的网格单元格组成。下面图片所示的是行网格线 1 和 3 和列网格线 1 和 3 之间的网格区域。

网格容器属性(Grid Container)

display

定义一个元素成为网格容器,并对其内容建立一个网格格式的上下文。

属性值:

  • grid: 产生一个块级的网格


  • inline-grid: 产生内联级网格


.container{
    display: grid | inline-grid   
}

注: column, float, clear, 和 vertical-align 元素对网格容器不起作用。

grid-template-rows

利用以空格分隔的值定义网格的列和行。值的大小代表轨道的大小,并且它们之间的空格表示网格线。

属性值:

  • : 可以是一个长度、百分比或者是网格中自由空间的一小部分(使用fr单位)


  • : 你选择的任意名称


  • subgrid - 如果你的网格容器本身就是一个网格项(即嵌套网格),你可以使用此属性指定行和列的大小继承于父元素而不是自身指定。


.container{
    grid-template-columns: <track-size> ... | <line-name> <track-size> ... | subgrid;
    grid-template-rows: <track-size> ... | <line-name> <track-size> ... | subgrid;
}

示例:

当你在值之间留有空格时,网络线就会自动分配数值名称:

.container{
    grid-template-columns: 40px 50px auto 50px 40px;
    grid-template-rows: 25% 100px auto;
}

但是你也可以显示命名,请参考下面括号语法中的名称命名方式:

.container{
    grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
    grid-template-rows: [row1-start] 25% [row1-end] 100% [third-line] auto [last-line];
}

请注意,一条网格线可以具有有多个名称。例如,这里的第二行将有两个名字: row1-end 和 row2-start:

.container{
    grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}

如果你的定义中包含重复的部分,你可以使用 repeat() 表示法进行精简:

.container{
    grid-template-columns: repeat(3, 20px [col-start]) 5%;
}

等效于:

.container{
    grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}

fr 单位允许你将一个轨道大小设置为网格容器内自由空间的一小部分。如下所示,每个网格项就会占据网格容器宽度的三分之一:

.container{
    grid-template-columns: 1fr 1fr 1fr;
}

这里自由空间表示除去非弹性项以后剩余的空间。在此示例中的 fr 单位的可用空间表示减去50px以后的空间大小:

.container{
    grid-template-columns: 1fr 50px 1fr 1fr;
}

grid-template-areas

使用grid-area属性定义网格区域名称,从而定义网格模板。网格区域重复的名称就会导致内容跨越这些单元格。句点表示一个空单元格。语法本身提供了一种可视化的网格结构。

属性值:

  • : 使用grid-area属性定义网格区域名称


  • .: 句点表示一个空单元格


  • none: 无网格区域被定义


.container{
    grid-template-areas: "<grid-area-name> | . | none | ..."
                      "..."
}

示例:

.item-a{
    grid-area: header;
}
.item-b{
    grid-area: main;
}
.item-c{
    grid-area: sidebar;
}
.item-d{
    grid-area: footer;
}
.container{
    grid-template-columns: 50px 50px 50px 50px;
    grid-template-rows: auto;
    grid-template-areas: "header header header header"
                         "main main . sidebar"
                         "footer footer footer footer"
}

这将创建一个四列三行的网格。最上面的一行为header区域。中间一行由两个main区域,一个空单元格和一个sidebar区域。最后一行是footer区域。

你所声明的每一行都需要具有相同数目的单元格。

你可以使用任意数量的句点(.)声明单个空单元格。只要句点之间没有空格就表示一个空单元格。

注意,你只是使用此语法进行网格区域命名,而不是网格线命名。当你使用此语法时,区域两边的线就会得到自动命名。如果网格区域名称为foo,则其行线和列线的名称就将为foo-start,最后一行线及其最后一列线的名字就会为foo-end。这意味着一些线就可能具有多个名称,如上面示例中所示,拥有三个名称: header-start, main-start, 以及footer-start。

grid-column-gap和grid-row-gap

指定网格线的大小。你可以把它想像成在行/列之间设置间距宽度。

属性值:

  • : 一个长度值


.container{
    grid-column-gap: <line-size>;
    grid-row-gap: <line-size>;
}

示例:

.container{
    grid-template-columns: 100px 50px 100px;
    grid-template-rows: 80px auto 80px; 
    grid-column-gap: 10px;
    grid-row-gap: 15px;
}

间距仅仅在列/行之间产生,而不会在边缘区。

grid-gap

grid-column-gap 和 grid-row-gap的简写值。

属性值:

  • : 长度值


.container{
    grid-gap: <grid-column-gap> <grid-row-gap>;
}

示例:

.container{
    grid-template-columns: 100px 50px 100px;
    grid-template-rows: 80px auto 80px; 
    grid-gap: 10px 15px;
}

如果没有指定grid-row-gap属性的值,默认与grid-column-gap属性值相同

justify-items

沿列轴对齐网格项中的内容(相反于align-item属性定义的沿行轴对齐)。此值适用于容器内所有的网格项。

属性值:

  • start: 内容与网格区域的左端对齐


  • end: 内容与网格区域的右端对齐


  • center: 内容处于网格区域的中间位置


  • stretch: 内容宽度占据整个网格区域空间(默认值)


.container{
    justify-items: start | end | center | stretch;
}

示例:

.container{
    justify-items: start;
}

.container{
    justify-items: end;
}

.container{
    justify-items: center;
}

.container{
    justify-items: stretch;
}

这也可以使用justify-self属性对各个网格项进行设置。

align-items

沿行轴对齐网格项中的内容(相反于justify-item属性定义的沿列轴对齐)。此值适用于容器内所有的网格项。

属性值:

  • start: 内容与网格区域的顶端对齐


  • end: 内容与网格区域的底部对齐


  • center: 内容处于网格区域的中间位置


  • stretch: 内容高度占据整个网格区域空间(默认值)


.container{
    align-items: start | end | center | stretch;
}

示例:

.container{
    align-items: start;
}

.container{
    align-items: end;
}

.container{
    align-items: center;
}

.container{
    align-items: stretch;
}

这也可以使用align-self属性对各个网格项进行设置。

justify-content

当你使用px这种非响应式的单位对你的网格项进行大小设置时,就有可能出现一种情况--你的网格大小可能小于其网格容器的大小。在这种情况下,你就可以设置网格容器内网格的对齐方式。此属性会将网格沿列轴进行对齐(相反于align-content属性定义的沿行轴对齐)。

属性值:

  • start: 网格与网格容器的左端对齐


  • end: 网格与网格容器的右端对齐


  • center: 网格处于网格容器的中间


  • stretch: 调整网格项的大小,使其宽度填充整个网格容器


  • space-around: 在网格项之间设置偶数个空格间隙,其最边缘间隙大小为中间空格间隙大小的一半


  • space-between: 在网格项之间设置偶数个空格间隙,其最边缘不存在空格间隙


  • space-evenly: 在网格项之间设置偶数个空格间隙,同样适用于最边缘区域


.container{
    justify-content: start | end | center | stretch | space-around | space-between | space-evenly;    
}

示例:

.container{
    justify-content: start;
}

.container{
    justify-content: end; 
}

.container{
    justify-content: center;  
}

.container{
    justify-content: stretch; 
}

.container{
    justify-content: space-around;    
}

.container{
    justify-content: space-between;   
}

.container{
  justify-content: space-evenly;    
}

align-content

当你使用px这种非响应式的单位对你的网格项进行大小设置时,就有可能出现一种情况--你的网格大小可能小于其网格容器的大小。在这种情况下,你就可以设置网格容器内网格的对齐方式。此属性会将网格沿行轴进行对齐(相反于justify-content属性定义的沿列轴对齐)。

属性值:

  • start: 网格与网格容器的顶端对齐


  • end: 网格与网格容器的底部对齐


  • center: 网格处于网格容器的中间


  • stretch: 调整网格项的大小,使其高度填充整个网格容器


  • space-around: 在网格项之间设置偶数个空格间隙,其最边缘间隙大小为中间空格空隙大小的一半


  • space-between: 在网格项之间设置偶数个空格间隙,其最边缘不存在空格间隙


  • space-evenly: 在网格项之间设置偶数个空格间隙,同样适用于最边缘区域


.container{
    align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}

示例:

.container{
    align-content: start; 
}

.container{
    align-content: end;   
}

.container{
    align-content: center;    
}

.container{
    align-content: stretch;   
}

.container{
    align-content: space-around;  
}

.container{
    align-content: space-between; 
}

.container{
    align-content: space-evenly;  
}

grid-auto-columns和grid-auto-rows

指定任何自动生成的网格轨道(隐式网格跟踪)的大小。当你显式定位行或列(使用 grid-template-rows/grid-template-columns属性)时,就会产生超出定义范围内的隐式网格轨道。

属性值:

  • : 可以是长度、 百分比或网格自由空间的一小部分(使用fr单位)


.container{
    grid-auto-columns: <track-size> ...;
    grid-auto-rows: <track-size> ...;
}

为了说明隐式网格轨道是如何被创造出来的,请思考如下代码:

.container{
    grid-template-columns: 60px 60px;
    grid-template-rows: 90px 90px
}

这里创建了一个2 x 2 的网格。

但是现在你想象你使用grid-column 和 grid-row 来定位网格项,如下所示:

.item-a{
    grid-column: 1 / 2;
    grid-row: 2 / 3;
}
.item-b{
    grid-column: 5 / 6;
    grid-row: 2 / 3;
}

这里我们定义.item b开始于列线 5 并结束于在列线 6,但是我们从来没有定义列线 5 或 6。因为我们引用不存在的线,宽度为0的隐式轨道的就会被创建用来填补空白。我们可以使用grid-auto-columns 和 grid-auto-rows属性来设置这些隐式轨道的宽度:

.container{
    grid-auto-columns: 60px;
}

grid-auto-flow

如果你不显式的在网格中放置网格项,自动布局算法就会自动踢出此网格项。此属性用来控制自动布局算法的工作原理。

属性值:

  • row: 告诉自动布局算法填充每一行,必要时添加新行


  • column: 告诉自动布局算法填充每一列,必要时添加新列


  • dense: 告诉自动布局算法试图填补网格中之前较小的网格项留有的空白


.container{
    grid-auto-flow: row | column | row dense | column dense
}

注意:dense值可能会导致更改网格项的顺序。

示例:

考虑如下HTMl代码:

<section class="container">
    <p class="item-a">item-a</p>
    <p class="item-b">item-b</p>
    <p class="item-c">item-c</p>
    <p class="item-d">item-d</p>
    <p class="item-e">item-e</p>
</section>

这里定义了一个两列五行的网格,并将 grid-auto-flow属性设置为row(即默认值):

.container{
    display: grid;
    grid-template-columns: 60px 60px 60px 60px 60px;
    grid-template-rows: 30px 30px;
    grid-auto-flow: row;
}

将网格项放置在网格中时只需要其中的两个网格项:

.item-a{
    grid-column: 1;
    grid-row: 1 / 3;
}
.item-e{
    grid-column: 5;
    grid-row: 1 / 3;
}

因为我们将grid-auto-flow属性设置为了row,所以我们的网格看起来会像这个样子。注意我们我们没有对其进行设置的三个网格项(item-b, item-c and item-d),会沿行轴进行布局。

如果我们将grid-auto-flow属性设置为 column,item-b, item-c 和 item-d 就会沿列轴进行布局。

.container{
    display: grid;
    grid-template-columns: 60px 60px 60px 60px 60px;
    grid-template-rows: 30px 30px;
    grid-auto-flow: column;
}

grid

在一行声明中设置一下所有属性的简写形式:grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, 以及 grid-auto-flow。它将 grid-column-gap 和 grid-row-gap属性设置为初始值,即使它们不能显示的设置此属性。

属性值:

  • none: 将所有的子属性设置为初始值


  • subgrid: 将grid-template-rows 和 grid-template-columns属性值设置为subgrid,其余子属性设置为初始值


  • / : 将grid-template-rows 和 grid-template-columns属性值设置为指定值,其余子属性设置为初始值


  • [ [ / ] ] : grid-auto-flow, grid-auto-rows 和 grid-auto-columns属性分别接受相同的值,如果省略了grid-auto-columns属性,它将设置为grid-auto-rows属性的值。如果两者均被忽略,那么都将被设置为初始值。


.container{
    grid: none | subgrid | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [/ <grid-auto-columns>]];
}

示例:

下面两个代码块是等效的:

.container{
    grid: 200px auto / 1fr auto 1fr;
}

.container{
    grid-template-rows: 200px auto;
    grid-template-columns: 1fr auto 1fr;
    grid-template-areas: none;
}

同样,下面的两个代码块也是等效的:

.container{
    grid: column 1fr / auto;
}

.container{
    grid-auto-flow: column;
    grid-auto-rows: 1fr;
    grid-auto-columns: auto;
}

它还接受一次性设置所有属性,更复杂但非常方便的语法。指定grid-template-areas, grid-auto-rows 和 grid-auto-columns属性,其他所有子属性都将设置为其初始值。你现在所做的是在其网格区域内,指定网格线名称和内联轨道大小。下面是最简单的描述:

.container{
    grid: [row1-start] "header header header" 1fr [row1-end]
          [row2-start] "footer footer footer" 25px [row2-end]
          / auto 50px auto;
}

等效于:

.container{
    grid-template-areas: "header header header"
                         "footer footer footer";
    grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
    grid-template-columns: auto 50px auto;    
}

网格项属性(Grid Items)

grid-column-start/grid-column-end/grid-row-start/grid-row-end

使用特定的网格线确定网格项在网格内的位置。grid-column-start/grid-row-start 属性表示网格项的网格线的起始位置,grid-column-end/grid-row-end属性表示网格项的网格线的终止位置。

属性值:

  • : 可以是一个数字来引用相应编号的网格线,或者使用名称引用相应命名的网格线


  • span : 网格项包含指定数量的网格轨道


  • span : 网格项包含指定名称网格项的网格线之前的网格轨道


  • auto: 表明自动定位,自动跨度或者默认跨度之一


.item{
    grid-column-start: <number> | <name> | span <number> | span <name> | auto
    grid-column-end: <number> | <name> | span <number> | span <name> | auto
    grid-row-start: <number> | <name> | span <number> | span <name> | auto
    grid-row-end: <number> | <name> | span <number> | span <name> | auto
}

示例:

.item-a{
    grid-column-start: 2;
    grid-column-end: five;
    grid-row-start: row1-start
    grid-row-end: 3
}

.item-b{
    grid-column-start: 1;
    grid-column-end: span col4-start;
    grid-row-start: 2
    grid-row-end: span 2
}

如果没有声明grid-column-end/grid-row-end属性,默认情况下网格项的跨度为1。

网格项可以互相重叠。可以使用z-index属性控制堆叠顺序。

grid-column/grid-row

grid-column-start + grid-column-end, 和 grid-row-start + grid-row-end属性分别的简写形式。

属性值:

  • / : 每一个属性均接收一个相同值,包括跨度。


.item{
    grid-column: <start-line> / <end-line> | <start-line> / span <value>;
    grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}

示例:

.item-c{
    grid-column: 3 / span 2;
    grid-row: third-line / 4;
}

如果没有声明结束网格线值,默认网格轨道跨度为1.

grid-area

给网格项进行命名以便于模板使用grid-template-areas属性创建时可以加以引用。另外也可以被grid-row-start + grid-column-start + grid-row-end + grid-column-end属性更为简洁的加以引用。

属性值:

  • : 你所定义的名称


  • / / / : 可以为数字或者名称


.item{
    grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}

示例:

对网格项进行命名的一种方式:

.item-d{
    grid-area: header
}

grid-row-start + grid-column-start + grid-row-end + grid-column-end属性的一种简写方式:

.item-d{
    grid-area: 1 / col4-start / last-line / 6
}

justify-self

沿列轴对齐网格项中的内容(相反于align-item属性定义的沿行轴对齐)。此值适用于单一网格项中的内容。

属性值:

  • start: 内容与网格区域的左端对齐


  • end: 内容与网格区域的右端对齐


  • center: 内容处于网格区域的中间位置


  • stretch: 内容宽度占据整个网格区域空间(默认值)


.item{
    justify-self: start | end | center | stretch;
}

示例

.item-a{
    justify-self: start;
}

.item-a{
    justify-self: end;
}

.item-a{
    justify-self: center;
}

.item-a{
    justify-self: stretch;
}

设置网格中所有网格项的对齐方式,可以使用网格容器上的justify-items属性。

align-self

沿行轴对齐网格项中的内容(相反于justify-item属性定义的沿列轴对齐)。此值适用于单一网格项中的内容。

属性值:

  • start: 内容与网格区域的顶端对齐


  • end: 内容与网格区域的底部对齐


  • center: 内容处于网格区域的中间位置


  • stretch: 内容高度占据整个网格区域空间(默认值)


.item{
    align-self: start | end | center | stretch;
}

示例:

.item-a{
    align-self: start;
}

.item-a{
    align-self: end;
}

.item-a{
    align-self: center;
}

.item-a{
    align-self: stretch;
}

使网格中所有的网格项对齐,可以使用网格容器上的align-items属性。

위 내용은 CSS 그리드 레이아웃 가이드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.