디스플레이와 일반 흐름


CSS를 전혀 적용하지 않은 페이지에 문단 세 개와 링크 몇 개를 넣어도, 요소들은 스스로 자리를 잡습니다. 문단은 페이지 아래로 차례차례 쌓이고, 링크는 여러분이 써넣은 그 위치의 텍스트 안에 자리를 잡습니다. 이렇게 하라고 브라우저에게 시킨 사람은 아무도 없습니다. 레이아웃 규칙을 단 하나도 작성하기 전부터 이미 레이아웃은 존재하며, 이후에 사용하는 모든 기법은 그 상태를 처음부터 만드는 것이 아니라 이미 있는 것을 바꾸는 작업일 뿐입니다. 이번 장에서는 그 출발점과, 그것을 좌우하는 단 하나의 속성을 다룹니다.
일반 흐름
브라우저가 여러분이 작성한 레이아웃 CSS 없이 페이지를 배치할 때는 **일반 흐름(normal flow)**을 사용합니다. 이는 요소들이 스스로 자리를 잡는 기본 방식입니다. 문단이나 제목 같은 블록 요소는 위에서 아래로 쌓이며, 각자 자신만의 줄을 차지합니다. 텍스트와 링크는 한 줄 안에서 왼쪽에서 오른쪽으로 흐르다가, 자리가 부족해지면 다음 줄로 넘어갑니다.
여러분은 이미 흐르는 대상, 즉 박스 모델을 배운 적이 있습니다. 이번 장은 그 위에서 이어지는데, 흐르는 것은 결국 그 박스들이기 때문입니다. 일반 흐름이라는 이름을 붙이는 이유는, 레이아웃의 다른 모든 것이 이것을 기준으로 정의되기 때문입니다. 플렉스박스, 그리드, 포지셔닝은 모두 "기본값과 다르게 배치하라"는 지시일 뿐이므로, 기본값을 알아야 그 변화들이 이해가 됩니다.
블록 박스와 인라인 박스
일반 흐름에서 요소는 크게 두 가지 종류로 나뉩니다. **블록 박스**는 컨테이너의 전체 너비를 차지하며 자신만의 줄에서 쌓이고, 다음 요소를 그 아래로 밀어냅니다. 문단 <p>, 제목 <h1>, <div>는 모두 블록이며, 그래서 이들이 한 줄씩 아래로 늘어서는 것입니다.
인라인 박스는 다릅니다. 텍스트 줄 안에 자리를 잡고 콘텐츠에 필요한 만큼의 공간만 차지하므로, 여러 개가 한 줄을 나눠 쓸 수 있습니다. <span>이나 링크 <a>는 인라인이며, 그래서 문장 안의 링크가 자신만의 줄로 튀지 않고 문장의 흐름 속에 머무는 것입니다.
<p>이 문단은 블록이므로 자신만의 줄을 차지합니다.</p>
<p>더 알아보려면 <a href="/ko/css/box-model">박스 모델</a>을 읽어 보세요.</p>
<!-- 링크는 인라인이므로 문장 안에 그대로 머뭅니다 --><p>, <div> 같은 블록 박스는 전체 너비를 차지하며 자신만의 줄에 쌓입니다. <span>, <a> 같은 인라인 박스는 줄 안에 자리를 잡고 필요한 만큼의 공간만 차지합니다. 그래서 링크가 자신만의 행으로 줄바꿈되지 않고 문장 안에 그대로 머무는 것입니다. display 속성
모든 요소에는 기본 종류, 즉 블록 또는 인라인이 있지만, 여기에 묶여 있어야 하는 것은 아닙니다. display 속성을 사용하면 요소가 어느 쪽처럼 동작할지 바꿀 수 있습니다. 링크에 display: block을 설정하면 이제 자신만의 줄을 차지하고, 리스트 항목에 display: inline을 설정하면 한 줄 안에 자리를 잡습니다.
흔한 문제를 해결해주는 세 번째 값이 있습니다: display: inline-block입니다. 인라인 박스처럼 줄 안에서 흐르지만, 블록처럼 너비, 높이, 세로 패딩을 받아들입니다. 버튼이나 이웃 요소와 나란히 있으면서도 정해진 크기를 가져야 하는 내비게이션 필(pill) 같은 것에 딱 맞습니다.
.nav-link {
display: inline-block; /* 줄 안에서 흐르지만 width와 padding을 받아들임 */
padding: 8px 16px; /* 순수 인라인과 달리 세로 패딩도 이제 작동함 */
}display 속성은 요소가 블록처럼 동작할지 인라인 박스처럼 동작할지를 바꿉니다. block은 자신만의 줄을 차지하고, inline은 텍스트 줄 안에 자리를 잡습니다. 유용한 중간 옵션은 inline-block으로, 줄 안에서 흐르면서도 너비와 패딩을 받아들여서 버튼이나 내비게이션 링크에 딱 맞습니다. 요소 숨기기: display none과 visibility hidden
때로는 요소가 보이지 않게 만들어야 합니다. 방법은 두 가지가 있고, 서로 다르게 동작합니다. display: none은 요소를 완전히 제거합니다. 요소가 사라지고 빈틈도 남지 않아서, 마치 페이지에 전혀 없었던 것처럼 됩니다. visibility: hidden은 요소를 보이지 않게 만들지만 자리는 그대로 남겨서, 원래 있던 자리에 빈 구멍이 생깁니다.
어느 것을 쓸지는 그 공간을 되돌려받고 싶은지에 따라 달라집니다. 닫힌 메뉴처럼 무언가를 완전히 없애고 싶다면 display: none을 쓰세요. 레이아웃이 갑자기 움직이지 않게 하면서 무언가를 숨기고 싶다면 visibility: hidden을 쓰세요. 그 박스의 자리가 그대로 예약되어 있기 때문입니다.
.closed-menu {
display: none; /* 사라지고, 빈틈도 남지 않음 */
}
.placeholder {
visibility: hidden; /* 보이지 않지만, 여전히 자리를 차지함 */
}display: none은 요소를 제거하고 빈틈도 남기지 않으며, visibility: hidden은 보이지 않게 만들지만 자리는 그대로 유지합니다. 닫힌 메뉴처럼 공간까지 없애고 싶다면 display: none을 선택하세요. 레이아웃이 갑자기 움직이지 않게 하고 싶다면 visibility: hidden을 선택하세요. display가 내부 레이아웃을 바꾸는 방식
여러분은 이미 display가 요소를 블록과 인라인 사이에서 바꾸는 것을 보았습니다. 하지만 더 깊이 들어가면 그 이상의 역할을 합니다. 같은 속성이 컨테이너를 플렉스박스나 그리드로 바꾸는 역할도 하는데, 이 둘은 자식들을 행과 열로 배치하는 현대적인 도구입니다. 지금은 display가 박스가 어떻게 배치되는지, 그리고 그 안의 자식들이 어떻게 배치되는지를 결정하는 단 하나의 다이얼이라는 점만 기억하면 됩니다.
레이아웃은 한 번에 켜는 커다란 스위치가 아닙니다. 다른 배치가 필요한 특정 컨테이너에만 display를 바꾸고, 그대로 두는 나머지는 일반 흐름에 머뭅니다. 플렉스박스와 포지셔닝 장은 여기서부터 이야기를 이어갑니다.
display 속성이, 컨테이너를 자식 배치를 위한 플렉스박스나 그리드로 바꾸는 역할도 합니다. 레이아웃은 한 번에 켜는 스위치가 아닙니다. 필요한 컨테이너에만 display를 바꾸고 나머지는 일반 흐름에 그대로 둡니다. 플렉스박스와 포지셔닝 장이 여기서부터 이야기를 이어갑니다. 
