Skip to content
This page has been auto-translated and may contain errors.View in English

표시 및 정상 흐름

docs.scrimba.com

CSS가 없는 페이지에 세 개의 단락과 몇 개의 링크를 넣으면, 여전히 자신들을 배치합니다: 단락들은 페이지 아래로 쌓이고, 링크들은 작성된 텍스트 내에 위치합니다. 아무도 브라우저에 그렇게 하라고 말하지 않았습니다. 첫 번째 레이아웃 규칙을 작성하기 전에, 이미 레이아웃이 존재하고 있으며 나중에 사용하는 모든 기술은 처음부터의 시작이 아닌 변경입니다. 이 장에서는 그 시작점과 이를 관리하는 하나의 속성에 관해 살펴봅니다.

정상 흐름

브라우저가 자신의 레이아웃 CSS 없이 페이지를 배치할 때, **정상 흐름**을 사용합니다: 요소들이 자신을 배치하는 기본 방식입니다. 단락과 제목 같은 블록 요소들은 위에서 아래로 쌓이며, 각각 자신의 줄에 위치합니다. 텍스트와 링크는 줄을 따라 왼쪽에서 오른쪽으로 흐르며, 공간이 부족하면 다음 줄로 줄바꿈합니다.

여러분은 이미 흐르는 요소들을 만났습니다: 이 장은 박스 모델을 기반으로 하는데, 이는 흐르는 것이 바로 그 박스들이기 때문입니다. 정상 흐름은 명명할 가치가 있습니다. 왜냐하면 레이아웃의 다른 모든 것은 이를 기반으로 정의되기 때문입니다. Flexbox, 그리드, 포지셔닝은 모두 "이들을 기본값과 다르게 배치하라"는 것을 의미하므로, 기본값을 아는 것이 변경 사항을 이해하는 데 도움이 됩니다.

**정상 흐름**은 브라우저의 기본 레이아웃입니다: flex, 그리드, float, 또는 포지셔닝이 개입하기 전에 얻는 배치입니다. 블록 박스는 소스 순서대로 페이지 아래로 수직으로 쌓이며, 각각 새로운 줄에서 시작하고 사용 가능한 전체 너비를 차지합니다. 인라인 박스는 줄을 따라 왼쪽에서 오른쪽으로 흐르며, 현재 줄이 가득 찰 때 다음 줄로 줄바꿈합니다.

이를 명명하는 이유는 레이아웃 도구들이 이로부터의 벗어남으로 정의되기 때문입니다. 컨테이너에 display: flex를 설정하면, 브라우저에 그 컨테이너의 자식 요소들을 정상 흐름 대신 flex 규칙으로 배치하도록 지시합니다. 기본값은 절대 사라지지 않습니다; 개별 컨테이너를 이로부터 벗어나게 합니다. 이것이 또한 스타일이 지정되지 않은 문서가 여전히 읽을 수 있는 이유입니다: 정상 흐름은 실제 레이아웃이지, 하나의 부재가 아닙니다.

**정상 흐름**은 float, 포지셔닝, flex, 또는 그리드가 무언가를 변경하기 전에 브라우저가 적용하는 레이아웃 모드입니다. 이는 함께 작동하는 두 개의 하위 모드를 가집니다: 블록 레이아웃은 블록 레벨 박스를 페이지 아래로 소스 순서대로 수직으로 쌓으며, 인라인 레이아웃은 인라인 레벨 박스를 한 줄 내에서 가로로 배열하고 여러 줄 박스에 걸쳐 줄바꿈합니다. 정상 흐름에 배치된 블록 박스는 사용 가능한 전체 너비를 차지하고 새로운 줄에서 시작합니다; 인라인 박스는 자신의 콘텐츠만큼만 너비를 차지하고 현재 줄 내에 위치합니다.

정확하게 명명하는 것이 중요한 이유는 전체 레이아웃 시스템이 이에 대한 대안들의 집합으로 구축되기 때문입니다. display: flexdisplay: grid는 컨테이너의 내부 레이아웃을 flex 또는 그리드 규칙으로 바꾸며, position: absolute 또는 float는 박스를 정상 흐름 밖으로 완전히 빼내어 주변 콘텐츠가 마치 그것이 그곳에 없는 것처럼 배치되도록 합니다. 모든 경우에 정상 흐름은 여러분이 벗어나는 기선이며, 명시적으로 이를 벗어나거나 다른 레이아웃 모드로 넘겨지지 않는 박스는 여전히 흐르고 있습니다. 이것이 스타일시트가 없는 문서가 여전히 합리적인 순서로 렌더링되는 이유입니다: 블록 및 인라인 흐름이 기본값이지, 폴백이 아닙니다.

Juno정상 흐름 정상 흐름은 무료로 얻는 레이아웃입니다: 블록은 페이지 아래로 쌓이고, 텍스트와 링크는 줄을 따라 흐릅니다. 아무도 이를 켜지 않으며, CSS를 작성하기 전에 이미 존재합니다. 레이아웃의 다른 모든 것은 이 기본값으로의 변경이므로, 먼저 기본값을 그려보는 것이 도움이 됩니다.
Juno정상 흐름 정상 흐름은 브라우저의 기본값입니다: 블록은 소스 순서대로 위에서 아래로 쌓이고, 인라인 박스는 줄을 따라 흐르고 줄바꿈합니다. Flex, 그리드, 포지셔닝은 모두 컨테이너를 이로부터 벗어나게 하는 방법이지, 어디서나 이를 대체하는 것이 아닙니다. 스타일이 지정되지 않은 페이지는 정상 흐름이 하나의 레이아웃이지, 그 부재가 아니기 때문에 잘 읽힙니다.
Juno정상 흐름 정상 흐름은 블록 레이아웃이 수직으로 쌓이고 인라인 레이아웃이 줄을 따라 흐르며, 다른 무언가가 박스에 영향을 주기 전에 기본적으로 적용됩니다. display: flexdisplay: grid는 컨테이너의 내부 레이아웃을 바꾸고, float 또는 position: absolute는 박스를 흐름 밖으로 빼내어 형제 요소들이 이를 무시하게 합니다. 여러분이 돌려보내지 않는 모든 것은 흐름에 머물러 있으며, 이것이 스타일시트가 없는 문서가 여전히 순서대로 렌더링되는 이유입니다.

블록 박스와 인라인 박스

요소는 정상 흐름에서 두 가지 주요 종류로 나뉩니다. **블록 박스**는 컨테이너의 전체 너비를 차지하고 자신의 줄에 쌓여 다음 요소를 아래로 밀어냅니다. 단락 <p>, 제목 <h1>, 그리고 <div>는 모두 블록이기 때문에 서로 아래에 정렬됩니다.

**인라인 박스**는 다릅니다. 텍스트의 줄 내에 위치하고 콘텐츠가 필요한 만큼만 공간을 차지하므로 여러 개가 한 줄을 공유할 수 있습니다. <span> 또는 링크 <a>는 인라인이므로, 문장 내의 링크는 자신의 줄로 이동하지 않고 단어의 흐름 내에 머물러 있습니다.

html
<!-- 이 단락은 블록이므로 자신의 줄에 위치합니다 -->
<p>This paragraph is a block, so it sits on its own line.</p>
<!-- 링크는 인라인이므로 문장 내에 머물러 있습니다 -->
<p>Read the <a href="/css/box-model">box model</a> for more.</p>

정상 흐름의 모든 박스는 블록 레벨 또는 인라인 레벨로 배치되며, 둘은 다른 규칙을 따릅니다. **블록 박스**는 새로운 줄에서 시작하고, 기본적으로 사용 가능한 너비를 채우며, 수직으로 쌓입니다. <div>, <p>, <h1>, 그리고 <section>은 기본적으로 블록입니다. 인라인 박스는 텍스트와 함께 줄 내에서 흐르고, 콘텐츠의 너비만 차지하며, 줄이 줄바꿈될 때까지 이웃 옆에 앉습니다. <span>, <a>, 그리고 <strong>은 기본적으로 인라인입니다.

사람들이 놀라는 차이점은 인라인 박스가 무시하는 것입니다. 인라인 박스는 width, height, 그리고 위아래 마진을 무시합니다. <span>width: 200px을 설정하면 아무것도 일어나지 않습니다. 왜냐하면 인라인 박스는 콘텐츠에 의해 크기가 결정되고, 여러분에 의해 결정되지 않기 때문입니다. 왼쪽과 오른쪽 패딩과 마진은 적용되지만, 수직 간격은 블록에서처럼 주변 줄들을 밀어내지 않습니다.

css
.tag {
  width: 200px;        /* 무시됨: span은 인라인이고, 콘텐츠에 의해 크기 결정 */
  padding: 0 8px;      /* 가로 패딩은 작동함 */
  margin-top: 40px;    /* 무시됨: 인라인 박스에 수직 마진 없음 */
}

정상 흐름에서 박스는 그 표시 타입에 따라 블록 레이아웃 또는 인라인 레이아웃으로 배치되며, 둘은 "쌓이거나 줄바꿈하거나"를 넘어 다릅니다. **블록 박스**는 자신 전과 후에 끊음을 생성하며, 너비가 주어지지 않는 한 포함하는 블록의 전체 인라인 크기를 소비하고, 네 개의 모든 마진과 두 개의 차원을 준수합니다. 인라인 박스는 줄 박스에 참여하며, 콘텐츠에 의해 크기가 결정되고, 그 레이아웃은 widthheight보다는 line-height와 기선 정렬에 의해 지배됩니다.

정확한 부분은 인라인 박스가 어떤 속성을 버리는지입니다. widthheight<span> 또는 <a>와 같은 대체되지 않는 인라인 박스에 적용되지 않습니다. 왜냐하면 그 크기는 콘텐츠와 주변 줄에서 나오기 때문입니다. 위아래 마진은 계산되지만 줄 높이에 영향을 주지 않으므로, 인접한 줄들을 밀어내지 않으며, 위아래 패딩도 시각적으로 렌더링되지만 줄 박스의 높이를 변경하지 않으므로, 인접한 줄들과 겹칠 수 있습니다. 왼쪽과 오른쪽 마진과 패딩은 적용되고 인라인 이웃들을 이동시킵니다. <img>와 같은 대체 인라인 요소들은 예외입니다: 그들은 본질적인 치수를 가지므로, 인라인이지만 widthheight가 그들에게 적용됩니다.

css
.badge {              /* .badge는 기본적으로 인라인인 <span> */
  width: 120px;       /* 효과 없음: width는 인라인 박스에 적용되지 않음 */
  height: 40px;       /* 같은 이유로 효과 없음 */
  padding: 12px;      /* 왼쪽/오른쪽은 이웃을 이동시킴; 위아래는 줄과 겹칠 수 있음 */
  margin: 8px 0;      /* 수직 8px는 무시됨, 가로 0은 적용될 것 */
}
Juno블록 박스와 인라인 박스<p><div>와 같은 블록 박스는 전체 너비를 차지하고 자신의 줄에 쌓입니다. <span><a>와 같은 인라인 박스는 줄 내에 위치하고 필요한 공간만 차지합니다. 이것이 링크가 문장 내에 머물러 있고 자신의 줄로 나뉘지 않는 이유입니다.
Juno블록 박스와 인라인 박스 블록 박스는 너비를 채우고 쌓이며; 인라인 박스는 줄을 따라 흐르고 콘텐츠에 맞춰집니다. 함정은 인라인 박스가 width, height, 그리고 수직 마진을 무시한다는 것입니다. 따라서 <span>width를 설정하는 것은 아무것도 하지 않습니다. 가로 패딩과 마진은 여전히 작동하는데, 이것이 사람들을 놀라게 하는 이유입니다.
Juno블록 박스와 인라인 박스 인라인 박스는 콘텐츠와 그 줄 박스에 의해 크기가 결정되므로, widthheight는 적용되지 않으며, 수직 마진과 패딩은 인접한 줄들을 밀어내지 않습니다. 가로 마진과 패딩은 적용되고 이웃들을 이동시킵니다. 예외는 <img>와 같은 대체 요소들이며, 이들은 자신의 차원을 가지고 있어 인라인일 때에도 widthheight를 수용합니다.

display 속성

모든 요소는 기본 종류, 블록 또는 인라인을 가지지만, 여러분은 그것에 국한되지 않습니다. display 속성은 요소가 어떻게 동작할지 변경할 수 있게 합니다. 링크에 display: block을 설정하면 이제 자신의 줄을 차지합니다; 목록 항목에 display: inline을 설정하면 행으로 위치합니다.

일반적인 문제를 해결하는 세 번째 값이 있습니다: display: inline-block. 인라인 박스처럼 줄 내에서 흐르지만, 블록처럼 너비, 높이, 그리고 수직 패딩을 수용합니다. 버튼 또는 네비게이션 알약처럼 이웃 옆에 앉아야 하면서도 여전히 정해진 크기를 가져야 하는 것에 원하는 것입니다.

css
.nav-link {
  display: inline-block;   /* 줄 내에서 흐르지만, 너비와 패딩을 수용함 */
  padding: 8px 16px;       /* 수직 패딩은 이제 작동함. 순수 인라인과 달리 */
}

display 속성은 박스가 레이아웃하는 방식을 설정하며, 세 가지 흐름 값은 block, inline, 그리고 inline-block입니다. display: block은 요소의 기본값이 무엇이든 상관없이 박스가 자신의 줄에서 시작하고 너비를 채치게 합니다. display: inline은 박스가 줄 내에서 흐르고 width, height, 그리고 수직 마진을 버리게 합니다. 둘 다 요소의 의미를 변경하지 않으며, 레이아웃만 변경합니다.

inline-block은 유용한 하이브리드입니다: 박스는 인라인 박스처럼 줄 내에서 흐르므로 여러 개가 나란히 앉아 있지만, 블록처럼 width, height, 그리고 수직 패딩과 마진을 수용합니다. flexbox로 이동하지 않고 행에 있으면서 여전히 실제 치수가 필요한 것, 버튼 모음이나 네비게이션 링크 모음에 이를 사용하세요. 전체 항목 행이나 그리드를 정렬과 간격으로 레이아웃해야 할 때, flexboxdisplay: flex가 더 나은 도구입니다; inline-block은 행에 있는 몇 개의 크기 지정 박스라는 더 작은 경우를 위한 것입니다.

css
.stat {
  display: inline-block;   /* 형제 요소들과 행에 앉아 있음 */
  width: 120px;            /* 고정 너비를 가지고 있으며, 인라인은 무시할 것 */
  padding: 12px;           /* 전체 패딩이 적용됨, 위아래 포함 */
}

display는 박스의 레이아웃 모드를 선택하며, 정상 흐름에 이를 유지하는 세 개의 값은 block, inline, 그리고 inline-block입니다. block은 자신 전과 후에 끊음을 생성하고 포함하는 블록의 인라인 크기를 채우는 박스를 제공합니다; inline은 줄 박스에 참여하고 width, height, 그리고 수직 마진을 버리는 박스를 제공합니다. display를 설정해도 의미는 절대 건드리지 않으며, 오직 레이아웃만 건드립니다: display: inline으로 설정된 <div>는 여전히 DOM과 보조 기술에 대한 <div>이며, 단지 인라인으로 배치될 뿐입니다.

inline-block은 의도적인 하이브리드입니다. 박스는 인라인 레벨이므로 줄 박스에 참여하고 인라인 이웃 옆에 앉아 있지만, 그 내부는 블록으로 배치되므로 width, height, 그리고 네 개의 모든 마진과 패딩이 적용되고 실제 레이아웃 공간을 차지합니다. 이는 flex 컨테이너를 원하지 않는 행에 있는 소수의 크기 지정 박스에 올바르게 사용됩니다. 예를 들어 고정 너비 통계 블록이나 네비게이션 알약입니다. 주의할 점은 이것이 인라인 레벨이기 때문에, HTML의 두 inline-block 요소 사이의 공백이 그들 사이의 실제 공간으로 렌더링된다는 것입니다. 이는 아래 고급 섹션에서 다룹니다. 전체 행에 걸쳐 정렬, 배포, 또는 줄바꿈이 있는 모든 것에, flexbox의 flex 레이아웃을 선호하세요; inline-block은 좁은 도구이지, 일반적인 도구가 아닙니다.

css
.pill {
  display: inline-block;   /* 인라인 레벨 박스, 블록 레벨 내부 */
  width: 96px;             /* 적용됨, 내부가 블록으로 배치되기 때문 */
  padding: 10px 14px;      /* 네 개의 모든 면이 레이아웃 공간을 차지함 */
  margin: 0 4px;           /* 이제 수직 마진도 적용됨 */
}
Junodisplay 속성display 속성은 요소가 블록으로 동작하는지 또는 인라인 박스로 동작하는지를 변경합니다. block은 자신의 줄을 차지하고, inline은 텍스트 줄에 앉습니다. 편리한 중간 옵션은 inline-block이며, 이는 줄 내에서 흐르면서도 여전히 너비와 패딩을 수용하므로, 버튼과 네비게이션 링크에 원하는 것입니다.
Junodisplay 속성display는 의미가 아니라 레이아웃을 설정합니다: block, inline, 또는 하이브리드 inline-block. 행에 앉아 있을 몇 개의 크기 지정 박스를 원할 때 inline-block을 사용하세요. 왜냐하면 width, height, 그리고 전체 패딩을 수용하면서 인라인으로 흐르기 때문입니다. 정렬과 간격이 필요한 전체 행에 대해, flexbox를 사용하세요.
Junodisplay 속성display는 레이아웃 모드를 선택하지만 의미는 선택하지 않으므로, 인라인 <div>는 여전히 DOM에 대한 <div>입니다. inline-block은 블록 레벨 내부를 가진 인라인 레벨 박스이므로, 행에 앉아 있지만 width, height, 그리고 네 개의 모든 마진을 준수합니다. 소수의 크기 지정 박스에 이를 유지하고 실제 행을 flexbox에 넘기세요. 그리고 인접한 박스들 사이에 남기는 공백 간격에 주의하세요.

것들을 숨기기: display none 대 visibility hidden

때때로 요소가 나타나지 않기를 원합니다. 두 가지 방법이 있으며, 그들은 다르게 동작합니다. display: none은 요소를 완전히 제거합니다: 그것은 사라지고 간격을 남기지 않으며, 페이지에 없었던 것처럼 말입니다. visibility: hidden은 그것을 보이지 않게 하지만 공간을 유지하므로, 그것이 있었던 곳에 빈 구멍이 있습니다.

어떤 것을 원하는지는 공간을 돌려받으려고 하는지 여부에 달려 있습니다. display: none을 사용하여 메뉴가 닫힐 때처럼 무언가를 완전히 떨어뜨리세요. visibility: hidden을 사용하여 레이아웃이 점프하지 않기를 원할 때 무언가를 숨기세요. 왜냐하면 그 박스가 여전히 예약되기 때문입니다.

css
.closed-menu {
  display: none;          /* 사라지고, 뒤에 간격이 없음 */
}
.placeholder {
  visibility: hidden;     /* 보이지 않지만, 여전히 공간을 차지함 */
}

요소를 숨기는 두 가지 방법은 상호 교환적이지 않습니다. display: none은 요소를 정상 흐름 밖으로 완전히 제거합니다: 박스를 생성하지 않고, 공간을 차지하지 않으며, 그 주변의 요소들은 그것이 절대 없었던 것처럼 닫습니다. visibility: hidden은 박스를 흐름에 유지하고 공간을 예약하므로, 레이아웃이 이동하지 않습니다; 요소는 오직 그려지지 않을 뿐입니다.

시각적 차이만큼 중요한 접근성 차이가 있습니다. display: none을 가진 요소는 접근성 트리에서도 제거되므로, 화면 판독기는 이를 건너뜁니다. 이는 축소된 패널처럼 전혀 없는 콘텐츠에 올바릅니다. visibility: hidden은 또한 콘텐츠를 화면 판독기에서 숨기면서 공간을 유지합니다. 시각적으로 사라진 무언가를 원하지만 여전히 보조 기술에 알리기를 원한다면, 이 둘 중 어떤 것도 올바르지 않습니다; 이는 시각적으로 숨겨진 유틸리티 클래스가 목적이며, 이는 CSS가 어떻게 작동하는지에서 의미와 함께 읽을 수 있습니다.

css
.tab-panel[hidden] {
  display: none;          /* 흐름에서 제거되고 접근성 트리에서도 제거됨 */
}
.spacer {
  visibility: hidden;     /* 공간을 유지하고, 여전히 화면 판독기에서 숨겨짐 */
}

display: nonevisibility: hidden은 모두 숨기지만, 흐름, 박스 트리, 그리고 접근성에서 다릅니다. display: none은 박스를 전혀 생성하지 않습니다: 요소는 레이아웃에서 부재하고, 공간을 차지하지 않으며, 그 자손들은 자신의 display가 무엇이든 상관없이 그와 함께 사라집니다. visibility: hidden은 박스를 정상적으로 생성하므로, 흐름에서 전체 공간을 차지하고 오직 그려지기만 억제합니다; 자손은 심지어 visibility: visible을 설정하여 다른 방식으로 숨겨진 조상 내에서 다시 나타날 수도 있으며, display: none은 이를 절대 허용하지 않습니다.

접근성과 동작상 결과는 의도적으로 선택하는 이유입니다. display: nonevisibility: hidden 모두 요소를 접근성 트리에서 제거하므로, 화면 판독기는 둘 다 알리지 않을 것입니다. 이는 시각적으로 없지만 여전히 큰 소리로 읽혀야 하는 콘텐츠에 대해서는 잘못되었습니다. 고전적인 경우는 "콘텐츠로 건너뛰기" 링크 또는 화면 판독기 전용 레이블입니다; 이들은 접근성 트리에 이를 두면서 박스를 픽셀로 자르는 시각적으로 숨겨진 패턴이 필요하며, 여기서 이 속성 중 어떤 것도 필요하지 않습니다. 두 가지 추가 실용적 노트: display: noneopacityvisibility의 방식처럼 상태 간에 전환되거나 애니메이션될 수 없으며, display: none으로 설정된 요소는 초점을 맞출 수 없으며 그 양식 컨트롤은 제출되지 않는 반면, visibility: hidden 컨트롤도 건너뛰어지지만 그 공간은 유지됩니다. display: none을 선택하여 완전히 제거하고, visibility: hidden을 선택하여 레이아웃을 유지하면서 숨기며, 보조 기술이 여전히 도달해야 할 때 자르기 유틸리티를 선택하세요.

css
.dropdown[aria-expanded="false"] .menu {
  display: none;          /* 완전히 제거됨: 박스 없음, 공간 없음, 초점 가능하지 않음 */
}
.avatar-slot {
  visibility: hidden;     /* 박스와 공간 유지, 그려지기 억제됨 */
}
Juno것들을 숨기기: display none 대 visibility hidden 두 가지 방법으로 숨기기: display: none은 요소를 제거하고 간격을 남기지 않으며, visibility: hidden은 보이지 않게 하지만 공간을 유지합니다. 공간이 없어지기를 원할 때 display: none을 선택하세요. 레이아웃이 점프하지 않기를 원할 때 visibility: hidden을 선택하세요.
Juno것들을 숨기기: display none 대 visibility hiddendisplay: none은 요소를 흐름 밖으로 당겨서 아무도 공간을 예약하지 않습니다; visibility: hidden은 박스와 공간을 유지하고 오직 그려지기만 숨깁니다. 둘 다 화면 판독기에서 요소를 숨기므로, 시각적으로 없지만 여전히 알려져야 한다면, 둘 다 올바르지 않습니다. 그 업무는 시각적으로 숨겨진 유틸리티 클래스에 속합니다.
Juno것들을 숨기기: display none 대 visibility hiddendisplay: none은 박스를 생성하지 않고 공간을 차지하지 않습니다; visibility: hidden은 박스와 공간을 유지하고 오직 그려지기만 억제하며, 자식은 visibility: visible을 설정하여 다시 나타날 수 있습니다. 둘 다 접근성 트리 밖으로 떨어집니다. 따라서 건너뛰기 링크 또는 화면 판독기 레이블은 둘 다 아닌 자르기 유틸리티가 필요합니다. display: none은 애니메이션 가능하지 않으며 그 컨트롤은 초점을 맞출 수 없거나 제출되지 않는 것을 기억하세요.

display가 내부 레이아웃을 변경하는 방법

여러분은 display가 요소를 블록과 인라인 사이를 전환하는 것을 보았습니다. 더 깊은 수준에서 더 많이 합니다. 같은 속성은 컨테이너를 flexbox 또는 그리드로 변환하는 것이며, 이는 행과 열에 자식을 배치하기 위한 두 가지 현대 도구입니다. 지금은, 붙잡아야 할 것은 display가 박스가 레이아웃하는 방식과 자신의 자식들이 그것을 레이아웃하는 방식을 결정하는 하나의 다이얼이라는 것입니다.

레이아웃은 한 번 켜는 하나의 큰 스위치가 아닙니다. 다른 배치가 필요한 특정 컨테이너에서 display를 변경하고, 여러분이 남겨둔 모든 것은 정상 흐름에 머물러 있습니다. flexboxpositioning 장은 여기에서 계속됩니다.

display는 실제로 두 가지를 동시에 제어합니다: 박스가 자신의 형제 요소들 사이에 어떻게 앉는지, 그리고 박스가 자신의 자식 요소들을 어떻게 배치하는지. display: blockdisplay: inline은 주로 첫 번째를 말합니다. display: flexdisplay: grid는 두 번째를 변경합니다: 컨테이너는 여전히 정상 흐름에 블록으로 참여하지만, 그 내부에서 자식들은 블록 및 인라인 흐름 대신 flex 또는 그리드 규칙으로 배치됩니다.

이것이 flexbox로 이동하는 것이 흐름에 대해 여러분이 알고 있는 모든 것을 버리지 않는 이유입니다. flex 컨테이너는 여전히 그 부모의 정상 흐름에 블록 박스입니다; 오직 자식들만 레이아웃 모드를 전환합니다. 정상 흐름은 그 주변에서 기본값으로 머물러 있으며, flex 또는 그리드가 필요한 특정 컨테이너를 선택합니다. positioning 장은 흐름을 벗어나는 다른 방법을 다룹니다. 즉, 컨테이너의 자식이 배치되는 방식을 변경하는 대신 박스를 완전히 흐름 밖으로 가져갑니다.

display 값은 실제로 두 가지 종류입니다: 외부 타입은 박스가 부모의 레이아웃에 어떻게 참여하는지를 말하고, 내부 타입은 박스가 자신의 자식을 어떻게 배치하는지를 말합니다. display: block은 외부 블록, 내부 흐름입니다; display: flex는 외부 블록, 내부 flex입니다; display: inline-flex는 외부 인라인, 내부 flex입니다. 이 두 부분 모델이 flex 컨테이너가 여전히 블록으로 정상 흐름에 앉아 있으면서 그 자식들이 flex 규칙을 따르는 이유입니다: 여러분은 외부 타입이 아닌 내부 타입을 변경했습니다.

여기에 자리를 얻는 또 다른 값: display: flow-root. 이는 정상 내부 흐름을 가진 박스를 제공하지만 새로운 블록 포맷팅 컨텍스트 (BFC: 자신의 내부가 외부와 상호 작용하지 않는 자체 포함 레이아웃 영역. 따라서 내부의 float은 포함되고 내부의 마진은 그 경계를 통해 축소되지 않음)를 강제합니다. flow-root가 존재하기 전에, 사람들은 overflow: hidden 또는 clearfix 해킹으로 BFC를 트리거하여 떠다니는 자식을 포함했습니다; flow-root는 "이것을 포함하라"고 말하기 위한 명시적이고 부작용이 없는 방법입니다. 또한 박스 모델에서 설명된 부모 및 자식 마진 축소를 중단합니다. 컨테이너를 display: flex 또는 display: grid로 이동할 때 flexbox에서, 여러분은 또한 새로운 포맷팅 컨텍스트를 설정하는 것이며, 이는 마진이 float 시대의 것들보다 현대 레이아웃 내부에서 더 예측 가능하게 동작하는 이유의 일부입니다.

css
.media {
  display: flow-root;     /* 떠다니는 자식들을 포함함, clearfix 해킹 없음 */
}
.gallery {
  display: flex;          /* 정상 흐름의 외부 블록, 자식을 위한 내부 flex */
}
Junodisplay가 내부 레이아웃을 변경하는 방법 블록과 인라인을 전환하는 같은 display 속성은 컨테이너를 자식을 배치하기 위한 flexbox 또는 그리드로 변환하는 것이기도 합니다. 레이아웃은 한 번 켜는 하나의 스위치가 아닙니다; 이것이 필요한 컨테이너에서 display를 변경하고 나머지를 정상 흐름에 두세요. flexbox 및 positioning 장이 여기에서 계속됩니다.
Junodisplay가 내부 레이아웃을 변경하는 방법display는 박스가 형제 요소들 사이에 어떻게 앉는지와 자신의 자식을 어떻게 배치하는지를 관리합니다. display: flexdisplay: grid는 두 번째를 변경하므로, flex 컨테이너는 여전히 정상 흐름의 블록입니다. 자신의 자식들만 flex 규칙으로 전환합니다. 이것이 flexbox를 배우는 것이 흐름을 대체하기보다는 흐름을 기반으로 구축되는 이유입니다.
Junodisplay가 내부 레이아웃을 변경하는 방법display 값은 외부 타입, 박스가 부모에 어떻게 참여하는지와 내부 타입, 그것이 자식을 어떻게 배치하는지를 가지고 있습니다. 이것이 flex 컨테이너가 흐름의 블록으로 머물러 있으면서 그 자식들이 flex로 가는 이유입니다. display: flow-root는 정상 내부 흐름을 유지하지만 새로운 블록 포맷팅 컨텍스트를 시작하므로, 오래된 overflow 또는 clearfix 해킹 없이 float을 포함합니다. Flex와 그리드 컨테이너도 자신의 컨텍스트를 설정하므로, 마진이 현대 레이아웃 내부에서 더 예측 가능하게 동작합니다.