반응형 웹을 위한 CSS 레이아웃 플렉스박스


이미지, 텍스트 등의 요소 위치는 블록/인라인 레벨 요소로 변경할 수 있습니다. 그런데 과연 블록/인라인 레벨 요소만 알면 모든 요소를 원하는 곳에 위치시킬 수 있을까요? 화면 크기가 다양하지 않았던 예전에는 가능했습니다. 고급 기법을 사용한 디자인으로 감싸진 웹 페이지가 많지 않았거든요. 하지만 지금은 다릅니다. 반응형 디자인이 필요할 만큼 화면 해상도가 다양해졌고, 편하고 화려한 디자인으로 제작된 웹 페이지가 많아졌습니다.
더 다양한 레이아웃을 만들고자 고안된 기법이 플렉스박스(flexbox)입니다. 플렉스는 ‘유연한’이란 뜻을 가지고 있어요. 이름만큼이나 화면 레이아웃을 유연하게, 자유자재로 배치할 수 있게 해줍니다. 기존에 사용했던 블록 레벨 요소, 인라인 레벨 요소 방식보다 훨씬 강력하고 편리한 기능이 많죠. 지금부터 신세대 레이아웃, 플렉스박스를 알아보겠습니다.
1 플렉스가 필요한 순간 확인하기
플렉스는 언제 필요할까요? 다음과 같이 body 안에 div로 정사각형 세 개를 만드는 코드가 있습니다.
예제 9-1 div box 3개 만들기 chapter09/01/index.html
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="style.css">
    </head>
    <body> <!-- ❶ -->
        <div></div> <!-- ❷ -->
        <div id="second"></div>
        <div></div>
    </body>
</html>
chapter09/01/style.css
div {
    width: 200px; /* ❸ */
    height: 200px;
    background-color: tomato; /* ❹ */
}
#second {
    background-color: seagreen; /* ❺ */ 
}
HTML 코드에서 body를 부모로, 3가지 div를 그 자식으로 설정합니다. CSS 파일에는 div 태그에 가로(width), 세로(height) 길이를 정해주고 배경색(background-color)을 넣어줬습니다. 또한 div 박스 사이의 구별이 쉽도록 가운데 박스에 id값을 주어 배경색을 초록색으로 설정합니다.
div 박스가 나란히 있지 않고 줄바꿈이 되는 이유는 div가 블록 레벨 요소여서 그래요. 검사 기능으로 체크해봅시다.
제일 위에 있는 주황색 div 박스에 마우스를 갖다대고 우클릭→ [검사(N)] 클릭→ 우하단에서 margin 영역에 마우스 갖다대주세요.
margin값이 자리를 차지하고 있습니다. 이 마진을 어떻게 없앨 수 있을까요? 그렇습니다. 바로 플렉스박스를 사용하면 됩니다! 물론 display 값을 인라인으로 바꿔도 가능하지만 이번에는 플렉스박스만를 활용해봅시다.
2 플렉스박스로 정렬하기
플렉스박스는 사용자 인터페이스 디자인에 최적화된 레이아웃을 정의하는 CSS입니다. 이미지, 텍스트 같은 요소를 원하는 곳에 배치하는 데 사용합니다. 인라인이 단순히 여백을 없애는 데 사용한다면, 플렉스박스는 여백을 없앨 뿐만 아니라 축을 변경한다든지, 자식 간의 정렬을 가운데로 맞출 때도 사용합니다. 즉 유연하게 박스 레이아웃을 변경할 수 있다는 장점이 있습니다.
플렉스박스 제1 원칙은 ‘부모만이 플렉스할 수 있다’입니다. 플렉스박스를 사용하려면 부모자식 관계에서 부모에 적용해야 자식이 영향을 받습니다. 플렉스박스의 사용 방법은 다음과 같습니다.
꼭! 부모 태그를 선택자로 지정해주세요. 그럼 이제부터 플렉스박스 특징(장점) 3가지를 다뤄보겠습니다.
1 공간에 맞추기 : display flex
2 주축 정렬하기
3 교차 축 정렬하기
2.1 공간에 맞추기 : display flex
display 속성은 block, inline, flow, grid, flex가 있습니다. 우리는 그 중 flex를 배워보겠습니다. flex는 자식 요소를 원하는 방향으로 유연하게 배치할 수 있어 자주 사용하는 속성입니다.
예제 9-2 body에 플렉스박스 적용 chapter09/02/style.css
body {
    display: flex; /* ❶ */
}
div {
    width: 200px;
    height: 200px;
    background-color: tomato;
}
#second {
    background-color: seagreen;
}
어때요? body 태그에 display 값을 flex로 선언했더니 감쪽같이 마진이 사라져 모든 div가 한 줄에 놓이게 되었죠? 다시 한 번 말씀드리면 플렉스박스의 첫 번째 규칙은 자식에 명시하지 않고 부모에 명시한다는 겁니다. 즉 부모의 display 값을 기본 설정인 block에서 flex로 바꾸는 겁니다. 이렇게 플렉스박스를 사용하면 추가적인 속성을 지정할 수 있습니다. 그중에 하나가 justify-content 속성입니다.
2.2 주축 정렬하기 : justify-content
justify-content 속성은 웹 페이지의 축을 따라 요소 사이에 공간을 만드는 방법을 정의합니다. 여기서 말하는 축이란 주축과 교차축을 말합니다. 별도의 설정이 없다면 주축은 가로를, 교차축은 세로를 기본값으로 가집니다. 하지만 이 둘은 flex-direction이라는 속성을 사용하여 축을 변경 해줄 수 있기 때문에 가로, 세로 대신 주축, 교차축이라고 지칭합니다. 따라서 기본값에서 주축이었던 가로 방향을 flex-direction을 사용해서 세로로 바꾸면 주축은 세로 방향이 되는 겁니다.
다시 말해 flexbox는 두 축(주축, 교차축)을 기준으로 움직이기 때문에 축 방향을 기준으로 요소를 움직일 줄 알아야 합니다. 우선 주축 정렬을 담당하는 justify-content를 알아보겠습니다. justify-content 속성에는 다음과 같은 값이 올 수 있습니다.
flex-start : 시작 부분에 정렬
flex-end : 끝에 정렬
center : 중앙에 정렬
space-between : 요소가 축을 따라 펼쳐집니다(각 요소 사이에 공간이 있음).
space-around : 요소가 축을 따라 펼쳐지지만 가장자리 주변에도 공간이 있습니다.
이해를 돕는 그림으로 속성별 배치를 확인해봅시다.
이번에는 주축을 가운데로 정렬하는 예제를 살펴보겠습니다. flex를 적용한 코드에서 body 태그의 주축을 가운데로 정렬해보겠습니다.
예제 9-3 justify-content 중앙 정렬 chapter09/03/style.css
body {
    display: flex;
    justify-content: center; /* 1 */
}
div {
    width: 200px;
    height: 200px;
    background-color: tomato;
}
#second {
    background-color: seagreen;
}
CSS에 body 태그의 주축을 가운데로 지정합니다. 그러면 자식인 div 박스가 가운데로 정렬됩니다. 특히 justify-content를 이용한 가운데 정렬이 좋은 이유는 반응형이기 때문이에요. 화면 크기를 바꿔도 div 박스는 가운데를 유지합니다.
이번에는 justify-content값을 center에서 space-between으로 변경해보겠습니다.
예제 9-4 justify-content 일정한 간격으로 정렬 chapter09/04/style.css
body {
    display: flex;
    justify-content: space-between; /* ❶ */
}
div {
    width: 200px;
    height: 200px;
    background-color: tomato;
}
#second {
    background-color: seagreen;
}
body 태그의 justify-content 값을 space-between으로 지정합니다. 자식인 div 박스가 균 등한 간격으로 떨어집니다. 역시 반응형이기 때문에 화면 길이를 변경하면 박스도 함께 움직여 간격이 계속 균등하게 유지됩니다. space-between은 유용하게 쓰이니 기억해둡시다. 이렇게 하나씩 시도해보면 각 값이 어떤 역할을 하는지 알 수 있습니다.
이제 flex-start, flex-end를 사용하는 방법도 아시겠죠? 간단하게 결과만 보여드릴 테니 한번 시도해보세요!

justify-content: flex-start;

justify-content: flex-end;
그럼 여기서 div 박스를 세로축으로 가운데 정렬하고 싶으면 어떻게 해야 할까요? 그땐 align-items라는 교차축 정렬 속성을 사용하면 됩니다.
2.3 교차축 정렬하기 : align-items
align-items 속성은 교차축을 정렬합니다(flex-direction으로 축 방향을 변경해주지 않는 한 기본값인 세로축을 정렬합니다). align-items에는 다음과 같은 속성값이 올 수 있습니다.
stretch : 요소의 길이와 교차축의 길이를 같게 함
flex-start : 시작 위치에 정렬
flex-end : 끝 정렬
center : 중앙 정렬
그림으로 속성별 배치를 확인해봅시다.
align-items를 이용한 교차축 가운데 정렬 예제를 살펴봅시다.
예제 9-5 align-items를 이용한 세로축 가운데 정렬 chapter09/05/style.css
html, 
body {
    height: 100%; /* ❶ */ 
}
body {
    display: flex;
    align-items: center; /* ❷ */
}
div {
    width: 200px;
    height: 200px;
    background-color: tomato;
}
#second {
     background-color: seagreen;
}
부모인 body에 align-itmes: center를 입력합니다. html과 body의 height 값을 100%로 지정합니다.
html과 body에 height값을 100%로 주어야 합니다!
높이를 지정하지 않으면 화면의 높이는 요소 중 가장 긴 길이를 가진 요소를 기준으로 높이를 정합니다. 예제를 통해 알아봅시다. 화면의 높이를 알아보기 위해 div 태그를 직사각형으로 만들고 테두리를 주겠습니다.
이렇듯 화면의 높이는 가장 큰 요소를 기준으로 지정됩니다. 중요한 것은 우리가 보는 화면의 흰 여백은 HTML이 제공하는 영역(높이)에 속하지 않는다는 점입니다. 이 상태 에서 가로, 세로 중앙 정렬을 하면 어떻게 될까요?
가로축은 화면 길이만큼 지정됐기 때문에 우리가 바라는 모습의 중앙 정렬이 되었지만, 세로축은 가장 큰 요소의 높이를 기준으로 중앙 정렬되어 우리가 의도한 브라우저 전체 화면에서의 정렬이 되지 않았습니다.
이를 해결하기 위해 직접 높이를 지정하는 방법이 있습니다. 비율(%)을 이용하여 높잇값을 100%로 지정해주는 방법입니다. 이때 주의할 점은 html 태그와 body 태그 모두 높잇값을 100%로 지정해주어야 한다는 점입니다(50%면 가장 긴 요소보다 border 영역이 줄어들고 200%면 훨씬 길어집니다). 우선 적용해볼까요?
우리가 의도한 대로 가로, 세로 중앙 정렬이 되었습니다. 그럼 높이를 100%로 지정해줘야 한다는 건 알겠는데 왜 html과 body 태그 모두 지정해주어야 할까요? 왜냐하면 %는 부모 요소에 대해 상대적으로 길이가 정해지기 때문입니다. 즉, div 태그는 부모인 body 태그와 최상위 부모인 html 태그의 높이에 대해 상대적으로 100%라는 값을 가지는 거예요.
이번에는 stretch를 실습해보겠습니다. 스트레칭할 때 몸을 쭉 늘리잖아요. 그러니까 stretch도 교차축 기준으로 화면 길이에 맞게 요소를 늘리지 않을까 예상해봅니다. 함께 예제를 실행해보겠습니다.
예제 9-6 align-items stretch chapter09/06/style.css
html, 
body {
    height: 100%;
}
body {
    display: flex;
    align-items: stretch; /* ❶ */
}
div {
    width: 200px;
    background-color: tomato; /* ❷ */ }
#second {
    background-color: seagreen;
}
부모인 body에 align-items 속성값으로 stretch를 입력하고 div 태그에 height값을 삭제합니다.
div의 높잇값을 삭제하지 않은 align-items에서 stretch만 바꾸면 아무런 반응이 일어나지 않을 수 있습니다. 여기 해당되는 분들은 div의 높이를 지정하는 코드가 display: stretch 코드보다 아래에 적혀 있을 가능성이 높습니다. 코드는 위에서 아래로 읽으며 실행되기 때문에 아래 코드가 최종 반영됩니다. stretch로 늘렸지만 이후에 높이를 고정했기 때문에 변하지 않는 겁니다. 하지만 높잇값을 지정하지 않으면 자동으로 높잇값에 맞춰 div 박스 길이가 늘어납니다.
지금까지 교차축으로 정렬하는 두 가지 속성값을 다뤘습니다. flex-start와 flex-end는 어디에 위치할지 감이 오시죠? 맞습니다. flex-start는 교차축(여기선 세로축)을 기준으로 하여 상단에, flex-end는 하단에 위치합니다. 각자 코드를 수정해서 확인해주세요. 결과는 다음과 같습니다.
flex-end에서는 마찬가지로 html과 body 높이에 100%를 주어야 적용됩니다. 왜냐하면 html 과 body의 높잇값이 가장 큰 요소의 길이를 기준으로 정의되기 때문입니다.
예제 9-6 align-items stretch chapter09/06/style.css
html, 
body {
    height: 100%;
}
3 플렉스 축 방향 바꾸기 : flex-direction
justify-content가 주축을 정렬하고, align-items가 교차축을 정렬합니다. 별도의 속성 지정이 없다면 주축은 가로를, 교차축은 세로를 의미하지만 앞서 말씀드렸듯이 이 축은 flex-direction에 의해 바뀔 수 있습니다. direction이 방향이라는 의미를 가지고 있는데 flex-direction이니까 플렉스의 축 방향을 바꿔주는 속성이라고 생각하시면 됩니다. flex-direction은 축 방향을 지정합니다. 지정하는 방식은 다음과 같습니다.
flex-direction 속성에는 다음과 같은 값이 올 수 있습니다.
row(기본값) : 가로 방향(행) 배치
row-reverse : 역순으로 가로 방향(행) 배치
column : 세로 방향(열) 배치
column-reverse : 역순으로 세로 방향(열) 배치
그림으로 속성별 배치 방향을 확인해봅시다.
flex-direction을 사용하여 축 방향을 지정하는 예제를 살펴봅시다.
예제 9-7 flex-direction 사용하기 chapter09/07/style.css
html, 
body {
    height: 100%;
}
body {
    display: flex;
    flex-direction: column; /* ❶ */ 
    justify-content: center; /* ❷ */
}
div {
    width: 100px;
    height: 100px;
    background-color: tomato;
}
#second {
    background-color: seagreen;
}
flex-direction: column을 입력해서 주축을 세로 방향으로 변경합니다.
justify-content: center를 입력해서 주축 기준 가운데로 옮깁니다.
flex-direction을 지정해주지 않고 justify-content를 사용하면 요소가 주축이 기본값인 가로 방향을 기준으로 가운데에 위치합니다. 하지만 flex-direction으로 주축을 세로 방향으로 지정해주었기 때문에 세로 방향을 기준으로 가운데에 위치했습니다. 이렇듯 주축과 교차축은 무조건적으로 가로, 세로를 담당하는 것이 아닌 flex-direction에 의해 자유롭게 바뀔 수 있습니다.
이번엔 align-items에 flex-end를 줘보겠습니다.
예제 9-8 align-items 위치 변경 chapter09/08/style.css
html, 
body {
    height: 100%;
}
body {
    display: flex;
    flex-direction: column; 
    justify-content: flex-end; /* ❶ */
}
div {
    width: 100px;
    height: 100px;
    background-color: tomato;
}
#second {
    background-color: seagreen;
}
justify-content에 flex-end를 입력합니다. 주축이 세로 방향이기 때문에 세로축 기준 맨 밑으로 이동합니다. 헷갈릴 겁니다. 처음이니 괜찮습니다. 그런 의미에서 정리를 해 볼까요?
3.1 축 방향 바꾸기 정리
justify-content와 align-items는 각각 주축과 교차축을 의미하며 가로축, 세로축을 기본값으로 가지고 있습니다. 하지만 flex-direction으로 주축과 교차축을 바꿀 수 있습니다. 즉, flex-direction에 row, column 중 어떤 값을 주는지에 따라 주축과 교차축이 변하게 됩니다. 그리고 이 방법을 사용하면 div 태그를 비롯한 모든 요소의 축을 자유롭게 움직일 수 있게 되는 거예요.
예를 들어 가로로 정렬되어 있는 텍스트를 세로로 정렬하고 싶을 때 사용할 수 있습니다.
플렉스박스는 이 외에도 많은 속성과 기능을 제공합니다. 하지만 다 알려드리면 너무 어렵다고 느끼실 거예요. 플렉스박스라는 것이 무엇인지 알고 기본 속성을 사용할 수 있으면 충분합니다. 지금은요!
학습 마무리
지금까지 플렉스박스를 알아봤습니다. 원하는 대로 display 속성을 바꾸고 축 방향을 정렬해 디자인을 할 수 있게 된 겁니다. 오늘 내용은 굉장히 중요하니까 핵심 요약으로 다시 복습해봅시다.
핵심 요약
justify-content와 align-items는 각각 주축과 교차축을 의미하며 가로축, 세로축을 기본값으로 가지고 있습니다. 하지만 flex-direction으로 주축과 교차축을 바꿀 수 있습니다. 즉, flex-direction에 row, column 중 어떤 값을 주는지에 따라 주축과 교차축이 변하게 됩니다. 그리고 이 방법을 사용하면 div 태그를 비롯한 모든 요소의 축을 자유롭게 움직일 수 있게 되는 거예요.
1 플렉스박스는 사용자 인터페이스 디자인에 최적화된 CSS입니다. CSS 박스 모델과 유사한 방식으로 레이아웃을 정의할 수 있습니다.
2 플렉스박스에서 사용할 수 있는 속성은 다음과 같습니다. 부모 태그를 선택자로 지정해야 한 다는 점에 유의해주세요.
공간 맞추기 display: flex
주축 정렬하기 justify-content
교차축 정렬하기 align-items
3 flex-direction은 플렉스의 축 방향을 지정합니다. 대표적인 값으로 row, column이 있습니다.

임효성
영상, 디자인, 개발 등 다양한 분야에 관심을 가지고 있습니다. 유튜버이자 프리랜서로 일하고 있습니다. 비전공자를 위한 코딩 30일 챌린지 영상으로 50만 조회수를 기록했으며, 개발자와 협업하여 웹 사이트 제작을 담당했습니다. 현재는 웹 프론트엔드 개발자의 꿈을 더 키워 가고 있습니다.

Leave a Reply

©2020 GoldenRabbit. All rights reserved.
서울시 마포구 신촌로2길 19 302호 (우)04051
master@goldenrabbit.co.kr
개인정보처리방침