Web 표준은 html로 웹사이트 틀을 만들고, Css로 꾸며주고, Javascript로 동작시키는데..
이것들은 각각 분리하여 작성되어야 나중에라도, 누구라도,, 알아보기 쉽고 유지 관리에도 도움이 된다!
░
우선.. 이 Web 코딩 강좌는 html 5와 Css 3, Bootstrap 5에 의거하여(추가적으로, 약간의 자바스크립트 코드도 가미하고, 외부 플러그인 라이브러리들도 좀 써서) 작성되었음을 알리며 문을 엽니다
- 곧, 이 웹사이트의 모든 모양과 움직임, 다양한 효과 등은 다 그 자체로 이 강좌에 나오는 내용들을 바탕으로 해서 작성된 것입니다!
░박스모델 개념에 대한 이해와 블록레벨 요소 대 인라인 요소의 분간은 Web 코딩의 가장 중요한 시작점이니
꼭! 꼭!! 씹어가며 찬찬히 살펴보십시오..
웹문서의 일반 흐름
1.
웹문서의 일반 흐름 flow layout 은 페이지 레이아웃이 전혀 적용되지 않은,
곧 브라우저가 기본값으로 웹문서의 요소들을 배치하는 것인데..
블록레벨 요소는 블록 방향(가로쓰기 모드라면; 수직 방향, 세로쓰기 모드라면; 수평 방향)으로 확장되면서 배치되고,
블록레벨 요소 내부 컨텐츠가 흘러가는 방향(가로쓰기 모드의 가로방향, 또는 세로쓰기 모드의 세로방향)이
바로 인라인 방향이 된다
블록레벨 요소(예컨대, 이 문단 전체)는 부모요소의 너비 100%와
자체 내용물의 최대 높이를 차지하며,
인라인 요소(예컨대, 이 문단 내의 각 단어들)는
자체 내용물의 최대 높이와 최대 너비를 차지하게 된다:
(! 위 html 예제 코드에서 <p> 요소의 Css 설정(class="divspan_ex")을 없애주면 어떤 모습이 될까요?)
인라인 요소 옆에서
자신의 본 모습을 되찾은 블록레벨 요소
입니다 ^^
←이것이 바로 순수 html 문서의 민낯, 즉 '일반 흐름'입니다!
2.
각 블록레벨 요소는 (가로쓰기 모드에서)위쪽 블록레벨 요소 아래 새 줄로 내려가 수직 방향으로 배치되며,
각 블록레벨 요소에 주어진 마진에 의해 서로 분리된다(이 마진은 큰 쪽에 의해 작은쪽이 접혀진다!).
반면, 인라인 요소는 (블록레벨 부모요소의 너비 내에서)다른 인라인 요소와 같은 라인에 차례로 자리잡되,
부모요소의 너비가 부족해지면; 나머지는 아래로 내려가게 된다.
하지만, 인라인 요소에 display: block; 속성값을 주면; 온전히 블록레벨 요소의 특성을 갖게 된다:
3.
인라인 요소에서 너비나 높이를 설정할 수는 없다. 인라인 요소의 크기를 제어하려면;
display: block;이나 display: inline-block; 속성을 주어야 한다.
예컨대, 인라인 요소에 display: inline-block; 속성값을 주면;
일부 블록레벨 요소의 특성을 갖게 되지만, 여전히 텍스트와 함께 인라인으로 흐르게 된다:
한 단락 내부에 인라인 요소인 스판 영역이 있는데,
이 인라인 요소에 display: inline-block; 속성을 주니 블록레벨 요소에서만 작동하는
width, margin과 padding 및 text-align 속성이 작동하는군요..
░화면 배치 방법을 바꿔줌으로써 블록레벨 요소 대 인라인 요소 사이의 전환이 가능한데..
단, 이는 태그의 성격 자체가 바뀌는 것은 아니고, 단지 디자인적 꾸밈새만 바뀔 뿐이다:
예컨대, 기본적으로 세로로 배치되는 li 리스트를 가로 내비게이션으로 바꿀 때나
한 줄로 표시되는 이미지에 여백과 테두리를 추가해 갤러리로 표시할 때,
Pc에서는 표시하되 Mobile에서는 없애고자 할 때 등에 이 display 속성이 사용된다!
Display 속성
웹문서의 일반 흐름에서 display 속성으로 화면 배치 방법을 바꾸어주면;
블록레벨 요소 대 인라인 요소 사이의 전환이 가능한데,
display: none;은 요소를 화면에서 감추고 차지하던 공간도 삭제한다.
display: block;은 인라인 요소를 블록레벨 요소로 배치하며(또는, none 속성을 주었던 요소를 다시 불러낸다),
display: inline;은 반대로 블록레벨 요소를 인라인으로 배치한다.
한편, display: inline-block;은 블록레벨 요소를 인라인으로 배치하되,
블록레벨 속성을 사용할 수 있도록 한다.
또는, 인라인 요소에서 블록레벨 속성을 사용할 수 있도록 한다
1.display 속성은 외부적으로는 요소가 블록 또는 인라인 박스로 처리되는지 여부(곧, 요소의 흐름 레이아웃)을,
내부적으로는 (플렉스 박스, 그리드 레이아웃 등에서)자식요소의 레이아웃을 설정한다
- 곧, 외부 타입은 흐름 레이아웃에 대한 요소의 참여 여부를 설정하며, 내부 타입은 자식요소의 레이아웃을 설정하는 것이다:
display: block flow;← 이 코드는 최근의 다중 키워드 구문인데,
앞 block 은 요소 자신의 흐름 레이아웃을, 뒤 flow 는 내부 자식요소의 레이아웃을 가리킨다!
[ 다중 키워드 구문 ]
/* 외부값 설정: 흐름 레이아웃에서의 요소의 표시 유형 지정 */
display: block [flow]; /* display: block flow; ← 다중 키워드 표기방식 */
display: inline [flow]; /* display: inline flow; ← 다중 키워드 표기방식 */
/* 내부값 설정: 요소 내부에서 컨텐츠가 배치되는 서식 컨텍스트 유형 정의 */
display: [block] flex; /* display: block flex; */
display: [block] grid; /* display: block grid; */
/* inline-내부값 설정 */
display: inline-flex; /* display: inline flex; */
display: inline-grid; /* display: inline grid; */
☞
다중 키워드 구문을 지원하는 브라우저에서 외부값이 지정되지 않으면; block이,
내부값이 지정되지 않으면; flow가 기본값이 된다
- 곧, 특정 요소에 display: flex; 값을 주면; 이 요소는 블록레벨 플렉스 박스로 바뀌고,
자식요소들은 플렉스 항목으로 작동하게 되어 흐름, 정렬을 제어하는 가변형 속성을 사용할 수 있게 되는 것이다!
2.
기본적으로 모든 요소는 흐름 레이아웃을 사용하여 블록 및 인라인 박스에 컨텐츠를 배치하는데,
position, overflow 등의 속성 설정에 따라,
또는 자체적으로 블록 또는 인라인 컨텍스트에 참여하는지 여부에 따라
해당 컨텐츠에 대한 새 블록 컨텍스트를 설정하거나 해당 컨텐츠를 부모 컨텍스트에 통합하거나 하게 된다.
곧, flow-root 요소는 새로운 블록 서식 컨텍스트를 설정하는 블록 박스를 생성하여 서식 루트가 있는 위치를 정의하는 것이다:
[ flow-root 설정 ]
/* flow-root 설정: 블록 컨텍스트 박스를 생성하여 서식루트가 있는 위치를 정의한다 */
display: block flow-root;
display: inline flow-root;
display: inline-block; /* display: inline flow-root ← 주변 컨텐츠와 함께 흐르는 블록 박스를 생성한다 */
3.
Css의 visibility 속성은 요소를 화면에서 감추거나 드러낼 때 사용하는데(기본값: visible),
visibility: hidden;은 요소를 화면에서 감추되, 그 영역은 여전히 차지한다
←
반면, display: none;은 화면에서 요소를 감추는 동시에 요소가 차지하던 공간도 완전히 해제한다!
visibility: hidden;
display: none;
➥
요소에 display: none;으로 설정하면 접근성 트리에서 제거되고, 스크린리더기 등에서도 접근하지 않는다.
하지만, 숨겨져 있지만 보이는 요소의 aria-describedby나 aria-labelledby 속성으로 참조되는 요소는 보조기술에 노출된다
←
관련 접근성 문제는, 더 필요하시면;
WebAIM
문서를 참조하십시오..
Css 박스모델
░
Css로 작성하는 모든 것은 박스 Box 이다!
브라우저의 렌더링 엔진은 Css 기본 박스모델에 따라 각각의 요소를 사각형 박스로 표현하고,
Css는 박스의 크기와 위치, 속성(색, 배경, 테두리 모양 등)을 결정한다!
박스모델 개념
Contents를 둘러싼 패딩 padding과 테두리 border,
주변 박스와의 간격인 마진 margin(모두, 각각 4방향으로 설정 가능하다)에서
인라인 요소는 해당 컨텐츠만큼의 영역만을 차지하면서 수평 방향으로 컨텐츠가 배치된다.
너비 width나 높이 height 설정은 할 수 없으며,
좌 left, 우 right 방향으로 공간을 줄 수 있으나
상 top, 하 bottom 방향으로는 공간을 설정할 수 없다
←
참고로, 인라인 요소의 높이는 기본적으로 line-height 값에 의해 결정된다!
반면, 블록레벨 요소는 (부모 요소의 너비 내에서)한줄 전체를 차지하는 박스 형태가 되어,
내용물이 늘어나면 아래 방향으로 컨텐츠를 쌓아나간다. 너비가 100%이므로 좌/우에 다른 요소가 올 수 없으며,
4방향으로 width나 height, padding 및 margin 설정이 가능하다.
한편, <a>, <button>, <img>, <video> 등의 인라인-블록레벨 요소는
(줄 바꿈 되지 않는)인라인 특성을 지니면서도
블록 특성인 width나 height, 상/하 margin 및 padding 설정이 가능하다!
컨텐츠 박스에는 글이나 이미지 등 요소의 실제 내용이 들어간다.
그 크기는 너비(width)와 높이(height)로 표현되며, 배경색과 배경 이미지를 가질 수 있다.
컨텐츠 박스의 쿠션 역할을 하는 패딩(padding) 영역 바깥의
테두리(border)는 박스의 경계선이며, 이는 가시 영역의 한계점이 된다:
[ 박스모델 개념 ]
Border(테두리) 박스
Padding(여백) 박스
Contents(내용) 박스
Margin(= 박스간 간격)
Border(테두리) 박스
Padding(여백) 박스
Contents(내용) 박스
* cf)
이 외곽 점선 및 박스 그림자는 박스 테두리와는 달리,
박스모델과는 전혀 무관한 (공간을 차지하지 않으면서, 단지 시각적 표시만 해주는)효과 처리일 뿐이다!
➥컨텐츠와 패딩, 테두리에는 배경 이미지를 지정할 수 있지만(곧, 컨텐츠와 패딩, 테두리는 블록레벨 요소의 영역에 속한다),
마진은 단지 박스간 간격을 제어할 뿐이기에 배경 이미지가 적용되지 않는다(곧, 마진은 박스에 포함되지 않는다!).
한편, 외곽선(outline) 및 그림자(box-shadow)는
박스 테두리 바깥 마진 공간에서 덧칠되므로 역시 박스의 크기에는 전혀 영향을 미치지 않는다!
박스 사이징
블록레벨 박스의 실제 크기는 width 및 height로 주어진
컨텐츠 영역의 크기에다 각 방향별 padding 및 border 값이 더해지는데,
Css 스타일 설정에서 box-sizing: border-box; 속성값을 주면;
컨텐츠 영역에다 패딩과 테두리까지 합친 박스의 실제 크기로 width, height 값이 재설정된다:
box-sizing: content-box; (기본값)
실제로는; 박스 크기가 늘어남: 컨텐츠 영역(곧, 박스의 원래 크기 400px) + 패딩(20x2) + 테두리(20x2) = 480px
box-sizing: border-box;
주어진 width 값(400)에서 패딩과 테두리를 뺀 값으로 컨텐츠 영역이 줄어들어 주어진 width 값(= 400px)이 유지됨!
.div_ex00 {
width: 400px; margin: 20px; padding: 20px;
border: 20px dotted gainsboro;
}
.div_ex00:first-of-type {
background-color:yellowgreen;
/* 이 부분은 Css 기본값이므로, 순수 html 문서에서는 적을 필요가 없다 */
box-sizing: content-box;
}
.div_ex00:last-of-type {
background-color: blanchedalmond;
/* 부트스트랩에서라면; border-box가 기본값으로 재정의되어 있으므로, 실제로 적을 필요는 없다! */
box-sizing: border-box;
}
☞
곧, box-sizing: border-box; 속성값을 주지 않는 경우라면;
패딩과 테두리값을 더한 크기로(미리 계산하여) width,
height 값을 지정해주어야만 레이아웃이 넘쳐나는 것을 막을 수 있다!
➥
현재 웹문서 내 모든 요소에 box-sizing: border-box; 속성을 적용하고자 한다면;
아래와 같이 설정해주면 된다.
하지만, 이미 부트스트랩 등 대다수의 플랫폼들에서는 패딩이나 테두리로 인해 박스의 너비가 변하는 것을 방지하기 위해,
자체 규격으로 이 값을 border-box로 재설정하여 사용하는 것이 보통이다:
☞
이렇게 하면 여백이 요소의 최종 계산된 너비에 영향을 미치지 않도록 보장하지만,
드물게 구글 맵 등에서 문제가 발생할 경우가 있는데, 그런 경우에는 해당 요소에서 다음과 같이 재정의해줄 수 있다:
.googlemap-widget { box-sizing: content-box; }
가변 박스
░
예컨대, <img> 요소는 그 이미지 파일 고유의 너비와 높이를 갖고 있고,
(따로 크기를 정해주지 않은 한)그 크기대로 웹문서에 나타난다.
또한, 빈 <div> 요소는 (블록레벨 요소이기에)전체 너비를 차지하지만, 높이는 제로이다
- 여기에 텍스트 등 컨텐츠가 들어가야 비로소 그 크기가 결정되는 것이다!
오버플로와 가변 박스
블록레벨 요소에 너비 및 높이 를 설정해주면;
(그 안에 어떤 내용이 들어가든 간에)박스의 크기가 고정된다.
따라서, 내부 컨텐츠가 박스 크기보다 커지면; 오버플로 overflow가 발생하게 된다!
1.
박스는 display 속성, 지정된 크기 및 내부 컨텐츠의 양에 따라 다르게 동작하여 레이아웃에 영향을 미치게 된다.
이에, 외부 크기 조정을 사용하여 이를 제어하거나 내부 크기 조정을 사용하여 컨텐츠 크기를 기반으로 브라우저가 결정하도록 할 수도 있다.
우선, 박스가 외부 크기 조정을 사용할 때, 박스 범위에서 추가할 수 있는 컨텐츠의 양에는 제한이 있음에 유의해야 한다.
이는 아래 "Css is awesome!"이라는 문장을 넘치게 만든다:
Css is awesome!
.box { /* box의 외부적 크기 설정: */
width: 300px; // 이것이 내부 자식요소 컨텐츠의 크기를 제한한다 ← 넘치면; 오버플로가 발생한다!
}
☞
이렇게 오버플로되는 현상을 방지하는 방법 중 하나가, 위와 같이 외부적 크기 지정인 width 값을
min-content 로 주어 내부 컨텐츠의 양에 따라 박스 크기가 신축적으로 변경되도록 해주는 것이다:
.box { width: min-content; }
.box-demo { width: 430px; height: 230px; } /* 기본 설정된 외부 크기 */
.box-demo[data-sizing="intrinsic"] { /* 토글 버튼이 눌리면; */
width: max-content; height: max-content; /* 내부 컨텐츠 양에 따라 박스가 늘어난다! */
}
.box-layout {
display: grid; grid-template-columns: 1fr min-content; gap: 0.5rem;
width: max-content;
}
☞
박스에 외부 크기가 주어져 있지만, 내부 크기 조정을 통해 컨텐츠(와 박스)를 더 많이 제어할 수 있다.
곧, 이 요소가 외부 크기 조정을 사용하는 경우 요소의 경계를 오버플로하기 전까지 추가할 수 있는 콘텐츠의 양에 제한이 있지만,
내부 크기 조정 토글이 켜져 있는 경우에는 그렇지 않다(곧, 내부 컨텐츠를 오버플로 없이 채울 수 있도록 박스가 커진다!)
2.
박스의 크기를 고정할 때, 안의 컨텐츠에 의해 오버플로가 일어나는 문제를 피하려면;
min|max-width/height: 값; 속성으로 컨텐츠 영역의 최소|최대 크기를 추가적으로 설정하여
컨텐츠의 양에 따라 신축적으로 박스의 너비/높이가 늘어나고 줄어들도록 해줄 수 있다.
이는 또한 화면의 크기 변화에 따라 이미지가 잘리거나 퍼지는 문제를 제거하고자할 때에도 이용된다!
➥
스타일시트에서 body { width: 960px; margin: 0 auto; }와 같이 설정해주면;
해당 박스(여기서는, 웹문서 전체)는 브라우저 크기에 맞추어 가변적인 크기로 항시 중앙에 위치하게 되는데,
브라우저가 박스 크기보다 작아지는 경우에 대비하고자 한다면;
max-width: 960px; 식으로 스타일을 추가하여
스크롤바가 생기는 대신 컨텐츠가 밑으로 내려가도록 해주면 된다!
➥ 가변 이미지
이미지 등의 멀티미디어 요소들은 너비와 높이 값을 지정하지 않은 경우 기본적으로 원본 크기대로 삽입된다.
곧, 브라우저 창의 크기가 변할 때도 이미지의 너비는 바뀌지 않으므로
브라우저 크기를 줄이면 이미지의 일부가 잘리고, 늘리면 화질이 저하된다!
이에 width: 100%;로 주면; 화면 너비에 맞추어 늘어나거나 줄어들지만,
원래 크기 이상으로 늘어나면 이 또한 화질이 저하된다!
이에 이미지를 감싸고 있는 부모 요소만큼만 커지거나 작아지도록 max-width: 100%;로 지정해주는 것이 바로 가변 이미지이다:
☞
가변 이미지는 height에 auto 값을 주어 너비에 따라 높이가 자동 조절되도록 해주는 것이 좋다.
나아가, min-width 속성으로 축소되는 너비 값을 제한해줄 수도 있다!
간격: 마진과 패딩
░
html은 기본적으로 자체 규격을 통해 블록 요소간 일정한 간격을 설정해준다. 예컨대, <br>은 자동으로 다음 줄로 내려가고,
<hr>은 (선을 그어주는 것만이 아니라)블록 방향으로 주변 요소와 일정한 간격(마진)도 준다.
<p>, <h1> 등의 블록레벨 요소들은 모두 주변 요소와의 사이에 기본값으로 설정된 마진 간격이 존재한다!
마진과 패딩
마진(margin: 값;)은 해당 태그 테두리의 바깥쪽 빈 공간,
곧 주변 요소들 테두리와의 간격이고(음수도 가능하다!),
패딩(padding: 값;)은 해당 태그의 내부 빈 공간 곧 컨텐츠와 테두리 사이의 여백이다
←
예컨대, 메뉴로 사용된 <li>(와 <a> 조합)에서 어느 범위까지를 클릭 영역으로 할지, 어디까지의 색상을 달리할지 등
그때, 그때의 상황에 따라 margin을 사용할 지 padding을 사용할 지가 선택된다!
✓
각 방향별 마진/패딩: margin|padding-top/right/bottom/left←
논리적 속성 또한 쓸 수 있다:
margin|padding-block-start/inline-end/block-end/inline-start
➥값 은 12시 방향부터 출발하여 상 우 하 좌, 상 좌우 하, 상하 좌우 식으로 줄 수 있고,
값의 단위는 px(= 절대 크기), %(= 부모 요소에 대한 비율),
em(= 부모요소 기준) 및 rem(= body 기준) 등을 쓸 수 있으며,
auto (기본값)는 남는 공간 모두를 차지하면서 적절하게 자동 배치된다(예컨대, Flex 박스에서의 자동 마진)
1.
문단 내 텍스트의 중앙 정렬에는 text-align: center; 속성이 사용되지만,
레이아웃 요소의 중앙 정렬에서는 Css의 margin 속성을 사용한다:
박스의 마진 값을 max-width: 600px; margin: 0 auto;와 같이 지정해주면;
해당 박스는 브라우저 크기에 맞추어 가변적인 크기로 항시 중앙에 위치하게 된다(= 화면 정중앙 가변 레이아웃)
☞
위 코드의 <div> 박스는 최대 크기 600px (max-width: 600px;), 상하 마진 0 & 좌우 마진 auto
(margin: 0 auto;)로 되어 화면의 가로 정 중앙에 위치하게 된다!
➥
박스는 가변적이되 그에 무관하게 마진이나 패딩은 고정되어 있도록 하고자 한다면;
Css의 calc(); 함수를 사용할 수도 있다:
div { margin: calc(100% - 25px) calc(100% - 100px); }←
박스 상하쪽으로 25px 만큼씩의 여백을 주고, 좌우쪽으로 100px 만큼씩의 여백을 준다!
2.margin 속성에서는 음수 값도 쓸 수 있기에,
이를 이용하면 하나의 박스에서 다른 박스 영역까지 침범하여 겹쳐 쌓는 것(= 음수 마진)이 가능해진다:
음~ 이넘이 건방지게 지 부모 품을 벗어나 위쪽으로 빠져 나갔군요..
부모 박스
3.마진 병합 마진 축소 현상은 인접한 두 요소의 마진 중 가장 큰 값을 선택하는 방식으로 작동한다.
예컨대, 아래 예제에서 p1(margin-bottom: 2rem;)과
p2(margin-top: 4rem;) 사이는 큰 마진 하나로 축소되어
6rem(위/아래 합계: 2rem + 4rem)이 아닌 4rem(큰거 하나: 4rem)의 간격이 된다:
p1. 상하 마진 2rem
p2. 위쪽 마진 4rem, 아래 마진 2rem
컨테이닝 블록
░
요소의 크기와 위치는 컨테이닝 블록의 영향을 받는 경우가 많다.
예컨대, %를 사용한 width 및 height, padding과 margin 값,
absolute 및 fixed 로 설정된 요소에서의 오프셋 값들은 자신의 컨테이닝 블록을 기준으로 하여 계산되는데,
이 컨테이닝 블록은 position 속성의 값에 따라 극명하게 달라지게 된다!
컨테이닝 블록
position이 static(기본값), relative, sticky 중 하나이면,
컨테이닝 블록은 가장 가까운 부모요소(inline-block, block, list-item 요소),
또는 가장 가까우면서 서식 맥락을 형성하는 조상요소(table, flex, grid, 혹은 블록 컨테이너 자기 자신)의 컨텐츠 영역 경계를 따라 형성된다:
☞
위 코드에서, position: absolute;로 지정된 자식 div 요소들의 좌표는
position: relative;로 지정되어 있는 부모 div 요소의 좌상단 꼭지점을 기준으로 한다
←
곧, position: absolute;로 지정된 요소는 가장 가까운
(fixed, absolute, relative, sticky로 설정된)부모요소를 자신의 컨테이닝 블록으로 하게 된다!
Css 포지셔닝
░
대부분의 경우, 어떤 요소의 컨테이닝 블록은 가장 가까운 블록레벨 부모요소의 컨텐츠 영역이 되지만,
반드시 그런 것만은 아니다.
예컨대, Css 포지셔닝을 사용하면 요소가 문서의 일반 흐름에서 동작하는 방식과 다른 관계를 설정할 수 있게 된다
- 곧, 특정 요소에 position 속성을 써서 문서의 일반 흐름에서 벗어난 다른 위치로 이동시킬 수 있는 것이다!
포지셔닝
기본적으로 박스는 문서의 흐름 순서대로 배치되는데(기본값인 position: static;),
박스간 마진병합 현상이 일어난다
←
여기서 좌표값은 사용할 수 없고, 플로팅에 의한 좌우 배치만 가능하다!
* 우선, 이 예제를 통해 포지셔닝 개념에 대한 개괄적 감을 잡아보십시오..
(초기 모습은 기본값인 Static 상태입니다)
Relative와 Absolute에 관해서는 밑에서 참조하십시오..
여기 있지롱 ~
☞
참고로, 위 옵션 중 Fixed의 모습은 화면 우측 상단에서 찾아보시고(스크롤해도 그 자리에 고정됨),
Sticky는 (처음엔 초기 모습과 같지만)화면을 스크롤하면 작동됩니다!
1.position: relative;는 문서의 일반 흐름대로 배치하되,
좌표값을 써서 일반 흐름상의 원래 위치로부터 (요소 자신을)상대적으로
(양수는 오른쪽 및 아래쪽 방향으로, 음수는 그 반대 방향으로)이동시키고,
다른 요소와 겹치도록 만들 수 있다:
p 1)
p 2) position: relative; top:30px; left:30px;
☞position: relative; top: 30px; left: 30px;는
(요소 자체가 윈래 나타나야 할 위치에서 상대적으로)위로부터 30px,
좌측으로부터 30px 떨어져서 배치된다
2.position: absolute;는 요소를 문서의 기본 흐름에서 벗어나
(가장 가까운 부모요소의 좌상단을 기준으로 하는)좌표값을 써서 배치하며,
해당 요소를 둘러싼 모든 컨텐츠는 재배치되어 해당 요소가 남긴 나머지 공간을 채우게 된다:
<h5>
position: absolute;는 요소를 문서의 기본 흐름에서 벗어나
(가장 가까운 부모요소의 좌상단을 기준으로 하는)좌표값을 써서 배치한다.
이때, 상위 부모요소에서 position: relative;로 설정해주면;
그 부모요소를 기준으로 하는 절대 위치에 자리잡게 되는 것이다!
☞absolute는 부모 요소의 영역에 겹쳐서 배치되므로, 이 문단(위 문단이 빠진 자리로 올라가서 자리잡게 된다!)에 의해
위쪽 요소(예컨대 위 코드의 <h5>)가 가려지지 않도록 해야 한다면;
그에 맞게 적절한 패딩을 주어야 한다: <h5 class="pb-5">← 부트스트랩의 패딩 유틸리티를 써서 아래쪽에 패딩을 줌!
☞position: absolute;는 요소를 문서의 기본 흐름에서 벗어나
(가장 가까운 부모요소의 좌상단을 기준으로 하는)좌표값을 써서 배치한다.
이때, 상위 부모요소에서 position: relative;로 설정해주면;
그 부모요소를 기준으로 하는 절대 위치에 자리잡게 되는 것이다!
➥
특정 요소에 position: relative; 값을 추가하면;
position: absolute; 값을 가진 모든 자식요소의 컨테이닝 블록이 된다.
이는, 자식요소에 position: absolute; 값이 적용되는 경우;
기존의 상위 부모요소 대신 이 relative 요소 아래로 재배치됨을 의미한다
←
이러한 특성은, 일반 흐름에서 요소를 완전히 제거하고,
대신 컨테이닝 블록의 가장자리(좌상단 모서리)로부터의 오프셋을 사용하여
요소를 배치할 때(예컨대, 화면 밖에 숨어 있지만, 버튼을 클릭하여 나타나고 사라지는 패널창 등)에 유용하게 사용된다!
3.position: fixed;는 화면 스크롤과 무관하게 뷰포트의 현재 위치에 고정한다
- 문서의 흐름과 무관하게 좌표값을 써서 원하는 위치에 배치하는데, 그 기준은 body가 된다:
➥
이는 컨텐츠가 스크롤될 때도, 항상 화면의 같은 위치에서 떠다니는 탐색 메뉴창, 메시지창, 광고창 등을 만드는 데 유용하게 사용된다.
예컨대, 웹페이지 탐색 시 상단 내비게이션바나 하단 바닥글, 좌우측 사이드바 등이 고정되어 있는 경우를 흔히 접하게 되는데,
이러한 각 방면 고정바는 position: fixed; 속성과 박스 좌표, 너비(및 높이) 값을 써서 만들게 된다:
스티키 고정
요소에 position: sticky; 값을 주면;
해당 요소는 설정된 (뷰포트 기준)오프셋에 도달할 때까지는 일반 흐름으로 스크롤되다가,
설정된 오프셋 지점에 이르면 position: fixed; 값을 준 것처럼 그 위치에 고정된다
- 곧, 뷰포트가 해당 요소를 지나쳐가며 스크롤할 때에도 요소 자체는 설정된 오프셋 값에 맞춰 자기 자리를 고수하는 것이다!
░
Css에서 Z-Index는 브라우저의 3차원 공간인 z축(x축: 가로, y축: 세로)을 기반으로
요소의 레이어 겹침 순서(곧, 어느 요소가 사용자의 눈에서 더 가까이 있는가)를 정하는데,
포지셔닝 기본값인 static 을 제외한 relative, absolute, fixed 에서
번호순으로 요소를 위로 겹쳐서 배치하게 된다
일반 문서에서의 쌓임 맥락
1.
같은 부모요소 영역 내에서, 포지션이 지정되지 않은 요소는 포지션이 지정된 요소 이전에 우선적으로 렌더링된다
- 곧, 포지션이 지정되지 않은 요소(DIV #5)는 (문서 흐름상 나중에 나올지라도 )포지션이 지정된 요소(DIV #4) 밑에 깔린다:
(! 맨 밑에는 부모요소의 배경과 테두리가 깔린다)
[DIV #4]
position: absolute; opacity: 0.7;
[DIV #5]
같은 부모요소 영역 내에서, 포지션이 지정되지 않은 요소(DIV #5)는 (코드 순서상 나중에 나오더라도)포지션이 지정된 요소((DIV #4)) 이전에 우선적으로 렌더링 된다!
2.
한편, 포지션이 지정된 요소들끼리는; 일반 요소들과 마찬가지로,
(주어진 포지션 값들과 무관하게)문서의 흐름상 순서대로
(아래, DIV #1 -> DIV #2 -> DIV #3 -> DIV #4)쌓이게 된다:
같은 부모요소 영역 내에서, 포지션이 지정되지 않은 요소(DIV #5)는 (코드 순서상 나중에 나오더라도)포지션이 지정된 요소 이전에 우선적으로 렌더링 된다!
요소의 겹침 순서
1.z-index 값이 지정되지 않은 경우(즉, 기본값인 0);
문서에 나오는 소스코드 순서대로 1, 2, 3, .. 순이 된다 - 곧, 나중에 작성된 요소가 먼저 작성된 요소를 덮는다:
부모요소 div
먼저 작성된 p 문단입니다
나중에 작성된 p 문단인데, 음수 마진을 주었습니다!
☞
위 코드에서는 <div> 요소보다 <i> 및 두 <p> 요소가 나중에 작성되었습니다
- 곧, z-index가 없는 경우, 나중에 작성된 요소가 위로 올라옵니다!
2.
반면, z-index 값을 음수로 주면; 일반 정적(Static) 요소의 밑으로 들어가게 된다:
부모요소 div
위 말만 믿고 z-index에 -1 값을 주었는데.. 음~ 소용없네요 ㅡㅡ;
1) 일반 흐름에서 z-index에 특정 값을 설정했는데 작동하지 않는다면;
요소의 position 값을 기본값인 static 이외의 값으로 설정해주어야 한다
←
이는 가장 흔히 일어나는 z-index 관련 혼란이다!
부모요소 div
드디어.. 저는 제 부모님 뒤로 갔습니다!
☞
자식요소에 (static 이외의)position 값을 주어야 한다는 말의 요점은,
자식요소의 z-index 값은 자식요소의 '직계' 부모요소에게만 의미가 있다는 것이다!
➥
문서의 일반 흐름에서와는 다른 쌓임 순서를 적용하고자 한다면;
먼저 부모요소 내부 자식요소에서 (static 및 auto 외의)position 값을 설정해주고
z-index 값도 지정해주어야 한다.
곧, z-index는 position이 설정된 요소에 대해서만 자신의 존재 의의가 있다!
2) 플렉스박스나 그리드에서는 굳이 position: relative;를 추가해주지 않아도
플렉스나 그리드 항목의 z-index 값을 변경할 수 있다:
부모요소 div
플렉스박스 안에서, 좀 더 간단하게.. 이제 저는 제 부모님 뒤로 갔습니다!!
3.
부모요소에 position 설정(과 함께 z-index 값)을 설정해주면;
새로운 스택 컨텍스트가 생성되며,
이 안에서는 자식요소의 z-index 값을 -999 까지 설정해주더라도 여전히 부모요소보다 밑에 놓일 수는 없다
- 곧, 이 자식요소는 새로운 스택 컨텍스트의 일부이기에 결코 부모요소로부터 벗어날 수 없다!
부모요소
이제 저는 다시 제 부모님 위로 올라옵니다!!
Stack 컨텍스트
░스택 컨텍스트란 하나 이상의 자식요소를 포함하는 상위요소를 말하는데,
내부 자식요소들은 소스 순서 규칙에 따라 쌓이고, z-index 값은 이 부모요소 내에서만 자신의 존재 의의가 있다!
스택 컨텍스트의 자식요소들은 대략 다음 순서로 아래쪽에서 위쪽으로 쌓인다:
음수 z-index 값이 있는 자식요소, 위치가 지정되지 않은 요소,
z-index: auto;인 요소, z-index: 1; 이상인 요소
스택 컨텍스트와 Z-index
하나의 쌓임 맥락은 그 내부에 또 다른 쌓임 맥락을 포함할 수도 있고,
이는 전체 계층구조상의 쌓임 맥락에서는 통째로 하나의 묶음 단위로 움직이게 된다.
곧, 각각의 쌓임 맥락은 서로 독립적이어서, 어느 요소가 자기 영역 내에 자신의 컨텐츠를 쌓은 후에,
자신은 또 통째로 그 위 부모 컨테이너 영역의 쌓임 맥락 안에서 하나로 묶인 단일 단위로 작동하는 것이다.
나아가, html 문서 내 모든 요소가 쌓임 맥락을 생성하는 건 아니므로, 쌓임 맥락의 계층구조는 html 문서 계층구조의 부분 집합이 된다:
➥
참고로, 스택 컨텍스트를 위해 반드시 z-index 및 position 속성을 써야만 하는 것은 아니다.
(none 값 이외의)transform, filter, clip-path 등을
사용할 때도 스택 컨텍스트가 형성된다.
또한, 자식요소에서 1 이하의 opacity 값을 설정해줄 때도
(사실상의)스택 컨텍스트가 형성된다!
Overflow
░박스는 display 속성값, 설정된 박스 크기 및 박스 안 컨텐츠에 따라 다르게 동작한다.
이러한 컨텐츠는 자식요소에 의해 만들어진 더 많은 수의 박스일 수도, 또는 일반 텍스트 컨텐츠일 수도 있지만,
어느 쪽이건, 이러한 컨텐츠는 기본적으로 박스의 크기에 영향을 미치게 된다!
박스 넘침처리
박스의 크기보다 컨텐츠의 내용이 너무 많을 때, 박스 바깥으로까지 컨텐츠가 넘쳐나는 오버플로가 발생하는데,
이는 컨텐츠 손실 방지를 위한 Css의 기본 메카니즘이 작동하여 모든 내용을 표시하고자 하는 때문이다!
컨테이너 박스 영역을 (블록레벨인)자식요소가 넘어서게 될 때 화면에 어떻게 나타낼 것인가?
html은 기본적으로 자기 영역을 넘어서라도 넘치는 컨텐츠를 표시해준다(기본값인 visible).
반면, overflow: hidden;은 자기 영역에서 벗어나는 부분은 잘라낸다
- 곧, 자식요소의 해당 부분이 숨겨진다.
한편, overflow: scroll;은 항상 스크롤바를 표시하며,
overflow: auto;는 자기 영역을 넘칠 때만 해당 방향의 스크롤바를 표시한다
집 건물 벽:
오버플로 문제를 다룰 때, 부모 컨테이너의 공간(이 작은 박스 - 거실 창문이라고 가정하자)은 크기가 정해져 있으며 변경되지 않는다.
따라서, 내부 자식요소(이 작은 박스 안의 텍스트 내용 - 거실 안에서 거닐고 있는 자신의 모습을 상상해보라)를 이 작은 창문을 통해 바깥의 관람자에게 다 보여주려면; 부모 컨테이너(곧, 창문의 크기)보다 더 큰 공간이 필요해진다.
이 거실 내부의 숨겨진 부분을 창문 바깥에서 어떤 방식으로 보도록 할 것인지를 정해주는 것이 바로 Css의 overflow 속성이다!
☞
결과적으로, 스크롤 설정된 박스의 내용은 그 자체의 미니 레이아웃이 되는데,
이는 박스의 모든 내용을 포함하되, 또한 페이지의 다른 항목과 겹치지 않도록 하기 위한 것이다
←
참고로, 오버플로가 효력을 가지려면;
반드시 부모 컨테이너 박스의 높이(height 또는 max-height)가 설정되어 있어야 한다!
✓ overflow-x/y: 값;으로 x/y축 방향의 오버플로를 각각 설정해줄 수도 있고,
overflow: x값 y값;으로 한번에 설정해줄 수도 있다
←
문서 방향 및 쓰기모드에 기반한 논리적 속성 또한 쓸 수 있다: overflow: overflow-inline/block;
➥
박스 내부 컨텐츠가 부모 박스에 설정된 크기를 벗어나게 되면;
내부 컨텐츠가 부모박스 바깥으로까지 넘쳐나는 오버플로가 발생하게 되는데,
이에 대처하는 overflow 값이 visible 이외의 다른 값으로 설정되면;
가 형성되며, 이 오버플로에 대처하여 박스에 설정되는 스크롤바는 기본적으로 패딩 영역에 자리잡게 되는데..
이는 또한 전체 박스의 크기에도 영향을 미치게 되므로 유의할 필요가 있다!
키보드 사용자가 Tab 키를 눌러 박스 안으로 이동한 다음, 화살표 키를 사용하여 스크롤할 수 있도록 스크롤 가능한 영역에서 포커스를 허용할 수 있는지는 접근성의 측면에서 중요하다!
스크롤링 박스에서 포커스를 받을 수 있도록 하려면; tabindex= "0"과 함께 적절한 role 및 aria-labelledby 속성을 추가해준다:
그런 다음 Css를 써서 박스에 포커스가 있음을 나타내고 outline 속성을 사용하여 스크롤이 가능하다는 시각적 단서를 제공해준다:
☞
위 코드는 role, aria-labelledby, tabindex 속성이 있는 경우에만 박스가 스크롤된다!
플렉스박스
░플렉스박스로 작동시키기 위해서는;
먼저, 해당 요소들을 플렉스 컨테이너로 묶어준 뒤 display: flex; 속성값을 주어 플렉스박스임을 선언해주어야한다!
플렉스박스 선언 및 정의
1.Flexbox로 작동시키기 위해서는;
먼저, 해당 요소들을 플렉스 컨테이너로 묶어준 뒤 display: flex; 및 display: inline-flex;(인라인 플렉스)로 플렉스박스임을 선언해주어야한다:
(이하, 가로쓰기 모드 기준임)
플렉스 컨테이너 div { display: flex; }
플렉스박스로 작동시키기 위해서는; 먼저, 해당 요소들(= 플렉스 아이템)을
플렉스 컨테이너로 묶어준 뒤 플렉스박스임을 선언해주어야한다: div { display: flex; }
주축은 플렉스 아이템들이 배치되는 방향이며(여기서는, 좌측에서 우측으로 나아간다),
이 기본축의 시작과 끝 가장자리는 main start와 main end가 된다
교차축은 플렉스 아이템들이 배치되는 방향에 직각을 이루는 축이며(여기서는, 위에서 밑으로 내려간다),
이 교차축의 시작과 끝 가장자리는 cross start와 cross end가 된다
2.
이어서, 플렉스박스 내부 각 아이템들을 배치할 방향 및 넘칠 시의 대처 방식을 지정해주는데(flex-flow: flex-direction flex-wrap;),
flex-flow는 flex-direction과 flex-wrap으로 나누어 각각 따로 설정해줄 수도 있다:
flex-direction: row;(기본값)는 가로 방향으로(이것이 주축이 된다!)
아이템이 배치되며, column은 세로 방향으로(이것이 주축이 된다!) 아이템이 배치된다
←
한편, row-reverse 및 column-reverse 는 각각 역순으로 배치된다
flex-wrap: nowrap;(기본값)은 아이템이 넘쳐나도 아래로 내려가지 않으며,
wrap 은 아이템이 넘치면 밑으로 내려가서 배치된다
☞
플렉스박스에서 넘쳐서 아래로 내려가는 부분은 새로운 플렉스박스로 작동하게 된다
- 곧, 플렉스 컨테이너가 래핑되면 여러 플렉스 라인이 생성되고, 각 라인은 새로운 플렉스 컨테이너처럼 작동하는 것이다!
아이템 공간배분
flex: flex-grow flex-shrink flex-basis; 속성은 플렉스 아이템간 공간 배분을 지정한다:
[ 플렉스박스 아이템 공간배분 ]
.flex-item { /* 기본값: 0 1 auto */
flex-grow: 0; /* 공간이 남으면; (아이템 크기를)확대할 것인가? ← 기본값 No */
flex-shrink: 1; /* 공간이 모자라면; (아이템 크기를)축소할 것인가? ← 기본값 Yes */
flex-basis: auto; /* 플렉스 아이템의 초기 너비(및 높이) 값 ← 기본값 auto */
}
☞
플렉스박스 아이템의 기본 크기를 설정하는 flex-basis는
플렉스 아이템의 초기 너비값을 지정하는데, flex-direction 방향에 따라
row 에서는 너비, column 에서는 높이가 사용된다!
아이템 1
아이템 2
좀 더 긴 아이템입니다
( * 플렉스 컨테이너에 항목을 표시하는 데 필요한 공간보다 더 많은 공간이 있다고 가정할 경우;
최대 컨텐츠 크기에서 항목이 처음에 정렬된 후 공간을 채우기 위해 확대되지 않는다
- 이는 flex 속성의 기본값이 initial(= flex: 0 1 auto;)인 때문이다)
1.
각 아이템별로 flex: 1;, flex: 2;, flex: 3;과 같이 설정해줄 수도 있다
- 이제 플렉스 컨테이너의 사용 가능한 공간은 6개가 되고, 각 아이템별로 1, 2, 3의 비율로 분배된다:
flex: 1;
flex: 2;
flex: 3;
2.
위 플렉스박스 컨테이너 안 모든 아이템에 flex: 1;로 주고(일단은; 모든 아이템이 1씩 같은 크기로 설정된다),
그 아이템 중 하나에 flex: 2;와 같이 설정해줄 수도 있다
←
이제 각 아이템의 사용 가능한 공간은 먼저 각각 1씩 똑같이 나누어진 뒤,
2 값으로 추가 설정해준 하나의 아이템은 2배로 늘어나서
총 4개의 공간이 1/1/2 비율로 배분된다:
플렉스 아이템의 보이는 순서를 지정하는 order 속성은 z-index와 비슷해 보이지만,
z-index와는 달리 레이어층으로 구성되지 않고 요소의 흐름상 해당 항목이 어디서 보여져야 하는지 그 위치를 결정할 뿐이다!
모든 플렉스 아이템의 기본 순서값은 0이고, 1, 2, .. 등으로 지정할 수 있다
- 같은 값이면; 소스 순서대로 보이고, -1은 맨 앞으로 온다
이 order 속성은 논리적인 순서나 탭 순서와도 전혀 무관하게 오직 화면상 보이는 순서에만 영향을 준다.
따라서, 이 Order를 사용하고자 할 때는,
먼저 html을 재검토해 보고 소스코드 순서를 변경함으로써 처리할 수 있다면; 그렇게 하는 것이 좋다!
아이템 정렬
░플렉스박스는 아이템을 정렬하고 아이템 사이의 공간 배분을 위해 관련 속성들을 마련해 두었는데,
주축 방향을 대상으로 하는 경우는 justify-로 시작하고,
교차축 방향을 대상으로 하는 경우에는 align-으로 시작한다
플렉스박스 아이템 정렬
플렉스박스에서는 주축 방향으로의 공간 배분 및 교차축 방향으로의 아이템 정렬 속성들을 설정해줄 수 있다.
공간을 분배하는 데에는 justify-content(주축 방향으로의 공간 배분) 속성과
align-content(주축 공간이 넘쳐서 교차축 방향으로 내려갈 때의 공간 배분) 속성을 쓸 수 있고,
교차축 방향으로의 아이템 정렬에는 align-items(모든 아이템 대상)와
align-self(특정 아이템 대상) 속성을 쓸 수 있다:
[ 플렉스박스 아이템 정렬 속성 ]
.flex-container { /* 플렉스 컨테이너 ← 아래 옵션 값들은 모두 기본값이다! */
display: flex; /* 플렉스박스 선언 */
justify-content: flex-start; /* 주축(row라면; 가로, column이라면; 세로) 방향으로의 아이템 배치 기준점 */
align-content: stretch; /* (아이템이 넘칠 때)교차축 방향으로의 아이템 배치 기준점 */
align-items: stretch; /* 교차축 방향으로의 아이템 배치 수직 기준선 */
} .flex-container .item1 { /* 플렉스 컨테이너 내 개별 아이템 .item1 */
align-self: stretch; /* 개별 아이템 대상 교차축 방향으로의 아이템 배치 수직 기준선 */
}
1.
주축 방향으로(flex-direction: row;) 아이템을 배치할 때는
justify-content 속성을 사용한다(기본값은 flex-start):
item 1
item 2
item 3
☞
참고로, flex-direction: column;인 경우라면; justify-content가 해당 열에서 상하 방향으로 작동한다!
➥justify-content와 align-content 값을 한번에 설정해줄 수도 있는데,
place-content: 교차축값 주축값; 속성을 사용하면 된다:
.flex-container { place-content: center flex-end; }←
값을 하나만 주면; 같은 값으로 교차축과 주축 모두에 적용된다
2.
플렉스 라인 내에서 교차축 방향으로 아이템을 배치할 때는
align-items 속성(아이템 배치의 수직 기준선)을 사용하는데,
이 정렬에 사용할 수 있는 공간은 플렉스 컨테이너의 높이에 따라 다르며 래핑된 항목 집합의 경우에는 플렉스 라인에 따라 달라진다:
align-items: stretch/flex-start/center/flex-end/baseline;←
기본값인 stretch는 모든 아이템의 너비 및 높이를 (안의 내용물 양과 무관하게)동일하게 배분한다!
3.
한편, 특정 아이템만을 대상으로 할 때는 align-self 속성(개별 아이템 배치의 수직 기준선)을 사용해주면 된다
←
기본값인 stretch 는 해당 아이템의 높이 및 너비를 (안의 내용물 양과 무관하게)최대 크기로 확장한다!
1st item: align-self
더 긴 2nd item with a line break
보다 더 긴 3rd item with a line break with a line break
플렉스박스 자동마진
플렉스박스 그룹에서 한 항목을 분리하거나 그룹을 두 그룹으로 분리해야 하는 경우;
플렉스박스 자동 마진을 적용하여 이를 수행할 수 있다.
플렉스 아이템의 어느 한쪽 방향에 자동마진(auto 값)을 설정하면;
해당 아이템은 적용된 방향의 남은 공간 모두를 차지하면서 나머지 그룹을 밀어내어 그룹을 분할하게 된다:
☞.container_boxing2 :nth-child(2) { margin-inline-start: auto; }로 바꿔주면;
[아이템 2] 이전부터 앞으로 밀려나게 된다!
➥
그리드 레이아웃에서의 justify-self 및 justify-items 속성은
인라인 축에서 작동하여 그리드 영역 내의 해당 축에 항목을 정렬하는 작업을 수행한다.
반면, 플렉스박스의 아이템은 주축에서 하나의 그룹으로 작동하고, 따라서 해당 그룹에서 개별 항목을 따로 분리한다는 개념이 없다.
그리하여 플렉스박스에서는 자동 마진을 써서 이 단점을 메꾸는 것이다!
Css Grid
░
Css 그리드 레이아웃은 2차원 컨텐츠용으로 설계된 레이아웃 방식으로서, 행과 열에 동시에 내용을 배치한다.
이 그리드 레이아웃은 웹페이지를 주요 영역들로 나누거나
html 기본 요소로 구축된 컨트롤 부분 간의 크기, 위치 및 레이어 등의 관계를 정의하는 데 매우 탁월하다!
그리드 선언 및 정의
그리드는 웹페이지 디자인 요소들을 수평/수직으로 정렬하는 2차원 레이아웃으로서,
그리드 레이아웃을 구축할 때는 먼저 행과 열이 있는 그리드 컨테이너를 정의한 뒤,
해당 그리드 컨테이너 아래에 각각의 항목(= 아이템)들을 배치해주면 된다.
하나의 그리드는 Columns(= 열)과 Rows(= 행)으로 구성되며,
각 행과 행, 열과 열 사이에는 Gap (= 간격)이 존재한다
1.
웹페이지를 그리드로 작동시키기 위해서는;
먼저 그리드 컨테이너에서 display: grid; 선언 이후 그리드 행(및 열), 갭 등을 작성해준다.
아래, 코드는 3개의 열 트랙과 2개의 행 트랙을 생성한다:
[ Grid 선언 및 정의 ]
.grid-container { /* 그리드 컨테이너 */
display: grid; /* 그리드 선언 */
grid-template-columns: 1fr 1fr 1fr; /* 그리드 열 너비: 같은 lfr 너비의 3열 */
grid-template-rows: 150px auto; /* 그리드 행 높이: 첫번째 행은 150px 높이, 두번째 행은 안의 내용물에 맞게 높이가 결정된다 */
gap: 12px; /* 갭 설정: 각 셀간 간격*/
}
2.그리드 컨테이너는 display: grid;가 적용된 html 요소로, 직속 하위요소들에 대한 그리드 맥락을 만들며,
그리드 아이템은 그리드 컨테이너 아래 직계 하위요소들(항목들)이다:
[ Grid 컨테이너와 아이템 ]
그리드 라인
각각의 세로선(열 라인)은 앞쪽에서부터 1 ~ 4(= 열 라인번호),
가로선(행 라인)은 위쪽에서부터 1 ~ 3(= 행 라인번호)까지 라인번호가 붙는다:
그리드 아이템 1
그리드 아이템 2
그리드 아이템 3
그리드 아이템 4
그리드 아이템 5
그리드 아이템 6
☞Grid Cell은 Table의 셀로, 행/열 Grid Track은 각각 Table의 행/열로 생각하면 된다.
한편, Grid Area는 여러 행, 또는 여러 열을 포괄하는 영역이 된다.
Grid Line에서
맨 앞쪽 세로선(1)부터 맨 끝 세로선(4)까지의 영역은 각각의 행 트랙이 되며,
맨 위 가로선(1)부터 맨 아래 가로선(3)까지의 영역은 각각의 열 트랙이 된다
➥Grid Gap은 행/열 트랙들 사이의 간격 으로서, 일반 트랙처럼 작동하여 크기 조정에 활용된다
- 컨텐츠를 배치할 수는 없지만, 그리드 항목이 갭에 걸쳐지게 할 수는 있다!
gap: 값; /* 행과 열 트랙간 간격 ← 단위는 px 및 % */
row-gap: 행 트랙간 간격; column-gap: 열 트랙간 간격;
그리드 컬럼 레이아웃:fr 단위
그리드의 fr 단위는 플렉스박스에서의 auto 값과 유사하게, 먼저 항목이 배치된 이후에 공간이 분배된다.
또한, fr 단위는 사용가능한 공간을 공유하므로 고정 크기 단위와 함께 쓸 수도 있다:
2.
Css의
함수를 쓰면 트랙이 그리드 컨테이너에서 갭을 뺀 나머지 공간을 동일하게 공유하도록 할 수 있다.
예컨대, minmax(auto, 1fr);로 주면;
그리드는 컨텐츠의 고유 크기를 확인하여 컨텐츠에 충분한 공간을 제공해준 다음 사용가능한 공간을 나누게 된다.
하지만, minmax(0, 1fr);로 주면; 트랙의 최소 크기는 최소 컨텐츠 크기가 아니라 0 이 되고,
그런 다음 그리드는 컨테이너에서 사용 가능한 모든 크기를 가져오고
갭에 필요한 크기를 뺀 다음 fr 단위에 따라 나머지를 분배하게 되는 것이다:
3.
Css의
함수와 Css auto-fill 및 auto-fit 키워드를 결합할 수도 있는데,
이 auto-fill 과 auto-fit 사이에는 미묘한 차이점이 존재한다.
곧, auto-fill 에서는 비워진 공간이 있는 반면, auto-fit 에서는 빈 공간 없이 꽉 채워진다
- 이는 남은 공간을 모두 차지하도록 트랙이 커짐을 의미한다
←
단, 첫 행 트랙이 다 채워지는 경우라면; 둘 사이에는 아무런 차이가 없다!
그리드에서 항목이 넘쳐나게 되면(예컨대, 다음 줄로 내려갈 때);
자동적으로 추가 그리드 선이 그려지면서 그리드가 확장되는데(= 암시적 그리드),
이렇게 자동 그리드로 생성되는 트랙은 기본값으로 auto 크기이며,
이는 일반적으로 컨텐츠를 담기에 충분히 크다는 것을 의미한다!
암시적 으로 생성되는 그리드 트랙은 기본적으로 크기가 자동 조정되지만(auto),
grid-auto-rows 및 grid-auto-columns 속성을 사용하여
'명시적'으로 그 크기를 조정해줄 수도 있다:
[ '명시적' 그리드 트랙 설정 ]
.grid-container {
display: grid; /* 그리드 선언 */
grid-template-columns: repeat(3, 1fr); /* 같은 너비의 3컬럼 생성 ← '명시적' 그리드! */
grid-auto-rows: 50px; /* 행 높이 수동 설정 ← '명시적' 그리드! */
gap: 12px; /* 그리드갭 설정 */
}
1.
위와 같이 행 높이를 고정된 값으로 주는 경우; 내부 컨텐츠가 늘어나는 경우 오버플로가 발생할 수 있는데,
이를 방지하기 위하여 Css의
함수를 써서 grid-auto-rows: minmax(50px, auto);와 같은 식으로
트랙의 최소 크기, 최대 크기 를 설정해줄 수 있다:
그리드 아이템에는 기본적으로 자동배치가 작동된다
- 곧, 각 항목은 소스에 나타나는 순서대로 셀당 하나씩 그리드에 배치된다.
대개의 경우는 이것으로 충분하지만, 필요하다면; 추가적으로 레이아웃을 조정해줄 수 있다:
1.
그리드 레이아웃은 기본적으로 행을 따라 항목을 배치하지만(문서 및 구성요소의 쓰기모드에서 텍스트가 표시되는 방향이 바로 행 라인이 된다!),
문서의 쓰기모드가 vertial: lr;이나 vertial: rl;인 경우 grid-auto-flow: column; 속성을 써서 항목을 열 방향으로 배치할 수 있다
2.
Css의 span 키워드를 써서
그리드 자동배치 레이아웃의 일부 또는 전체 항목이 둘 이상의 트랙에 걸쳐지도록 할 수 있다:
.greed_item { grid-column: auto / span 2; }←
앞 부분은 auto로 주고, 맨 뒤에서 2개이 열 트랙을 하나로 합친다!
3.
일부 항목이 여러 트랙에 걸쳐진 자동배치 레이아웃의 경우, 그리드에 일부 채워지지 않은 셀이 생길 수 있다
- 곧, 레이아웃이 완전히 자동배치된 그리드 레이아웃의 기본 동작은 항상 앞으로 진행하는 것인데,
다음 항목을 넣을 공간이 충분하지 않다면;
그리드는 갭을 남기고 다음 트랙으로(예컨대, 아래 행으로) 건너뛰게 되는 것이다.
여기서, grid-auto-flow: dense; 속성을 사용하면;
그리드가 나중에 레이아웃에서 항목을 가져와 건너뛴 빈 갭을 채우는 데 사용할 수 있다
←
단, 이러한 설정은 디스플레이가 논리적 순서에서 분리된다는 것을 의미할 수 있다!
그리드 배치/정렬
░
그리드의 시작 라인과 끝 라인을 번호로 지정하여 이 라인을 따라 그리드 아이템을 배치해줄 수 있다.
나아가, 그리드 영역에 이름을 지정하여 해당 그리드에 셀을 할당해줄 수도 있다!
그리드 아이템 배치
라인 기반 그리드 배치는 그리드 아이템의 라인, 범위 또는 자동 설정(auto) 값을 제공하여
그리드 영역의 인라인 시작 및 끝 가장자리를 지정함으로써 그리드 컨테이너 내에서 그리드 항목의 크기와 위치를 지정한다:
grid-column: 시작번호/끝번호; 그리드 열의 시작번호/끝번호←끝번호 생략시는; auto
grid-row: 시작번호/끝번호; 그리드 행의 시작번호/끝번호←끝번호 생략시는; auto
░
아래, MDN의
은 자신의 웹사이트에서 구현할 필요가 있는 일반적인 레이아웃 패턴에 대한 레시피를 모으는 것을 목표로 한다!
그리드 카드
카드는 일반적으로 그룹 또는 컬렉션 내에 표시되며,
각 카드에는 제목, 이미지, 컨텐츠(및 바닥글)이 포함된다.
카드는 1차원 레이아웃임에도 Css 그리드 레이아웃을 사용하여 배치하는데,
그럼으로써 그리드 트랙에 대한 컨텐츠 크기 조정을 사용할 수 있게 된다!
1.
단일 열 그리드 카드는 grid-template-rows 속성으로 다음과 같이 설정해줄 수 있다.
아래 Css 코드는 카드 제목행은 최대 크기(max-content)로 주어 늘어나는 것을 방지하고,
이미지 트랙은 (이미지의 높이인)200px 높이로 고정하며,
컨텐츠가 있는 맨 아래 행은 1fr로 주어 나머지 공간을 채우고 있다:
✓
플렉스박스를 사용하여 각 카드를 배치할 수도 있는데,
이 경우 각 카드 행의 크기가 카드 컨테이너가 아닌 각 행의 flex 속성으로 설정된다.
또한, flex 항목의 크기가 부모 컨테이너가 아닌 자식요소에서 정의된다
←
어느 것을 사용할 지 여부는 그리드 카드에서와 같이 컨테이너에서 트랙을 다루는 것을 선호하는지,
아니면; 각 카드들에 부가적인 설정을 더하여 다룰 필요성이 있는지에 달려있을 뿐이다!
리스트그룹 뱃지
플렉스박스를 이용하면 간단히 뱃지와 함께 하는 리스트그룹 패턴을 만들고 레이아웃을 쉽게 변경할 수 있다:
텍스트와 배지가 수평 중앙에 정렬되도록 하기 위해 justify-content: space-between; 속성과
align-items: flex-center; 값을 넣어주면 된다:
➥
참고로, 부트스트랩의 <button> 및 유틸리티 클래스를 이용하면;
버튼 내 뱃지의 위치를 쉽게 변경해줄 수 있다(본 부트스트랩 강좌의
뱃지 달아주기
부분 참조 요)
☞
위 <button>에서의 .position-relative 및
<span>에서의 position-absolute top-0 start-100 translate-middle는
버튼 내 뱃지의 위치를 지정해주기 위한 것이다!
그리드 래퍼
그리드 래퍼 패턴은 중앙 래퍼 내에서 그리드 내용을 정렬하는 동시에 항목이 분리되어 포함하는 요소
또는 페이지의 가장자리에 정렬되도록 하는 데 유용하다.
그리드에 배치된 항목은 가로 가운데의 max-width 래퍼
및 그리드의 바깥쪽 가장자리, 또는 둘 다에 정렬할 수 있어야 한다.
░플렉스박스, 그리드, 다단컬럼 등은 기본적으로 반응형 레이아웃이며,
미디어쿼리나 뷰포트 메타태그 등은 반응형 레이아웃을 위한 것이다!
다단컬럼 레이아웃
Css
을 사용하기 위해서는; 먼저 다단 컨테이너 래퍼를 만들고,
column-count: 개수;로 가변 너비의 개수 만큼의 컬럼을 생성하거나,
column-width: 너비;로 고정된 너비 (가능한 개수만큼)의 컬럼(남는 공간은 각 컬럼별로 공평하게 배분된다!)을 생성해 준다.
추가적으로, column-gap 속성으로 컬럼간 간격을 설정해줄 수 있고,
column-rule 속성으로 컬럼간 구분선을 그어줄 수 있다:
Css 다단 레이아웃을 위해서는 먼저 다단 컨테이너 래퍼를 만들고, column-count나 column-width를 써서 다단 레이아웃을 작성해준다. 한편, 다단 컬럼은 개별적으로 크기나 색상, 배경 등을 스타일링할 수는 없다. 오직 column-gap으로 컬럼간 간격을 설정하고, column-rule로 컬럼 구분선을 추가해줄 수 있을 뿐이다:
Css 다단 레이아웃을 위해서는 먼저 다단 컨테이너 래퍼를 만들고, column-count나 column-width를 써서 다단 레이아웃을 작성해준다. 한편, 다단 컬럼은 개별적으로 크기나 색상, 배경 등을 스타일링할 수는 없다. 오직 column-gap으로 컬럼간 간격을 설정하고, column-rule로 컬럼 구분선을 추가해줄 수 있을 뿐이다:
➥Css 조각화 fragment는 컨텐츠가 여러 페이지, 영역 또는 열에서 끊어졌을 때 표시되는 방식을 정의한다.
이러한 단편화는 인라인 상자가 여러 줄로 줄 바꿈될 때, 또는 블록레벨 박스가 열 레이아웃 컨테이너 내에서 둘 이상의 열에 걸쳐 있거나
인쇄할 때 페이지 나누기에 걸쳐 있는 경우에도 발생한다!