📌 이 포스팅에서는 CSS의 grid에 대해서 정리하겠습니다!
🔥 grid 란?
🔥 grid container에 주는 속성들
🔥 grid item에 주는 속성들
🔥 grid 정렬 및 순서 정하기
✔️ flex가 1차원 레이아웃 시스템이라면, grid는 가로-세로를 동시에 제어하는 2차원 레이아웃 시스템입니다.
✔️ 즉, flex는 하나의 방향으로 정렬을 적용시키는데, grid는 양방향으로 배치할 때 유용합니다.
✔️ 일반적으로 전체 레이아웃은 grid로 제어하고, 그 안에 container에 대해서는 flex로 잡아주는 방식을 사용한다고 합니다.
✔️ grid도 flex와 마찬가지로 부모가 되는 container와 그 안에 요소들인 item으로 구분하여 제어합니다.
✔️ grid container : "display:grid;" 적용하는 grid의 전체 영역을 의미합니다. grid container의 요소들이 grid의 규칙에 따라 정렬됩니다.
✔️ grid item : container의 자식 요소입니다.
✔️ grid track : grid의 행(row)과 열(column)
✔️ grid cell : grid 한 칸을 가르키는 말로, item 하나가 들어가는 가상의 틀을 의미합니다.
✔️ grid line : grid 셀을 구분하는 선을 뜻합니다.
✔️ grid number : grid line의 각 번호입니다.
✔️ grid gap : grid cell 간의 간격 또는 grid cell와 container 간의 간격을 의미합니다.
✔️ grid area : grid line으로 둘러싸인 영역으로, grid cell의 집합을 의미합니다.
✔️ grid 또한 flex처럼 "display:grid" 속성으로 시작합니다. "display:grid"를 container에 주었을 때, item들이 block 요소라면 변화가 없습니다.
✔️ 아무런 변화가 발생하지 않는 이유는 grid track의 형태와 크기를 지정하지 않았기 때문입니다.
✔️ 전체적인 grid 형태를 정의하기 위해서는 "grid-template-columns" 또는 "grid-template-rows"를 통해 설정이 필요합니다.
✔️ "grid-template-columns"는 열의 배치이고, "grid-template-rows"는 행의 배치를 제어합니다.
✔️ px 단위로 cell을 제어할 수도 있지만, grid에서는 fraction이라는 개념이 있습니다. 이는 비율을 의미하며 1fr, 1fr도 쓰면 1:1의 비율로 레이아웃을 정렬합니다.
<!DOCTYPE html> <html> <head> <style> .grid-container-1 { padding: 10px; background: lightgray; display: grid; grid-template-columns: 1fr 1fr; } .grid-container-2 { padding: 10px; background: lightgray; display: grid; grid-template-columns: 100px 500px 300px; } .grid-item { padding: 10px; border: 3px solid rgb(50,50,40); color: white; background: #ff6937; } </style> </head> <body> <div class="grid-container-1"> <div class="grid-item">item_A</div> <div class="grid-item">item_B</div> <div class="grid-item">item_C</div> <div class="grid-item">item_D</div> <div class="grid-item">item_E</div> <div class="grid-item">item_F</div> <div class="grid-item">item_G</div> <div class="grid-item">item_H</div> <div class="grid-item">item_I</div> </div> <div class="grid-container-2"> <div class="grid-item">item_A</div> <div class="grid-item">item_B</div> <div class="grid-item">item_C</div> <div class="grid-item">item_D</div> <div class="grid-item">item_E</div> <div class="grid-item">item_F</div> <div class="grid-item">item_G</div> <div class="grid-item">item_H</div> <div class="grid-item">item_I</div> </div> </body> </html>
✔️ fr과 px을 함께 사용할 수도 있고, 같은 비율이 반복된다면 repeat를 이용할 수 있습니다.<style> .grid-container-1 { padding: 10px; background: lightgray; display: grid; grid-template-columns: repeat(5, 1fr); } .grid-container-2 { padding: 10px; background: lightgray; display: grid; grid-template-columns: 1fr 300px 1fr; } .grid-item { padding: 10px; border: 3px solid rgb(50,50,40); color: white; background: #ff6937; } </style>
✔️ "grid-template-rows"는 cell의 높이를 제어합니다.
✔️ 현재 9개의 item이있고, columns을 3개로 나눴으니, row는 3개가 됩니다.
<style> .grid-container-1 { padding: 10px; background: lightgray; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: 100px 200px 400px; } </style>
✔️ "grid-template-rows"를 2개만 지정하면 어떻게 될까요? 순서대로 2개만 크기가 지정되고, 남은 자리에는 auto가 들어간 것과 같습니다. container의 높이만큼 확보합니다.
<style> .grid-container-2 { padding: 10px; background: lightgray; display: grid; grid-template-columns: 1fr 300px 1fr; grid-template-rows: 200px 100px; } </style>
✔️ "display:inline-grid" 속성도 있는데 "display:inline-flex" 처럼 주변 inline요소들이 옆으로 올라올 수 있게 해줍니다.
✔️ "grid-template-columns"만 지정해주었을 때, item의 content의 길이만큼 높이는 늘어날 수 밖에 없습니다. 이 때, 높이에 대해 minmax를 주면 최소높이와 최대높이를 정할 수 있습니다.
<style> .grid-container { padding: 10px; background: lightgray; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, minmax(100px, auto)); } </style>
✔️ auto-fill은 item의 요소의 갯수와 상관 없이 자동으로 어떤 비율을 채워줄 때 사용합니다. minmax의 너비를 %로 주어주면 "repeat(5, minmax(20%,auto));" 넣은것과 차이점이 없지만, minmax에 px값을 넣어주면 차이가 발생합니다.
<style> .grid-container { padding: 10px; background: lightgray; display: grid; grid-template-columns: repeat(auto-fill, minmax(20%,auto)); } </style>
✔️ auto-fit은 자동으로 container에서 남은 여백을 각 item에게 나눠줘서 가득 채우게합니다.
✔️ 즉, "repeat(auto-fill, minmax(200px,auto))"을 사용했는데, item이 3개밖에 없어서 화면이 커질 때, 올라와서 붙을 item이 없다면 여백이 발생됩니다.
✔️ 이 때, "repeat(auto-fit, minmax(200px,auto))"을 사용하면 아래처럼 가득 채우는 것을 볼 수 있습니다.
<style> .grid-container { padding: 10px; background: lightgray; display: grid; grid-template-columns: repeat(auto-fit, minmax(20px,auto)); } </style>
✔️ row-gap은 행(row)과 행(row) 사이의 간격을 만들어주기 때문에 위, 아래에 cell 사이의 여백을 의미합니다.
✔️ column-gap은 열(column)과 열(column) 사이의 간격을 만들어주기 때문에 오른쪽 cell와 왼쪽 cell 사이사이의 여백을 의미합니다.
✔️ gap은 row와 column 갭을 모두 사용할 때 씁니다. 예전에는 grid-gap을 사용했지만 현재는 gap으로 축약되었다고 합니다.
<style> .grid-container { padding: 10px; background: lightgray; display: grid; grid-template-columns: repeat(auto-fit, minmax(30%,auto)); gap:20px } </style>
✔️ "grid-auto-columns"와 "grid-auto-rows"는 item이 몇개까지 늘어날지 예상하기 어려울 때 사용하는 속성으로 rapeat을 넣어줄 필요 없이, minmax만 넣어주면 minmax의 제어에 따라 item이 추가됬을 때 자동으로 이어지면서 정렬해줍니다.
✔️ "gird-column"와 "grid-row"는 item에 주는 속성으로 grid line으로 cell을 지정하여 제어할 수 있습니다.
✔️ 속성 값으로는 line의 범위가 들어가는데 line은 맨 위부터 1번값으로 지정하면 됩니다.
✔️ 이를 /로 출약하여 사용하지 않고, 풀어서 작성할 하는 방법으로 "grid-column-start" & "grid-column-end", "grid-row-start" & "grid-row-end"가 있습니다.
✔️ 아래 예시를 보면, 첫번째 item을 지정하여, gird-column과 grid-row를 주었더니 그 line범위 까지의 공간을 차지하는 것을 볼 수 있습니다.
<!DOCTYPE html> <html> <head> <style> .grid-container { padding: 10px; background: lightgray; display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: minmax(100px, auto); gap: 1rem; } .grid-item { padding: 10px; border: 3px solid rgb(50,50,40); color: white; background: #ff6937; } .grid-item:nth-child(1){ grid-column : 1/3; grid-row : 1/4; } </style> </head> <body> <div class="grid-container"> <div class="grid-item">item_A</div> <div class="grid-item">item_B</div> <div class="grid-item">item_C</div> <div class="grid-item">item_D</div> <div class="grid-item">item_E</div> <div class="grid-item">item_F</div> <div class="grid-item">item_G</div> <div class="grid-item">item_H</div> <div class="grid-item">item_I</div> </div> </body> </html>
✔️ "grid-template-areas"는 grid 영역 이름을 지정하여 제어할 수 있도록 합니다.
✔️ 즉, grid area에 이름을 붙이고, 그 이름을 이용하여 grid area를 배치하는 방법입니다.
✔️ gird area에 영역을 주기 위해서는 각 item에게 "grid-area" 사용하여, "grid-template-areas"에서 어떤 이름으로 사용될지 이름을 명시해줍니다.
✔️ 이후 container에 "grid-template-areas" 속성으로 각 이름들이 어떻게 배치될지 지정합니다.
✔️ 공백을 주고 싶을 땐, dot(.)이나 none을 적어주면 그 영역을 공백으로 처리합니다.
<!DOCTYPE html> <html> <head> <style> .grid-container { padding: 10px; background: lightgray; display: grid; gap: 1rem; grid-template-columns: 1fr 3fr 1fr; grid-template-areas: '. header header' 'sidebar-left main sidebar-right' '. . .' 'footer footer footer'; } .grid-item { padding: 10px; border: 3px solid rgb(50,50,40); color: white; background: #ff6937; } /* grid 영역 이름 지정 */ .header{grid-area: header;} .sidebar-left{grid-area: sidebar-left;} .sidebar-right{grid-area: sidebar-right;} .main{grid-area: main;} .footer{grid-area: footer;} </style> </head> <body> <div class="grid-container"> <div class="header grid-item">Header</div> <div class="sidebar-left grid-item">Sidebar left</div> <div class="sidebar-right grid-item">Sidebar right</div> <div class="main grid-item">lorem*20</div> <div class="footer grid-item">Footer</div> </div> </body> </html>
✔️ felx에서 container에 주는 속성으로 align-items가 있습니다. flex에서는 main axis와 cross axis가 교차되면 그에 따라 기준이 되는 정렬 축이 변경됩니다.
✔️ 단, grid에서는 이런 축의 교차가 없기 때문에 "align-items"를 container에 속성으로 지정하면, 세로(column축) 방향으로 정렬을 해줍니다.
✔️ 또한 여기서 정렬한다는 의미는 cell 영역의 범위 안에서 item이 어디를 기준으로 정렬되느냐하는 의미입니다.
✔️ gird에서 "align-items" 속성은 "strerch"가 기본값이고, "start", "center", "end" 속성값을 사용할 수 있습니다.
<!DOCTYPE html> <html> <head> <style> .grid-container { padding: 10px; background: lightgray; display: grid; gap: 1rem; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 200px); gap: 1rem; /* align-items: stretch; */ /* align-items: start; */ align-items: center; /* align-items: end; */ } .grid-item { padding: 10px; border: 3px solid rgb(50,50,40); color: white; background: #ff6937; } </style> </head> <body> <div class="grid-container"> <div class="grid-item">item A</div> <div class="grid-item">item B</div> <div class="grid-item">item C</div> <div class="grid-item">item D</div> <div class="grid-item">item E</div> <div class="grid-item">item F</div> <div class="grid-item">item G</div> <div class="grid-item">item H</div> <div class="grid-item">item I</div> </div> </body> </html>
✔️ grid에서 가로축에 대한 정렬 "justify-items"로 제어합니다. 이 또한 container에 적용하고, 기본값은 "strech"입니다. 이 밖에 "start", "center", "end" 속성이 있습니다.
<!DOCTYPE html> <html> <head> <style> .grid-container { padding: 10px; background: lightgray; display: grid; gap: 1rem; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 200px); gap: 1rem; /* justify-items: stretch; */ /* justify-items:start; */ justify-items:center; /* justify-items:end; */ } .grid-item { padding: 10px; border: 3px solid rgb(50,50,40); color: white; background: #ff6937; } </style> </head> <body> <div class="grid-container"> <div class="grid-item">item A</div> <div class="grid-item">item B</div> <div class="grid-item">item C</div> <div class="grid-item">item D</div> <div class="grid-item">item E</div> <div class="grid-item">item F</div> <div class="grid-item">item G</div> <div class="grid-item">item H</div> <div class="grid-item">item I</div> </div> </body> </html>
✔️ "align-items"와 "justify-items"를 축약속성으로 쓰려면, "place-items"를 사용합니다.
✔️ "align-content" 또한 container에 정렬을 위해 적용하는 속성으로 "align-items"는 개별 item이 cell안에서 정렬을 담당한다면, "align-content"는 모든 cell의 차원에서 세로축 정렬을 제어합니다.
✔️ "justify-content"도 container에 주는 속성으로 grid item을 통째로 정렬할 때 사용하고 가로 방향을 제어해줍니다.
✔️ 이 둘 속성 모두 "stretch"가 기본값이고, "start", "center", "end", "space-between", "space-around", "space-evenly"를 속성값으로 사용할 수 있습니다.
✔️ 축약형으로는 "place-content"를 사용할 수 있습니다. 속성값은 "align-content", "justify-content" 순서로 지정해줍니다.
✔️ 각 아이템의 나열 순서를 결정하는 속성으로 작은 숫자일 수록 먼저 배치됩니다. flex와 제어 방식을 동일하고, item에 적용시키는 속성입니다.
.grid-item:nth-child(1){order:3;} .grid-item:nth-child(2){order:2;} .grid-item:nth-child(3){order:1;}