[CSS] Grid 그리고 Grid와 Flex의 차이

Yeong·2023년 5월 17일
0

가장 먼저 Flex와 Grid 의 가장 큰 차이는
flex는 한 방향 레이아웃 시스템이고 (1차원)
Grid는 두 방향(가로-세로) 레이아웃 시스템이다.

  • 그리드 컨테이너 (Grid Container)
    display: grid를 적용하는, Grid의 전체 영역입니다. Grid 컨테이너 안의 요소들이 Grid 규칙의 영향을 받아 정렬된다고 생각하면 됩니다. 위 코드 div class=”container”가 Grid 컨테이너예요.
  • 그리드 아이템 (Grid Item)
    Grid 컨테이너의 자식 요소들입니다. 바로 이 아이템들이 Grid 규칙에 의해 배치되는 거예요. 위 코드에서 div class=”item”들이 Grid 아이템입니다.
  • 그리드 트랙 (Grid Track)
    Grid의 행(Row) 또는 열(Column)
  • 그리드 셀 (Grid Cell)
    Grid의 한 칸을 가리키는 말이에요. div같은 실제 html 요소는 그리드 아이템이고, 이런 Grid 아이템 하나가 들어가는 “가상의 칸(틀)”이라고 생각하면 됩니다.
  • 그리드 라인(Grid Line)
    Grid 셀을 구분하는 선입니다.
  • 그리드 번호(Grid Number)
    Grid 라인의 각 번호입니다.
  • 그리드 갭(Grid Gap)
    Grid 셀 사이의 간격입니다.
  • 그리드 영역(Grid Area)
    Grid 라인으로 둘러싸인 사각형 영역으로, 그리드 셀의 집합

**display: grid; ** 

💡 그리드 형태 정의

grid-template-rows
grid-template-columns

3개의 칼럼이 있을 경우 grid-template-columns: 100px 200px 300px 이라고 한다면 각각의 크기만큼 차지한다.
만약에 3열 중 양끝 열의 값은 변하고, 2번째 칼럼은 고정되기를 원하면
grid-template-columns: 1fr 200px 1fr 이라고 한다.

📝 repeat() 와 minmax()

grid-templete-rows: repeat(3, minmax(100px, auto));
  //repeat(반복횟수, 반복값)

최솟값과 최댓값을 지정할 수 있는 함수.

minmax(100px, auto)의 의미는 최소한 100px, 최대는 자동으로(auto) 늘어나게!

=>즉 아무리 내용의 양이 적더라도 최소한 높이 100px은 확보하고, 내용이 많아 100px이 넘어가면 알아서 늘어나도록 처리해 준 예시

📝 auto-fill 과 auto-fit

auto-fill과 auto-fit은 column의 개수를 미리 정하지 않고 설정된 너비가 허용하는 한 최대한 셀을 채운다.

  
.container {
	grid-template-columns: repeat(auto-fill, minmax(20%, auto));
}

반응형 미디어쿼리의 효과를 누릴 수 있다. 화면창의 크기에 따라 나뉘니까!

★auto-fit는 칼럼의 갯수가 부족할 때 그 한 줄을 다 채워주는것.
예를들어, 칼럼이 3개인데 그 한 줄이 다 안채워지고 남는다면 auto-fill을 auto-fit으로 바꿔준다. 그러면 한줄을 균형있게 채워줌.minmax(200px, auto)라면 갯수가 모자라도 채운다.

📝 fr

fr은 fraction(뜻은 여기로)인데, 숫자 비율대로 트랙의 크기를 나눈다.
예를들어 1fr 1fr 1fr은 균일하게 1:1:1 비율인 3개의 column을 만들겠다는 의미이다.
그 칸을 100% 잘 채운다.

만약 모든 칼럼이 동일하게 1fr 이라면
grid-template-columns: repeat(5,1fr) 이라고 작성해도 된다.
=> 몇 개의 칼럼을 어떤 비율로 쓰는 것인지 의미함

grid-template-columns: repeat(3,1fr 2fr 1fr)이라고 작성해도되는데 그 경우엔 아래와 같이 화면이 구현된다. (A, B, C1:2:1의 비율로 3번 반복된다는 뜻.)

💡 Gap 간격만들기

그리드 셀 사이의 간격을 설정

.container {
	row-gap: 10px;
	/* row의 간격을 10px로 */
	column-gap: 20px;
	/* column의 간격을 20px로 */
}

💡 그리드 형태를 자동으로 정의

grid-auto-columns
grid-auto-rows

row 개수를 미리 알 수 없는 경우 grid-auto-rows를 사용한다.
그러면 굳이 횟수를 지정해서 반복할 필요 없이 “알아서” 처리된다.

.container {
	grid-auto-rows: minmax(100px, auto);
}

grid-template-rows로 미리 세팅해 둔 것이 없이 때문에 여기있는 모든 row들은 grid-template-rows의 통제를 벗어난 row가 되는 것이고, 바로 grid-auto-rows가 처리를 하는 것! “통제를 벗어난”의 의미는 바로 이것이다.

💡 각 셀의 영역 지정

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


1부터 4까지의 Grid 라인 번호가 매겨져 있는데, 바로 그 번호를 이용해서 column과 row의 범위를 결정한다.

column으로 살펴보면, grid-column-start가 시작 번호, grid-column-end가 끝 번호이다. grid-column은 start와 end 속성을 한번에 쓰는 축약형이다.

위의 빨간색 영역을 코드로 쓰면 아래와 같다.

.item:nth-child(1) {
	grid-column-start: 1;
	grid-column-end: 3;
	grid-row-start: 1;
	grid-row-end: 2;
}

위와 아래는 동일함.

.item:nth-child(1) {
	grid-column: 1 / 3;
	grid-row: 1 / 2;
} 

시작번호 / 끝번호를 지정하는 방법 외에, 몇 개의 셀을 차지하게 할 것인지를 지정해줄 수도 있다.

.item:nth-child(1) {
	/* 1번 라인에서 2칸 */
	grid-column: 1 / span 2;
	/* 1번 라인에서 3칸 */
	grid-row: 1 / span 3;
}

grid-auto-columns는 grid-template-columns의 통제를 받지 않는 column들의 배치를 결정하는 규칙이라고 했는데, 이 grid-column을 이용해 ‘통제받지 않는’ column들을 만들 수 있다.

.container {
	grid-template-columns: 50px;
	grid-auto-columns: 1fr 2fr;
}
.item:nth-child(1) { grid-column: 2; }
.item:nth-child(2) { grid-column: 3; }
.item:nth-child(3) { grid-column: 4; }
.item:nth-child(4) { grid-column: 5; }
.item:nth-child(5) { grid-column: 6; }
.item:nth-child(6) { grid-column: 7; }
/* end를 생략하면 그냥 한 칸임 */

이렇게 하면, 첫번째 column(G)만 grid-template-columns의 통제를 받아 50px로 되고, 나머지 column들은 grid-auto-columns의 규칙에 따라 1:2의 비율이 반복된다.

💡 자기 자리 지키기

span이나 이런 것들을 하다보면 밀려나는 경우가 있다. 자리를 강제로 지키게끔 해주어야한다.

 .grid-item:nth-child(3){
            grid-column:3;
            grid-row: 2;
        }
        .grid-item:nth-child(4){
            grid-column:3;
            grid-row: 2 / span 3;
        }

서로 영향을 받는 아이들끼리 강제로 자리를 위치시켜야한다.

💡 영역 이름으로 그리드 정의 (grid-template-areas)

각 영역(Grid Area)에 이름을 붙이고, 그 이름을 이용해서 배치하는 방법

.container {
	grid-template-areas:
		"header header header"
		"   a    main    b   "
		"   .     .      .   "
		"footer footer footer";
}

위의 형태로 각자 차지하는 셀의 개수만큼 해당 위치에 이름을 써주면 된다.
각 셀마다 공백을 하나씩 넣어서 구분해주면 된다.
header는 첫번째 row에서 3개의 column을 차지하니 맨 위에 3번 쓴 것!
빈칸은 마침표 또는 “none”을 사용하면 되고, 마침표의 개수는 여러개를 써도 상관없다.

각 영역의 이름은 해당 아이템 요소에 grid-area 속성으로 이름을 지정해주면 된다.

.header { grid-area: header; }
.sidebar-a { grid-area: a; }
.main-content { grid-area: main; }
.sidebar-b { grid-area: b; }
.footer { grid-area: footer; }

💡 자동 배치 (grid-auto-flow)

아이템이 자동 배치되는 흐름을 결정하는 속성

.container {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(25%, auto));
	grid-template-rows: repeat(5, minmax(50px,auto));
	grid-auto-flow: dense;
}
item:nth-child(2) { grid-column: auto / span 3; }
item:nth-child(5) { grid-column: auto / span 3; }
item:nth-child(7) { grid-column: auto / span 2; }

B, E, G는 각각 셀을 3개 또는 2개를 점유하도록 설정했는데, 그 때문에 셀에 들어갈 자리가 없어서 빈 셀들이 생겼다.
Grid 배치의 기본 설정은 아이템이 row를 기준으로 순서대로 배치가 되다가 들어갈 자리가 없으면 그 칸은 비워두고 아래로 배치가 된다.
dense는 기본적으로 빈 셀을 채우는 알고리즘이며, row와 column에 따라 기준이 달라진다.

💡 정렬

📝 세로 방향 정렬 (align-items)

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

각각의 셀이 세로축 안에서 위치가 조정된다. 기본값인 stretch는 컨테이너 높이에 따라서 알아서 늘어난다.

📝 가로 방향 정렬 (justify-items)

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

📝 place-items

.container {
	place-items: center start;
}

align-items와 justify-items를 같이 쓸 수 있는 단축 속성이에요.
align-items, justify-items의 순서로 작성하고, 하나의 값만 쓰면 두 속성 모두에 적용된다.

📝 아이템 그룹 세로 정렬 (align-content)

Grid 아이템들의 높이를 모두 합한 값이 Grid 컨테이너의 높이보다 작을 때 Grid 아이템들을 "통째로" 정렬한다.

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

📝 아이템 그룹 가로 정렬 (justify-content)

Grid 아이템들의 너비를 모두 합한 값이 Grid 컨테이너의 너비보다 작을 때 Grid 아이템들을 통째로 정렬한다.

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

📝 place-content

align-content와 justify-content를 같이 쓸 수 있는 단축 속성.
align-content, justify-content의 순서로 작성하고, 하나의 값만 쓰면 두 속성 모두에 적용된다.

.container {
	place-content: space-between center;
}

📝 개별 아이템 세로 정렬 (align-self)

해당 아이템을 세로(column축) 방향으로 정렬하고, 아이템에 적용한다.

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

📝 개별 아이템 가로 정렬 (justify-self)

해당 아이템을 가로(row축) 방향으로 정렬하고, 아이템에 적용한다.

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

📝 place-self

align-self와 justify-self를 같이 쓸 수 있는 단축 속성.
align-self, justify-self의 순서로 작성하고, 하나의 값만 쓰면 두 속성 모두에 적용된다.

.item {
	place-self: start center;
}

💡 배치순서 (order)

각 아이템들의 시각적 나열 순서를 결정하는 속성.
숫자값이 들어가며, 작은 숫자일 수록 먼저 배치됩니다. "시각적" 순서일 뿐, HTML 자체의 구조를 바꾸는 것은 아니므로 접근성 측면에서 사용에 주의해야한다.

.item:nth-child(1) { order: 3; } /* A */
.item:nth-child(2) { order: 1; } /* B */
.item:nth-child(3) { order: 2; } /* C */

💡 z-index

Z축 정렬을 할 수 있는데 숫자가 클 수록 위로 올라온다.
(position에서의 z-index랑 똑같이 생각하면 됨)
** z-index를 설정 안하면 0이므로, 1만 설정해도 나머지 아이템을 보다 위로 올라온다

💡 Tip

  • 미디어쿼리없이 반응형 : auto-fill
.card-list {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, auto));
	column-gap: 2%;
}

auto-fill을 이용하여서 minmax220px 로 두고 화면크기에 따라 알아서 채워지게끔 한다.

  • background이미지 화면창에 맞게 :
background: url(images/lego.png) no-repeat white;
background-position: calc(50% + 22vw) 0;
background-size: calc(300px + 40vw) auto;

최소 이미지의 크기는 300px이고 화면창에 따라 40vw가 추가적으로 더해질 수 있다.


Grid와 Flex의 차이

Flex 는 1차원 적인 부분만 고려한 레이아웃이다
Grid 는 2차원 적인 부분도 고려한 레이아웃이다.

Flex는 꼬치 처럼 한방향으로만 갈수있지만
Gird는 신문에 각 부분처럼 공간을 나눈다고 생각하면된다.

0개의 댓글

관련 채용 정보