Computer >> 컴퓨터 >  >> 프로그래밍 >> CSS

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

CSS 플렉스박스(Flexbox) 모델은 기존의 CSS 박스 모델(Box Model)을 개선하기 위해 만들어졌습니다. 플렉스박스 모델 역시 박스 모델의 핵심 요소인 마진(margin), 패딩(padding), 보더(border), 콘텐츠(content)를 그대로 포함하고 있지만, 부모 컨테이너 안에서 자식 요소들이 남은 공간을 가장 효율적으로 채울 수 있도록 유연성(flexibility)을 제공한다는 점이 큰 차이입니다.

이 튜토리얼을 통해 플렉스박스 모듈의 핵심 개념을 이해하고, 여러분의 웹사이트를 더욱 반응형으로 만드는 첫걸음을 내디뎌 보세요.

아래는 기본적인 플렉스박스 데모를 위한 시작 코드입니다. 설명과 함께 코드를 직접 따라 해 보세요!

<!DOCTYPE html>
  <head>
    <title>Flexbox</title>
    <style>
       * {
        	box-sizing: border-box;
        	font-family: 'Roboto'
       }
      .parent-container {
        	height: 700px;
        	background: green;
        	width: 700px;
        	padding: 20px;
      }
      .child-item {
        	height: 200px;
        	width: 200px;
        	margin: 0px;
        	padding: 20px;
      }
      .child-item:first-child {
        background: orange;
      }
      
      .child-item.one {
        background: purple;
      }
      .child-item.two {
        background: aliceblue;
      }
      .child-item.three {
        background: grey;
      }
      .child-item.four {
        background: pink;
      }
      .child-item.five {
        background: yellowgreen;
      }
      .child-item.six {
        background: red;
      }
      .child-item.seven {
        background: blanchedalmond;
      }
      .child-item.eight {
        background: white;
      }
      .child-item.nine {
        background: lightblue;
      }
      .child-item.nine {
        background: darkred;
      }
      .child-item:last-child {
        background: yellow;
      }

	</style>
 </head>
 <body>
  	<div class="parent-container">
		<div class="child-item">Lisa Simpson</div>
        	<div class="child-item one">Bart Simpson</div>
        	<div class="child-item two">Maggie Simpson</div>
        	<div class="child-item three">Homer Simpson</div>
        	<div class="child-item four">Marge Simpson</div>
        	<div class="child-item five">Grampa Simpson</div>
        	<div class="child-item six">Santa's Little Helper</div>
        	<div class="child-item seven">Apu Nahasapeemapetilon</div>
        	<div class="child-item eight">Moe Szyslak</div>
        	<div class="child-item nine">Ned Flanders</div>
        	<div class="child-item ten">Snowball II</div>
    </div>

	<script src="" async defer></script>
 </body>
</html>

부모 컨테이너(플렉스박스) 속성

display: flex

display 속성에는 화면상에서 컨테이너를 배치하는 데 사용할 수 있는 다양한 값들이 있습니다. block, inline-block, none, hidden, inline 등은 이미 익숙할 텐데요, 지금 우리가 집중적으로 살펴볼 값은 바로 flex입니다.

먼저 큰 상자 하나를 상상해 보세요. 보물상자, 장난감 상자, 혹은 골판지 상자가 좋겠네요. 그리고 그 상자 안에 물건들을 넣는다고 생각해 봅시다. 이때 큰 상자가 바로 부모(parent), 즉 플렉스박스(flexbox)이고, 상자 안에 들어가는 작은 물건들은 자식(children), 즉 플렉스 아이템(flex item)이라고 부릅니다.

부모 컨테이너에 display:flex를 적용하면, 이 속성은 해당 컨테이너에만 할당됩니다. 자식 요소들은 이 속성을 상속하지 않습니다(다만 자식 요소 역시 자신만의 컨테이너에 이 속성을 사용해, 그들의 자식에게 영향을 줄 수는 있습니다).

display:flex를 적용하면 이전에는 사용할 수 없었던 다양한 속성들의 문이 열립니다: flex-direction, justify-content, align-items, align-self, flex-wrap, flex-flow 등이 그것입니다.

위의 코드 에디터를 실행해 보세요. 현재는 초록색의 큰 부모 컨테이너와, 그 안에 담긴 11개의 작은 자식 컨테이너가 보일 것입니다.

자식 컨테이너들이 서로 겹쳐서 위아래로 쌓여 있는 이유는 기본값이 display: block이기 때문입니다. block 방식에서는 각 컨테이너가 자신이 속한 행 전체를 차지하며, 마진 역시 부모 컨테이너의 너비만큼 확장되기 때문에 자식 컨테이너들이 세로로 쌓이게 됩니다.

반면 display: flex를 사용하면 float나 vertical-align 같은 구식 박스 모델 속성에 의존하지 않고도, 자식 컨테이너들을 부모 안에서 원하는 대로 자유롭게 배치할 수 있습니다.

코드 에디터의 style 태그에 display: flex를 추가해서 부모 컨테이너의 CSS를 아래와 같이 만들어 보세요:

.parent-container {
height: 700px;
background: green;
width: 700px;
padding: 20px;
display: flex;

.parent-containerdisplay: flex를 추가하면 자식 컨테이너들의 배치 방향이 달라집니다. 저장 후 실행하면 이제 자식 컨테이너들이 나란히 배치되어 있는 것을 확인할 수 있습니다.

display: block 대신 display: flex를 사용하면 기본 마진이 0으로 설정됩니다. 이제 우리는 마진을 원하는 대로 자유롭게 조작할 수 있습니다!

flex-direction

flex-direction 속성은 컨테이너의 주축(main axis)을 설정합니다. 플렉스 컨테이너의 기본값은 row입니다. 따라서 display:flex로 부모 컨테이너를 설정할 때, 콘텐츠를 세로(column)로 배치해야 하는 경우가 아니라면 굳이 flex-direction을 지정할 필요가 없습니다.

기본 방향에서 주축은 왼쪽에서 오른쪽으로, 교차축(cross axis)은 위에서 아래로 향합니다. 아래 이미지를 참고하세요.

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

이제 위 코드 에디터의 .parent-containerflex-direction: column을 추가해 보세요. 어떤 변화가 일어날까요?

flex-direction을 column으로 바꾸면 축이 서로 뒤바뀝니다. 기존의 주축은 교차축이 되고, 교차축은 주축이 됩니다. 아래 그림처럼 말이죠.

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

그 결과, 예제의 자식 컨테이너들도 축이 뒤바뀌어 다시 위아래로 쌓이게 됩니다.

flex-direction에서 가장 중요하게 기억할 점은, 주축의 방향이 flex-direction 속성값과 일치한다는 것입니다(column은 위에서 아래로, row는 왼쪽에서 오른쪽).

justify-content는 주축 방향의 간격을, align-items는 교차축 방향의 간격을 담당합니다. 이 속성들은 조금 뒤에서 자세히 다루겠습니다.

flex-direction에는 두 가지 값이 더 있습니다: row-reversecolumn-reverse입니다. 이 값들은 row 및 column과 유사하지만, 플렉스 아이템들이 역순으로 배치된다는 차이가 있습니다. row-reverse는 오른쪽에서 왼쪽으로, column-reverse는 아래에서 위로 배치됩니다.

이 값들은 웹 버전과 모바일·태블릿 버전에서 서로 다른 레이아웃 순서를 적용해야 할 때 특히 유용합니다.

flex-wrap

지금까지 우리는 display: flex가 부모의 자식 컨테이너에 미치는 영향과, row 또는 column 방향으로 흐름을 조작하는 방법을 배웠습니다. 그렇다면 부모 컨테이너의 공간이 부족해지면 어떻게 될까요? 그리고 이 문제는 어떻게 해결할 수 있을까요?

해답은 바로 flex-wrap 속성입니다. 기본값은 nowrap으로, 이 경우 자식 컨테이너들이 부모 컨테이너를 넘어서 오버플로우되어 의도치 않은 레이아웃 문제를 일으킬 수 있습니다. .parent-containerflex-wrap: wrap;을 추가하고 결과를 확인해 봅시다.

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

레이아웃이 한결 깔끔해진 것이 보이시나요? flex-wrap은 모든 자식 요소를 나란히 배치하다가 부모 컨테이너의 너비에 도달하면 다음 행으로 넘어가고, 모든 컨테이너가 표시될 때까지 이 과정을 반복합니다.

flex-wrap에는 nowrap, wrap, wrap-reverse 세 가지 값을 사용할 수 있습니다. wrap-reverse는 wrap과 동일하지만, 위에서 아래로가 아닌 아래에서 위로 흐른다는 점이 다릅니다.

flex-flow

flex-flow는 flex-directionflex-wrap의 축약형(shorthand) 속성입니다. 예를 들어 flex-direction을 column으로, flex-wrap을 wrap으로 설정하고 싶다면 flex-flow: column wrap처럼 한 번에 작성하면 됩니다. 기본값은 flex-flow: row nowrap입니다.

justify-content

justify-content 속성은 부모 컨테이너의 주축을 따라 정렬하는 역할을 합니다. 필요한 공간을 직접 계산할 필요 없이, 플렉스 아이템들을 주축을 따라 자동으로 분배해 줍니다. 가장 많이 사용되는 여섯 가지 값은 flex-start(기본값), flex-end, center, space-around, space-between, space-evenly입니다.

flex-start:

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

flex-end:

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

center:

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

space-around:

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

space-between:

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

space-evenly:

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

align-items

align-items와 justify-content의 가장 큰 차이점은, 자식 컨테이너를 배치하는 축이 다르다는 것 외에도 기본값에 있습니다. 앞서 언급했듯이 flex-direction을 사용할 때 justify-content의 기본값은 flex-start입니다. 하지만 align-items의 기본값은 그렇지 않습니다. align-items의 기본값은 stretch입니다.

이를 확인해 보기 위해, 페이지 상단의 코드 에디터로 돌아가 .child-container의 width와 height를 제거해 봅시다. 이미 display: flexflex-direction은 설정되어 있습니다. 이제 flex-direction: rowflex-direction: column을 번갈아 적용하면서, 제약 없이 놓인 컨테이너가 어떻게 동작하는지 관찰해 보세요. 예상과 같은 결과인가요?

align-items 규칙이 설정되어 있지 않으면, 자식 컨테이너는 교차축 방향으로 부모 컨테이너의 크기만큼 늘어납니다(stretch). 하지만 부모 컨테이너에 align-items 속성을 설정하면, 자식 컨테이너의 크기는 콘텐츠 크기에 패딩과 보더를 더한 크기에 맞춰 자동으로 조정됩니다.

align-items: stretch

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

align-items: center

CSS 플렉스박스(Flexbox) 완벽 가이드: 반응형 레이아웃의 기초

앞서 justify-content에서 살펴본 나머지 속성들도 align-items에 동일하게 적용되며, 의미 또한 같습니다. 단지 적용되는 축이 바뀔 뿐입니다.

자식 컨테이너(플렉스 아이템) 속성

order

일반적으로 부모 컴포넌트 안의 컨테이너 순서는 HTML 파일에 작성된 순서를 따릅니다. 하지만 컨테이너의 순서를 직접 제어하고 싶다면, 예를 들어 모바일 환경에서 특정 자식 컨테이너를 먼저 강조하고 싶을 때, order 속성을 사용하면 됩니다. order 속성은 숫자 값을 받으며, 화면에 표시될 때 자식 컨테이너들이 어떤 순서로 배치될지를 결정합니다.

align-self

align-self는 기본 정렬 방식이나 부모의 align-items로 설정된 정렬을 개별적으로 재정의(override)할 수 있게 해 줍니다. 단, align-self는 부모 자체가 display: flex일 때만 동작한다는 점을 기억하세요. 사용할 수 있는 값은 flex-start, flex-end, baseline, stretch입니다.

마무리

이번 튜토리얼에서는 플렉시블 박스 모델의 기본기를 다뤘습니다. 플렉스박스는 부모 컨테이너와 자식 컨테이너 사이의 관계로 이루어져 있으며, 부모의 플렉스박스 속성이 자식 컨테이너들이 부모의 여유 공간에서 움직이는 방식에 직접적인 영향을 준다는 것을 알게 되었습니다.

flex-direction, justify-content, align-items, flex-wrap을 사용해 부모 안에서 자식의 위치를 조작하고, 자식 쪽에서는 order와 align-self를 사용해 부모에 설정된 기본값이나 규칙을 재정의할 수 있습니다.

위의 코드 에디터를 활용해 이 속성들을 직접 실험해 보며 연습해 보세요. 여러분은 이미 플렉스박스 전문가로 가는 길을 잘 걷고 있습니다!