[CSS] 12. grid
in CSS on Css
12. grid
grid 개요
- flex 박스가 main axis만 가능했다면, grid는 main + cross
- 이차원 배열
- 컨테이너를 가지고 행과 열을 만든 다음에 내부를 꾸미는 방식
- rows : 행
- columns : 열
- gutters (gao) : 행과 열 사이에 공백
- 레이아웃을 하기 위해 table 보다 grid 사용하기
Container - display
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
.container {
border: 5px solid red;
display: inline-grid;
grid-template-colums: 1fr 1fr 1fr
width: 150px;
}
.item {
border: 3px solid;
}
- 외부 레이아웃 + 내부 레이아웃 가능
- inline-grid
- grid : 외부 컨테이너를 만들고 행과 열을 만든 후 형제 Item 들을 하나 하나 넣는 것
Container - grid-template-rows, grid-template-columns
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
.container {
border: 5px solid red;
display: inline-grid;
// 3열을 만드는데 100px 150px 150px
grid-template-columns: 100px 150px 100px;
grid-template-rows: 100px 100px;
// 1 : 1 : 1로 전체 width를 사이좋게 나눠가지고 싶다면
grid-template-rows: 1fr 1fr 1fr
grid-template-colums: 2fr 1fr // 2 : 1
grid-template-rows: 80px 80px 80px 80px;
// 이걸 함수 표기하면?
grid-template-rows: repeat(4, 80px);
}
.item {
border: 3px solid;
}
- container 에 사용하는 속성
- 행과 열의 차이, 사용법은 동일
Container - grid-template-areas
<div class="container">
<div class="item header">1</div>
<div class="item main">2</div>
<div class="item sidebar">3</div>
<div class="item footer">4</div>
</div>
.container {
border: 5px solid red;
width: 400px;
height: 400px;
display: grid;
grid-template-colums: repeat(5, 1fr);
grid-template-rows: repeat(3, 1fr);
// 칸은 15개 인데 아이템은 4 개다
grid-tempalte-areas:
"hd hd hd hd hd"
"ma ma ma . sb"
"ft ft ft ft ft";
// . 은 빈 공간
width: 150px;
}
.item {
border: 3px solid;
}
.header {
grid-area: hd;
}
.main {
grid-area: ma;
}
.sidebar {
grid-area: sb;
}
.footer {
grid-area: ft;
}
- item 들이 한칸에 한개가 아니라 여러칸에 한개가 들어가도록 하는 것
- 각각의 덩어리가 네모 형태여야 한다.(ㄱ,ㄴ,ㄷ 같은 모양 안된다)
Container - row-gap, column-gap, gap
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
.container {
border: 5px solid red;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(4, 1fr);
row-gap: 20px;
column-gap: 50px;
// 둘이 합치면?
gap: 20px 50px;
// 앞이 무조건 row 뒤가 column 이어야 한다
}
.item {
border: 3px solid;
}
- 행간의 간격, 열간의 간격
- gutter 의 너비를 결정하는 것
Container - grid-auto-rows, grid-auto-columns
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
.container {
border: 5px solid red;
display: grid;
grid-template-colums: 100px 150px 80px;
grid-template-rows: repeat(3, 1fr);
// 칸은 9개인데 아이템은 10개
grid-auto-rows: 100px;
// 넘쳐나는 애들의 행을 100px로 한다.
grid-auto-colums: 50px;
// 암시적으로 지정한다
// 아이템이 없으면 눈에 보이지 않는다.
}
.item {
border: 3px solid;
}
- grid 는 내부에 item 이 있건 없건 내부에 명시적으로 공간을 만들어 놓는다.
- 공간은 9개인데 10번째 아이템이 있다면?
- 그것의 크기를 지정하는게 grid-auto-rows(colums)
Container - grid-auto-flow
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
.container {
border: 5px solid red;
display: grid;
grid-template-colums: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
// 1 2 3
// 4 5 6
grid-auto-flow: column;
// 행축으로 방향축을 잡는다.
// 1 4
// 2 5
// 3 6
grid-auto-flow: row dense;
// 중간에 크기가 커서 빈영역이 생긴다면 뒤에 아이들이 그 빈영역으로 올라온다.
// 위의 빈 영역이 채워진다
// 1 . .
// 2~~~~~~
// 3 4 5 일때
// 1 3 4
// 2~~~~~
// 5
}
.item {
border: 3px solid;
}
.item:nth-child(2) {
grid-column: span 2;
}
- item들이 어떻게 흘러갈 것인지를 결정하는 것
- 자리 잡는 방법의 흐름
row, column, row dense, column dense
row
: default
Container - grid (shorthand)
grid: 행(row) / 열(column)
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
.container {
border: 5px solid red;
display: grid;
grid-template-colums: 100px 200px;
grid-template-rows: 1fr 2fr
// shorthand
grid: 1fr 2fr / 100px 200px;
grid-auto-flow: row | column;
// row
grid: auto-flow 1fr 2fr / 100px 200px;
// column
grid: 1fr 2fr / auto-flow dense 100px 200px;
}
.item {
border: 3px solid;
}
- 컨테이너 속성의 단축어
- 처음에는 각각의 속성을 직접 쓰는 것을 추천
- 익숙해지면 단축어 사용하기
- 외재적인 속성 (명시적) :
grid-template-rows, grid-template-columns, grid-template-areas
- 내용물이 있건 없건 눈에 보인다.
- 내재적인 속성 (암시적) :
grid-auto-rows, grid-auto-columns, grid-auto-flow
- 아이템이 있어야만 눈에 보인다.
Container - justify-content, align-content
grid: 행(row) / 열(column)
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
.container {
border: 5px solid red;
width: 100%;
height: 500px;
display: grid;
grid-template-colums: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
// 메인축을 기준으로
justify-content: start; //default
justify-content: end;
justify-content: center;
justify-content: space-around; // 좌우 공백 동일
justify-content: space-between; // 양 끝 제외 하고 여백 동일
// 교차축을 기준으로
align-content: start;
align-content: end;
align-content: center;
align-content: space-around; // 좌우 공백 동일
align-content: space-between; // 양 끝 제외 하고 여백 동일
}
.item {
border: 3px solid;
}
- 전체 컨테이너를 기준으로 아이템들을 어떻게 배치하느냐
- flex 와 동일하다
- 조건 : 컨테이너의 크기가 내부 아이템의 크기보다 커서 빈공간이 남아야한다.
Container - justify-items, align-items
grid: 행(row) / 열(column)
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
.container {
border: 5px solid red;
width: 100%;
height: 500px;
display: grid;
grid-template-colums: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
justify-items: stretch; //default
justify-items: start | end | center
align-items: stretch | start | end | center
// 메인축을 기준으로
}
.item {
border: 3px solid;
}
.item:;nth-child(1) {
width: 50px;
height: 50px;
// 실제 한 칸보다 매우 작아진다.
// 왼쪽위에 작게 위치한다.
}
.item:nth-child(1) {
justify-self: end;
각각의 아이템에게 줄 때는 self
}
- 하나의 아이템에 대한 이야기
- justify-items는 전체 레이아웃에서 내부 뭉텅이를 어찌 넣느냐
- justify-items 는 한 칸에 대한 정렬
- 큰 틀의 크기랑은 상관이 없다.
Item - grid-row, grid-column
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
.container {
border: 5px solid red;
display: grid;
grid-template-colums: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
}
.item {
border: 3px solid;
}
.item:nth-child(1) {
background-color: red;
// start,end의 숫자는 선 기준이다. 3칸일때 위에서부터 1, 2, 3, 4
// 명시적 속성일 경우는 (grid-template-*)
// -4, -3, -2, -1로도 가능
grid-row-start: 1;
grid-row-end: 4; // -1 도 된다.
// 1 . .
// 1 . .
// 1 . .
// shorthand
grid-row: 1 / -2;
grid-column: 1 / 3;
//시작하는 곳부터 몇칸 차지했으면 좋겠을 땐?
grid-row: 2 / span 2;
// 시작하는 위치부터 2칸 차지햇으면 좋겠어
}
grid-row-start + grid-row-end
의 shorthand
Item - grid-area
// 하나라면
// grid-template-areas 지명 목적
grid-area: a;
// shorthand
grid-area: 2 / 1 / 2 / 4;
// grid-row + grid-column
grid-row: 4 / span 2;
grid-column: 2 / -1;
grid-area : 4 / 2 / span 2 / -1;
// 순서 주의하기
- 1 : grid-template-areas 에서 아이템 알려주기 위한 지명 목적
- 2 : grid-row-start, grid-column-start, grid-row-end, grid-column-end => shorthand
Item - order
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
.container {
border: 5px solid red;
display: grid;
grid-template-colums: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
.item {
border: 3px solid;
}
.item:;nth-child(5) {
order: -1;
// 다른 것들이 기본값이 0 이기 때문에 가장 앞으로 온다
// 5 1 2 3 4
}
.item:nth-child(3) {
order: -1;
// -1 중 순서가 더 빠른 3번이 가장 앞으로 온다
// 3 5 1 2 3
// 마크업에서는 원래 순서와 같다
// 1 2 3 4 5
}
- 초기값 : 0
Item - z-index
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
</div>
.container {
border: 5px solid red;
display: grid;
grid-template-colums: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
.item {
border: 3px solid;
}
.item:;nth-child(1) {
grid-row: 1 / span 2;
grid-column: 1 / span 2;
z-index: 5;
// 1이 위로 올라온다.
}
.item:nth-child(2) {
grid-row: 1 / 2
grid-column: 2 / 4;
// 둘이 겹쳐진다
// 마크업상 뒤에 있는 2가 위로 온다.
z-index: 3;
}
grid 단위 - fr, min-content, max-content
fr
(fraction) : 유동적으로 width의 길이를 비율에 따라 나눌 때- 절대 비율과 사용 가능
100px 1fr 1fr
: 100px 의 남은 공간을 나눠 갖는다. - 이 경우 절대 길이가 우선적으로 지정된다.
grid-template-columns: min-content 1fr 1fr;
min-content
: content의 내용 중 가장 짧은 단어에 맞는 크기로 줄어든다.max-content
: 이 content를 한 줄에 볼 수 있는 길이까지 길어진다.- 둘 다 내용에 따라 유동적으로 변경된다.
grid 단위 - auto-fill, auto-fit
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
.container {
border: 5px solid red;
display: grid;
// 이 두가지를 모두 쓰면 여백 없이 반응형에 맞게 할 수 있다.
grid-template-colums: repeat(auto-fill, minmax(100px, 1fr));
grid-template-rows: repeat(auto-fit), 1fr);
.item {
border: 3px solid;
}
- 반응형때 사용
auto-fill
: width 가 늘어나면 빈공간이 생기는 것이 아닌 남는 공간에 칼럼 갯수를 증가시키는 것minmax(min, max)
: 가장 작을 때 값과 가장 클 때 값을 지정auto-fit
: auto-fill을 사용할 때 width 가 매우 증가하면 거기 대응할 칼럼이 없다면 빈공간이 생기게 된다.- 하지만 auto-fit은 내부 아이템 크기가 증가하여 여백을 만들지 않는다.
- 남는 공간이 생길 때 공간이 생기지 않는다는 것이 좋다.
나의 회고 🤫
드디어 레이아웃 끝판왕 grid를 배웠다.
알고있는 속성도 있었고 처음보는 속성도 있었다.
이제부터는 레이아웃을 잡을 때 grid, flex를 상황에 맞게 적절하게 사용하여 더 이쁜 레이아웃을 만들 수 있어졌다.
html, css 를 다시 공부하며 얕게 여러번 공부하는 것 보다 깊에 한번 제대로 공부하는 것이 더 얻는 것이 많음을 다시 한번 깨달았다.
오늘로 끝이 아닌 TIL보며 자주 복습하자! 😳👍