HTML은 구조와 의미를 담당합니다.
CSS는 스타일과 레이아웃을 담당합니다.
그렇다면 CSS는 DOM의 위치를 어떻게 구성할까요?
이 게시물은 CSS의 레이아웃에 대한 모든 것을 다룹니다.
아래 게시물의 번역입니다.
https://www.smashingmagazine.com/2018/05/guide-css-layout/
Normal Flow(일반적인 흐름;Flow Layout)
일반적인 흐름은 모든 레이아웃의 시작점 입니다.
즉, 다른 레이아웃을 적용한다는 것은,
문서의 일반적인 흐름에서 해당 요소를 특별하게 취급한다고 생각할 수 있습니다.
일반적인 흐름을 활용하도록 문서 구조화
따라서 레이아웃에 대해 생각하기 전에,
문서의 구조와 콘텐츠가 문서의 위에서 아래로 읽힐 순서에 대해 생각해야 합니다.
일반적인 흐름에서 벗어나기
Floats
float는 상자를 왼쪽이나 오른쪽으로 이동하는 데 사용되며,
콘텐츠가 해당 상자를 둘러싸며 표시하게끔 할 수 있습니다.
항목에 float를 적용하려면,
CSS 속성 float에 left 또는 right 값을 사용하세요.
float의 기본값은 none입니다.
<style>
.item {
float: left;
}
</style>
CLEARING FLOATS
요소를 플로팅하면
다음 요소가 플로팅된 요소의 바닥을 둘러싸야만, 이후에 일반적인 흐름이 계속됩니다.
이를 방지하려면 float를 clear 해야 합니다.
float 다음에 올 요소에,
왼쪽에 떠있는 요소의 float를 없애려면 clear:left
오른쪽에 떠있는 요소의 float를 없애려면 clear:right를 적용합니다.
둘다 없애려면 both를 사용합니다.
<style>
.clear {
clear: both;
}
</style>
<div class="container">
<div class="item"></div>
<p>Pea horseradish azuki bean lettuce avocado asparagus okra.</p>
</div>
<style>
body {
padding: 20px;
font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}
p {
margin: 0 0 1em 0;
}
.container {
width: 500px;
border: 5px solid rgb(111,41,97);
border-radius: .5em;
padding: 10px;
}
.item {
width: 100px;
height: 100px;
float: left;
margin: 0 20px 20px 0;
background-color: rgba(111,41,97,.3);
}
.container {
clear: both;
}
</style>
<style>
.container::after {
content: "";
display: table;
clear: both;
}
</style>
블록 서식 맥락(The Block Formatting Context)
<style>
.container {
overflow: auto;
}
</style>
<style>
.container {
display: flow-root;
}
</style>
Float는 레거시를 위해 존재합니다.
해당 속성을 대체하기 위해 grid 레이아웃이 존재합니다.
저는 신규 프로젝트에서 해당 속성을 사용하지 않는 것을 권장합니다.
Float를 더 공부하고 싶다면...
- “The Clearfix: Force an Element To Self-Clear its Children,” Chris Coyier, CSS-Tricks
- “float,” CSS: Cascading Style Sheets, MDN web docs
- “clear,” CSS: Cascading Style Sheets, MDN web docs
- “Understanding CSS Layout And The Block Formatting Context,” Rachel Andrew, Smashing Magazine
포지셔닝(Positioning)
상대 위치 지정(RELATIVE POSITIONING)
아이템에 position:relative 속성이 있는 경우
기준점은 자기 자신이 일반적인 흐름에 있을 때의 위치입니다.
그 다음 top, left, bottom 및 left 속성에 대한 오프셋 값을 사용하여
자기 자신이 일반적으로 표시되는 위치에서 상자를 이동할 수 있습니다.
<style>
.item {
position: relative;
bottom: 50px;
}
</style>
페이지의 다른 항목은 요소의 새 위치에 반응하지 않습니다.
정상적인 흐름에서 배치된 위치는 예약되어 있으므로
다른 요소와의 겹침을 직접 관리해야 합니다.
절대 위치 지정(ABSOLUTE POSITIONING)
position: absolute를 설정하면 해당 항목은 일반적인 흐름에서 제거됩니다.
즉 원래 일반적인 흐름에 따라 위치할 공간이 제거됩니다.
항목은 다른 위치 지정된(position:static이 아닌) 요소 내에 중첩되지 않았다면
뷰포트일 포함 블록(containing block)을 기준으로 위치가 지정됩니다.
.item {
position: absolute;
top: 20px;
right: 20px;
}
뷰포트가 아닌 다른 상자를 기준으로 위치하고 싶다면, 해당 요소를 포함하는 다른 블록에 static이 아닌 position 값을 제공합니다.
position: relative를 설정하면 일반적인 흐름에서 항목이 제거되지 않으므로 해당 값을 선호합니다.
오프셋의 기준이 될 부모 요소에 position:relative를 제공하고
움직일 요소에 position:absolute와 오프셋을 제공합니다.
고정 위치 지정(FIXED POSITIONING)
.item {
position: fixed;
top: 20px;
left: 100px;
}
끈끈한 위치 지정(STICKY POSITIONING)
(놀랍게도)일반적인 흐름, 끈끈한 위치 지정과 같은 용어는 mdn 공식문서의 한글 번역을 차용한 것입니다
.item {
position: sticky;
top: 0;
}
다음은 콘텐츠와 함께 스크롤되는 내비게이션 바의 인기 있는 효과를 흉내낸 예제입니다.
콘텐츠를 스크롤할 시 뷰포트 상단에서 부착되어 화면에 머무르도록 하는 방법입니다.
위치 지정에 대해 더 공부하기
- “Positioning,” MDN Learning Area, MDN web docs, Mozilla
- “position: sticky;,” Chris Coyier, CSS-Tricks
- “CSS position:sticky,” Browser support information for sticky positioning, caniuse
플렉스 레이아웃(Flex Layout)
.container {
display: flex;
}
해당 요소의 직계 자식은 플렉스 항목이 되며
인라인 방향의 시작점 모서리에 정렬된 행으로 배치됩니다.
플렉스 박스의 축
방향과 순서(DIRECTION AND ORDER)
Flexbox는 row-reverse 또는 column-reverse의 flex-direction 값을 사용하여
기본 축에서 항목의 방향을 변경하는 기능을 제공합니다.
플렉스 속성
플렉스 속성은 기본 축을 따라 플렉스 항목의 비율을 제어하는 방법입니다.
세 가지 속성은 다음과 같습니다.
- flex-grow
- flex-shrink
- flex-basis
이 세가지 속성은 일반적으로 flex 속성을 이용해 약식 형식으로 사용되며,
첫 번째 값은 flex-grow, 두 번째는 flex-shrink, 세 번째는 flex-basis를 의미합니다.
.item {
flex: 1 1 200px;
}
flex-grow가 양수 값으로 설정되면 항목이 커져 공간을 차지할 수 있습니다.
따라서 위의 예에서 각 항목에 200픽셀을 지정하면 항목 간에 추가 공간이 공유됩니다.
플렉스박스 더 공부하기
- https://studiomeal.com/archives/197
- “CSS Flexible Box Layout,” A complete guide to the specification, MDN web docs, Mozilla
- “A Complete Guide to Flexbox,” Chris Coyier, CSS-Tricks
- “Flexbox Froggy,” A game for learning Flexbox
- “Flexbugs,” A community curated list of browser bugs relating to Flexbox
그리드 레이아웃(Grid Layout)
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: 200px 200px;
}
길이 단위 또는 백분율을 사용하여 열 및 행 트랙을 설정할 수 있지만
그리드 레이아웃을 위한 새로운 단위인 fr 단위를 사용할 수도 있습니다.
fr 단위는 플렉스 단위이며 그리드 컨테이너에서 사용 가능한 공간의 공유를 나타냅니다.
(flex의 stretch, shrink도 동일하게 사용 가능한 공간의 공유를 의미합니다.)
그리드는 가용 공간을 분배할 수 있습니다.
내용물이 컨테이너에 맞는지 확인하기 위해 백분율을 계산할 필요가 없습니다.
아래 예에서는 fr 단위를 사용하여 열을 만들고 트랙이 자동으로 생성되도록 합니다.
우리는 또한 grid-gap을 사용하여 트랙 사이에 간격(gap)을 만들고 있습니다.
fr 단위와 절대 길이를 혼합할 수도 있습니다.
그리드 용어(GRID TERMINOLOGY)
그리드에는 항상 두 개의 축이 있습니다.
인라인 축은 페이지에 단어가 배치되는 방향을 향하고 블록 축은 블록이 배치되는 방향을 향합니다.
- 그리드 컨테이너(Grid Container)는 display: grid를 설정한 요소입니다.
- 그리드 라인(grid line)은 grid-template-columns 및 grid-template-rows를 사용하여 지정한 열 및 행 track에 의해 생성된 직선입니다.
- 그리드 셀(grid cell)은 그리드(4개의 교차하는 그리드 라인 사이)에서 가장 작은 단위를 이라고 합니다.
- 그리드 트랙(grid track)은 두 라인 사이의 셀들을 의미합니다.
- 그리드 영역(grid area)은 직사각형 모양을 만드는 한 개 이상의 그리드 셀 집합입니다.
그리드 자동 배치(GRID AUTO-PLACEMENT)
기본적인 라인 기반 위치 지정(BASIC LINE-BASED POSITIONING)
.item {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 3;
}
.item {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
이름 지정 영역을 이용한 위치 지정(POSITIONING WITH NAMED AREAS)
명명된 영역을 사용하여 그리드에 항목을 배치할 수도 있습니다.
이 방법을 사용하려면 각 항목에 이름을 지정한 다음 grid-template-areas 속성 값으로 레이아웃을 설명합니다.
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
}
.item3 {
grid-area: c;
}
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-areas:
"a a b b"
"a a c c";
}
- 항목이 여러 셀에 걸쳐 있도록 하려면 이름을 반복해서 적습니다.
- 영역은 완전한 직사각형을 형성해야 하며 L자형 또는 테트리스 조각은 허용되지 않습니다.
- 그리드는 완전해야 합니다. 즉, 모든 셀을 채워야 합니다.
- 공백을 남기려면 해당 셀을 .로 채웁니다.
아래 CSS는 오른쪽 하단 모서리를 비워둡니다.
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-areas:
"a a b b"
"a a c .";
}
이것은 CSS를 보는 사람이라면 누구나 레이아웃이 어떻게 동작하는지 정확히 볼 수 있기 때문에 추천하는 방법입니다.
그리드 레이아웃에 대해 더 알아보기
- “CSS Grid Layout,” Web technology for developers, MDN web docs, Mozilla
- “Grid by Example,” Everything you need to learn CSS Grid Layout, Rachel Andrew
- “Grid Garden,” A fun interactive game to test and improve your CSS skills
- “Layout Land,” Jen Simmons, YouTube
- “Best Practices With CSS Grid Layout”
- “Styling Empty Cells With Generated Content And CSS Grid Layout”
- “Using CSS Grid: Supporting Browsers Without Grid”
- “CSS Grid Gotchas And Stumbling Blocks”
- “Naming Things In CSS Grid Layout”
시각적 순서와 문서 상 순서(Visual And Document Order)
시각적 순서와 문서 상 순서에 대해 더 알아보기
- “CSS Grid Layout and Accessibility,” Web technology for developers, MDN web docs, Mozilla
- “HTML Source Order vs CSS Display Order,” Adrian Roselli
- “Flexbox And The Keyboard Navigation Disconnect,” Code Things, Tink
- “The Responsive Order Conflict For Keyboard Focus,” Alastair Campbell
박스 생성(Box Generation)
박스와 컨텐츠 안보여주기(display: none)
하위 항목을 포함하여 해당 요소와 해당 요소의 모든 콘텐츠가 생성되지 않도록 하려면 display: none을 사용할 수 있습니다.
이제 요소가 표시되지 않으며 해당 위치에 공간이 예약되지 않습니다.
.item {
display: none;
}
하위 요소만 보여주기(display: contents)
display의 새로운 값은 display: contents입니다.
display: contents를 요소에 적용하면 해당 요소에 대한 상자는 생성되지 않지만 자식은 정상적으로 생성됩니다.
이는 간접 하위 요소가 플렉스 또는 그리드 레이아웃의 일부가 되도록 하려는 경우에 유용할 수 있습니다.
박스 생성에 대해 더 알아보기
- “Vanishing Boxes With display: contents,” Rachel Andrew
- How display: contents; Works,” Ire Aderinokun,
- CSS display: contents,” Browser support information, caniuse
정렬 (Alignment)
- justify-content
- align-content
- place-content
- justify-items
- align-items
- place-items
- justify-self
- align-self
- place-self
- row-gap
- column-gap
- gap
레이아웃 모델은 기능이 다르기 때문에 사용 중인 레이아웃 모델에 따라 정렬이 약간 다르게 동작합니다.
몇 가지 간단한 Grid 및 Flex 레이아웃에서 정렬이 작동하는 방식을 살펴보겠습니다.
align-items 및 justify-items 속성을 설정하는 것은
모든 그리드 항목에 align-self 및 justify-self 속성을 설정하는 것과 동일합니다
이 속성은 그리드 영역 내부의 항목을 정렬합니다.
align-content 및 justify-content 속성은 그리드 컨테이너에 트랙을 표시하는 데 필요한 것보다,
더 많은 공간이 있는 그리드 트랙을 정렬합니다.
Flexbox에서 align-items 및 align-self는 교차 축(Cross Axis)의 정렬을 담당하고,
justify-content는 기본 축의 공간 내 분배를 담당합니다
align-content 또한 플렉스박스에서는 교차 축 방향 공간 내 분배를 의미합니다.
아래와 같은 경우, 아이템들이 주축 뱡향이 아니라 교차 중 방향으로 분배되고 있으며,
wrap된 각 줄이 하나의 아이템처럼 취급됩니다.
align-content는 이 각 줄의 분배를 담당합니다.
행과 열 간격(ROW AND COLUMN GAPS)
정렬에 대해 더 알아보기
- “CSS Box Alignment,” CSS: Cascading Style Sheets, MDN web docs, Mozilla
- “Box Alignment in Flexbox,” CSS Flexible Box Layout, MDN web docs, Mozilla
- “Box Alignment in CSS Grid Layout,” CSS Grid Layout, MDN web docs, Mozilla
- “The New Layout Standard For The Web: CSS Grid, Flexbox And Box Alignment,” Rachel Andrew, Smashing Magazine
- “Box Alignment Cheatsheet,” Rachel Andrew
다중 열 레이아웃 (Multi-Column Layout)
컬럼 너비에 설정하기 (SETTING A COLUMN WIDTH)
.container {
column-width: 300px;
}
열 갯수 설정하기 (SETTING A NUMBER OF COLUMNS)
너비를 설정하는 대신 column-count를 사용하여 열 수를 설정할 수 있습니다.
이 경우 브라우저는 요청한 열 수 사이의 남는 공간을 각 열에 나누어 분배합니다.
.container {
column-count: 3;
}
GAP 속성과 COLUMN 법칙 (GAPS AND COLUMN RULES)
column-rule: 4px dotted #000;
요소가 열 간에 걸치게 하기 (ALLOWING ELEMENTS TO SPAN COLUMNS)
column-span 속성을 사용하여 모든 열에 걸쳐 여러 열 컨테이너 내부의 요소를 확장할 수 있습니다.
h3 {
column-span: all;
}
column-span가 있는 스패닝 요소가 있으면,
스패닝 요소 위와 아래에만 컬럼이 있는 형태가 됩니다.
column-span: all 또는 column-span: none만 사용할 수 있습니다.
즉, 일부 열에만 걸치도록 할 수 없습니다.
다중 열 레이아웃에 대해 더 알아보기
- “Using Multi-Column Layouts,” CSS Multi-column Layout, MDN web docs, Mozilla
분할(Fragmentation)
.card {
page-break-inside: avoid;
break-inside: avoid;
}
.container h2 {
page-break-after: avoid;
break-after: avoid;
}
분할(Fragmentation)에 대해 더 알아보기
- “A Guide To The State Of Print Stylesheets In 2018,” Rachel Andrew, Smashing Magazine
- “Column Breaks,” QuirksMode.org
어떤 레이아웃을 사용해야 할까요?
'FrontEnd' 카테고리의 다른 글
[번역] CSS margin(마진)에 대한 모든 것(with 마진 겹침) (0) | 2023.02.06 |
---|---|
[번역] 왜 Tailwind CSS를 사용하나요? (0) | 2023.02.05 |
[번역] CSS 레이아웃과 블록 서식 맥락 이해하기 (0) | 2023.02.02 |
[번역] 타입스크립트를 활용한 타입 프로그래밍 입문 (0) | 2023.02.01 |
[번역] 빅테크 프론트엔드 기술 인터뷰 : Html편 (0) | 2023.02.01 |