위 내용을 개선해 볼 것이다.
named grid lines 1번, 2번, 3번 번호를 붙이지 않고
이제는 이름을 사용해볼 것이다.
.wrapper {
display: grid;
grid-template-columns: [main-start] 1fr [content-start] 1fr [content-end] 1fr [main-end];
grid-template-rows: [main-start] 100px [content-start] 100px [content-end] 100px [main-end];
}
1fr 1fr 1fr 하지말고 이름을 불러주자
1번 1fr : [main-start][content-start] 2번 1fr [content-end]
3번 1fr : [main-end]
이것이 line 기반에 name을 추가해서 사용하는 패턴이다.
grid에서 line 1번 시작하여 3번 끝난다는 것을 이제는 [main-start] 시작해서 [main-end]로 끝난다고 할 수 있다.
——
14-grid-linename
.container class를 선언할 것이다.
grid 작업을 하려면 마크업의 구조가 어떻게 되어 있는지 알고 진행해야 한다.
14-grid-linename은 마크업 구조가 너무 심플하다.
<마크업 구조 - 5개 그룹 선형화>
container 상자
|
|__ header 그룹
|
|__ navigation 그룹
|
|__ main 그룹
|
|__ sidebar 그룹
|
|____ footer 그룹
그리고 header ~ footer까지 모두 contatiner의 직계 자식이다.
flex와 동일하게 grid도 grid item이 되려면 grid container 안에 직계 자식 이어야 한다.
손자 레벨은 grid item이 아니다.
만약 손자 레벨을 grid item화 하고 싶다면 부모의 display를 content로 만들면 된다. (flex 시간에 배운 내용이 grid에 동일하게 적용된다.)
먼저 container 영역에 grid라고 선언해준다.
grid로 선언을 해줘야지만 이제부터 grid item으로서 역할을 갇게 된다.
.container {
display: grid;
}
개발자 도구 > layout 파트 >
그리고 grid-template-columns을 1fr 1fr 1fr로 지정한다.
repeat 함수를 사용하지 않고 각각의 크기
를 지정하였다.
여기서 가운데 8fr를 크게 지정하겠다.
이 경우 1/10(10%), 8/10(80%), 1/10(10%) 크기로 분배가 된다는 뜻이다.
.container {
display: grid;
grid-template-columns: 1fr 8fr 1fr;
}
이제는 1fr 앞에 [대괄호]를 추가하여 시작에[full-start], 끝에[full-end], 중간은 [content-start][content-end]으로 감싼다.
.container {
display: grid;
grid-template-columns: [full-start] 1fr [content-start] 8fr [content-end][full-end] 1fr;
}

그리고 생략해도 되는 내용이지만,
grid-auto-flow 또는 grid-auto-rows: auto;를 지정하여 자동으로 행을 만들 것이다.
저장하면 세 개의 column을 만들었기에 작은 영역, 넓은 영역, 작은 영역으로 배치가 되는 것을 볼 수 있다.
그리고 딱 픽스 되어있는 높이 vh가 grid에서는 독이 된다. (높이 없이 작업할 것)
vscode 단축코드
5개 코드를 한번에 지우는 shortcut : 앞에 한 단어를 command + D 하고, command + shift + L 하고 오른쪽 방향키 쓰면 여러줄을 한번에 지울 수 있다.
행(rows)도 line 이름을 지정할 수 있지만 우성 지정하지 않도록 한다.
.container {
display: grid;
grid-template-columns: [full-start] 1fr [content-start] 8fr [content-end][full-end] 1fr;
grid-template-rows: 1fr 8fr 1fr;
}

이제 .container 안에 .header를 배치할 것이다.
만약에 .header를 [full-start]부터 [full-end]까지 배치한다면 grid-column을 사용하는 것이 좋다.
grid-column mdn
https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column
- grid-column: 1 / 3;
첫 번째 그리드 라인에서 시작하여 세 번째 그리드 라인까지, 즉 두 개의 열을 차지하도록 설정.- grid-column: 1 / span 2;
현재 위치에서 두 개의 열을 차지.

여기서 grid-area를 써도 상관은 없다.
참고:
grid-area는 그리드 아이템의 행과 열 위치를 동시에 설정할 수 있어 편리하다.
그러나 단순히 열 위치만 지정하려면 grid-column을 사용하는 것이 더 간단할 수 있다.
line name으로 열 위치를 지정할 수 있다.
grid-column full-start / full-end; 지정하고 header가 전체 영역을 차지하는 것을 볼 수 있다.
.container {
display: grid;
grid-template-columns: [full-start] 1fr [content-start] 8fr [content-end][full-end] 1fr;
grid-template-rows: 1fr 8fr 1fr;
.header {
grid-column: full-start / full-end;
}
}

header 높이가 정확히 보이지 않아 .container에 최소 높이 값을 지정한다.
.container {
min-height: 100vh;
min-block-size: 100vh;
display: grid;
grid-template-columns: [full-start] 1fr [content-start] 8fr [content-end][full-end] 1fr;
grid-template-rows: 1fr 8fr 1fr;
.header {
grid-column: full-start / full-end;
}
}
min-height의 논리단위로 min-block-size를 들 수 있다.
높이 지정에 min-block-size를 추가하는 것 관련으로 '멋사 질의응답' 내용을 확인바란다.
https://www.notion.so/Grid-max-inline-size-1ad73873401a80e19c89c991e42f2cc8?pvs=4

부모가 높이를 가지고 있으면 그 안에서 행을 쪼개기 쉽기 떄문이다.
확실히 grid로만 사용하여 섹션별로 각 높이를 지정하는 것 보다 훨씬 편하다는 것을 알 수 있다.
그리고 .navigation에다가 grid-column을 지정하는데 단축으로 'full'만 작성하여도 적용이 된다는 것을 볼 수 있다.
.container {
min-height: 100vh;
min-block-size: 100vh;
display: grid;
grid-template-columns: [full-start] 1fr [content-start] 8fr [content-end][full-end] 1fr;
grid-template-rows: 1fr 8fr 1fr;
.header {
grid-column: full-start / full-end;
}
.navigation {
grid-column: full;
}
}

그리고 .container에 있는 grid-template-rows에 1fr를 추가하니 행이 하나 더 추가되어 navigation 원하는 대로 렌더링 되는 것을 볼 수 있다.
.container {
min-height: 100vh;
min-block-size: 100vh;
display: grid;
grid-template-columns: [full-start] 1fr [content-start] 8fr [content-end][full-end] 1fr;
grid-template-rows: 1fr 1fr 8fr 1fr;
.header {
grid-column: full-start / full-end;
}
.navigation {
grid-column: full;
}
}

이번에는 .main이 [content-start][content-end] 영역이니까 단축해서 'content'라고만 입력 하겠다.
.container {
min-height: 100vh;
min-block-size: 100vh;
display: grid;
grid-template-columns: [full-start] 1fr [content-start] 8fr [content-end][full-end] 1fr;
grid-template-rows: 1fr 1fr 8fr 1fr;
.header {
grid-column: full-start / full-end;
}
.navigation {
grid-column: full;
}
.main {
grid-column: content;
}
}

이어서 sidebar영역과 footer에도 각각 content, full을 지정 해준다.

만약 sidebar의 위치를 main의 좌측에 배치하고 싶다면 아래와 같이 지정 해주면 된다.
.sidebar {
grid-column: 1 / 2;
grid-row: 3 / 4;
}
또는 .container 영역에 grid-auto-flow: dense;
를 지정하여도 동일한 결과가 나온다.
grid-auto-flow: dense 관련 mdn
https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow
dense는 main 다음 마크업 순서로 sidebar가 나오더라도 내 앞에 비어있는 셀(grid area)가 있을 경우,
거기부터 밀집하여 채우는 기능이다.

하지만 현재 row 방식으로 쌓여서 작업되는 상황이고, 마크업 순서대로 레이아웃이 설정되어 있기 때문에 위 순서로 오지 않는다.
또 다른 상황으로 가보자.
이름이 반듯이 하나만 있을 필요가 없다는 것이다.
.container 영역에서 [content-start]에 [content-start like-start], [content-end]에 [content-end like-end]로 작성할 수 있다는 것이다.
grid-template-columns: [full-start] 1fr [content-start like-start] 8fr [content-end like-end] 1fr [full-end];

즉, line에 이름을 지어주고 그 이름을 레이아웃에 활용하는 패턴이다.
이름을 활용하는 패턴은 아래 상황에 사용하기 좋다.
아래 navigation 영역은 12 column 안에 배치되어 있지만 배경 색깔은 바깥까지 연장된 느낌이다.
이렇게 만들려면 전체 크기를 차지하기 위한 full-start, full-end를 만들고
그 안에 실제 컨텐츠가 배치되는 content-start, content-end를 따로 주는 것이다.
즉 배경이 있는 container는 full 위치, 실제 내용이 있는 영역은 content 위치로 지정할 수 있는 것이다.
여기서 더 나아가서 content를 12 column으로 조각조각 나누어 원하는 위치에 배치할 수도 있다.

보편적으로 content가 배치되는 영역은 늘 늘어나지 않고 굉장히 제한적이다.
모니터 해상도가 커지면 대부분 왼쪽/오른쪽을 여백으로 비워 놓는다.
과거의 많은 트릭
전통적인 방법으로는 margin: 0 auto; 처리하는데
이 경우 문제점은 배경색이 auto margin까지 연장되어야 한다.
마치 상자의 시작 점이 왼쪽, 오른쪽 비워있는 공간을 것처럼 보이도록 트릭으로 음수 margin을 사용하거나
viewport 단위로 position에 해당 크기만큼 움직이는 방법 등이 있다.
grid line 기반을 활용하면 더 편하게 사용할 수 있다.
12 column이 있다는 가정으로 예제를 만들어 보자.
.container의 grid-template-column 다시 작성해보자.
1fr의 크기를 조정해보자.
grid에서 많이 쓰이는 #minmax 함수를 추가 해본다.
유동적인 너비로 지나치게 작아지거나 커지는 점을 방지하고자 사용한다.
#최소최대 크기를 지정하는데 정말 많이 사용한다.
.container {
min-height: 100vh;
min-block-size: 100vh;
display: grid;
grid-template-columns: [full-start] minmax(1rem, 1fr) [content-start] 8fr [content-end][full-end] minmax(1rem, 1fr);
grid-template-rows: 1fr 1fr 8fr 1fr 1fr;
minmax(1rem, 1fr)
제일 작아도 16px, 그리고 필요할 경우 flexable하게 넑어질 수 있도록 fr 단위를 설정.
최소 1rem, 최대 1fr(남은 공간을 나눠 가짐).
grid 계산기
http://gridcalculator.dk/
실제 content가 배치된 영역의 크기를 1280px로 지정한다.
Gutter,Margin을 Gap이라고 불리운다.
Gap까지 포함했을 때
전체 너비에서 column이 가지고 있는 개수 (4개)의
행과 열 사이에 있는 Gutter 20 3과
양 사이드 Margin 20 2를 뺀 나머지 셀 영역이 각각 295px로 나오는 것을 볼 수 있다.
만약 column이 12개가 있다면 셀이 85px이 나오고
이 값을 grid-template-columns: [full-start] minmax(1rem, 1fr) [content-start] 8fr [content-end] [full-end] minmax(1rem, 1fr);
에
1fr 대신 적을 수 있다는 것이다.


어제 배운 반복하는 repeat() 함수를 8fr
위치를 대체한다면
repeat( , ) 함수의 첫 번째 인자 값 : column의 개수 - 12개 column
두 번째 인자 값 : 1fr
즉, 해당 영역에 1fr이 12번 선언된 것과 동일한 효과를 볼 수 있다.
.container {
min-height: 100vh;
min-block-size: 100vh;
display: grid;
grid-template-columns: [full-start] minmax(1rem, 1fr) [content-start] repeat(12, 1fr) [content-end][full-end] minmax(1rem, 1fr);
grid-template-rows: 1fr 1fr 8fr 1fr 1fr;

여기에서 1fr을 다시 minmax() 함수로 바꾸면
minmax(85px, 1fr)
그리고 85px을 rem 단위로 환산하면 5.3125rem 이다.
minmax( 최소, 최대 ) 크기 지정
리밋을 걸어준 것 밖에 차이가 없다.
차분히 이해하면 된다.

같은 방법으로 11:55
그 이하는 작아지지 않고 커지기만 한다.
minmax (5.3125rem) 이 부분은 강사님이 다시 테스트 해볼 것이다.
전체적인 레이아웃 설계할 때 도움이 된다.

만약 아래 이미지처럼 navigation 영역을 grid line으로 만든다면
content 내용은 navigation 12 column안에 배치되어 있게 되는 것이고
그렇게 되면 wrapping이 두 번 필요하다.
full 영역 한번, navigation 배치될 영역 한 번

이렇게 된 김에 navigation 마크업을 수정해보자.
emmit 명령 : ul.menu>(li>a{Menu $})*4 css 코드를 이어서 수정 해보자.
.menu 영역을 식별하기 위해 배경 색상을 지정하고 #subgrid 개념을 활용해 보겠다.
여기서 ul은 손자 레벨이고 직계 자식이 아니기때문에 grid에 배치된 것이 아니다.
이 때 .menu의 부모 요소에 display: contents;를 주어 .menu가 navigation의 직계 자손이 되도록 하는 것이다.


문제는 현재 navigation은 뷰포트 크기로 가야 하는데 grid content 영역에 멈춰 있다.
결국 navigation도 전체 .container의 item이 되어야 하는 상황이다.
방법은 navigation에 diaplay: grid;를 주고 .container에 작성했던 grid-template-columns: 값을 그대로 가져와서 지정하는 것이다.
이렇게 하면 navigation 자체가 grid-container가 되고 그 안에서 다시 template를 갖게 된다.
(변경전)

(변경후)

여기서 navigation은 부모가 가진 template를 full 사이즈로 그대로 반복하게 되는데
추가로 main이나 sidebar 같은 하위 요소가 해당 template를 가져다 쓰게된다면 full 사이즈가 아닌 겹쳐서 grid 셀 안에 grid 형식으로 문제가 생길 수 있다.
해당 문제 없이 template를 가져오는 속성이 subgrid를 사용하는 것이다.

추가로 여기에 grid-template-rows : subgrid가 있다면 rows 배치할 때 부모 contatiner에 대당하는 grid-template-rows에 의거해 배치가 가능하다.
조부모는 불가능하고, 직계 자식만 가능하다. 부모 정보를 고대로 가져오면 또 안에 grid를 생성해서 아래처럼 이상하게 보인다.


sub grid 안에 sub grid가 또 지정이 가능할지?
subgrid 와 inherit 의 차이에 대한 아티클