CSS 플렉스박스(Flexbox) - 1. 기초

CSS 플랙스 박스는 레이아웃을 만들 수 있는 다양한 방법들 중 가장 유연하고 쉬운 방법중 하나입니다.

인터넷 익스플로러 미지원으로 국내에서는 사용 빈도가 높지 않았지만, 인터넷 익스플로러 퇴출과 함께 가장 강력한 레이아웃 제작 방식이 될 것입니다.

플렉스박스는 이름 그대로 유연한 박스 모델을 제공하며, 특히 정렬 기능이 탁월하기 때문에 여러가지 속성 값을 조합해 위치와 정렬을 맞추는 수고로움을 하지 않아도 되는 장점이 있습니다.

그리드(Grid)와 다른점은 그리드는 테이블 모양으로 정형화 된 형태를 배치하는데 강점이 있는 반면, 플렉스 박스는 비정형 레이아웃을 좀 더 간결하게 정렬해 배치하는데 강점이 있습니다.

예를 들어 다음과 같은 HTML 코드를 플렉스박스로 레이아웃을 만들어 보겠습니다.

<div class="content">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

기본 플렉스박스

가장 간단하게 외부 ".content" 클래스에 플렉스박스 속성을 부여합니다.

내부 요소나 이미지 배너를 배치하는 것을 가정해내부 아이템들의 크기는 200x100px로 크기를 정했습니다.

.content{
    display: flex;
    background-color: #9a9;    
}
.content .item{
    width: 200px;
    height: 100px;
    background-color: #a99;
    margin: 10px;
}

외부 ".content" 요소는 블록 요소의 특성 그대로지만, 플렉스박스 바로 하위의 내부 요소들은 플랙스박스의 속성을 상속받아 인라인블록(inline-block)처럼 자동으로 왼쪽 정렬로 가로로 배치됩니다.

부모 요소에 "display: flex;" 속성 부여만으로 이렇게 자식 요소들이 배치 속성을 가지게 됩니다.

플렉스박스는 바로 하위의 자식 요소들에게만 플렉스박스의 배치가 영향을 미치므로 플렉스박스로 배치할 요소들은 플렉스박스 바로 하위에 배치해야 합니다.

플랙스박스 기본 적용

플랙스박스의 자식 요소들 기본 배치 방향은 가로 방향(row)입니다. 세로 방향(column)으로 속성을 부여해 한 행에 한 아이템만 위치시킬 수도 있습니다. 별도로 배치 방향을 지정하지 않았으면 가로 방향이 자동 적용됩니다.

자식 요소의 배치 방향을 지정하는 속성은 "flex-direction" 이며 "row", "column" 값을 가질 수 있습니다.

.content{
    display: flex;
    flex-direction: column;
    background-color: #9a9;
}
.content .item{
    width: 200px;
    height: 100px;
    background-color: #a99;
    margin: 10px;
}

"column" 속성 값으로 세로 배치를 하면 다음과 같이 세로 방향으로 한 줄로 배치됩니다.

예제는 자식 요소인 ".item" 클래스 요소들의 가로 너비를 200px로 정해서 왼쪽으로 붙어 있는 것이며, 너비를 100%로 지정하면 가로 영역을 다 채우게 됩니다.

속성 값에는 "row-reverse"와 "column-reverse" 가 더 있습니다.

아이템이 배치되는 순서가 반대로 되는 속성 값입니다. 잘 사용되지는 않습니다.

좌우 정렬과 여백

배치 방향과 함께 정렬 방식을 지정해보겠습니다.

플렉스박스의 정렬 속성은 "justify-content" 입니다. CSS에서 일반적으로 정렬을 하는 방법은 가로 방향으로 "left", "center", "right" 를 정하거나, 세로 방향으로 "top", "middle", "bottom" 정하는 방식인데, 플렉스박스의 정렬 방식은 조금 다릅니다.

플렉스박스의 정렬 속성 값은 "flex-start", "flex-end", "center", "space-between", "space-around", "space-evenly" 6개입니다.

플랙스 박스의 정렬 속성은 자식 요소들의 배치 위치와 함께 여백을 주는 방식까지 함께 정할 수 있기 때문에, 자식 요소들이 일정한 규칙을 가지고 정리되어 배치되는 편리함이 있습니다.

특히, "space-between", "space-around", "space-evenly" 속성 값은 요소들 사이의 여백까지 자동으로 배분하기 때문에 자식 요소들을 간격을 두고 간편하게 배치할 수 있습니다.

플렉스박스의 정렬 속성 값은 다음과 같이 정렬됩니다.

정렬 속성 값은 가로 배치(row)일 때만 적용되며 기본 값은 "flex-start" 입니다.

수평 정렬 속성 값 정렬 방식 적용 예
flex-start 시작 위치에서부터 채워서 배치합니다.(요소 사이 여백x)
flex-end 끝 위치에서부터 채워서 배치합니다.(요소 사이 여백x)
center 좌우 같은 여백을 두고 전체 자식 요소를 가운데 배치합니다.(요소 사이 여백x)
space-between 첫 요소 왼쪽과 끝 요소 오른쪽에는 여백이 없으며, 마주 보는 요소들 사이에 여백을 배분해 배치합니다.
space-around 각 요소의 좌우에 같은 여백을 배치합니다. 마주보는 요소 사이는 2배의 여백이 생깁니다.
space-evenly 모든 요소 사이가 같은 여백을 가집니다. 첫 요소 왼쪽과 끝 요소 오른쪽에도 같은 너비의 여백이 생깁니다.

".content" 요소에 패딩으로 여백을 준 경우 "space-between"으로 여백을 주면 불필요한 여백이 생기지 않기 때문에 다음과 같이 적절히 배치된 레이아웃을 만들 수 있습니다.

.content{
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    background-color: #9a9;
    padding: 20px;
    border: 3px dashed #a00;
}
.content .item{
    width: 100px;
    height: 100px;
    background-color: #a99;
    border: 3px dotted #000;
    font-size: 2em;
    line-height: 100px;
    text-align: center;
}

수직 정렬

앞서의 예는 플렉스박스인 ".content" 요소에 높이 값이 지정되지 않았기 때문에 자식 아이템들의 높이에 맞춰 자동으로 정해집니다.

플랙스박스에 높이 값이 있을 경우 다음 처럼 아래쪽으로 많은 여백이 남게 되기 때문에, "align-items" 속성을 사용해 수직 정렬을 합니다.

수직 정렬은 "flex-start", "flex-end", "center", "baseline", "stretch" 5가지가 있습니다.

각각의 수직 정렬 속성은 다음과 같이 아이템들이 정렬됩니다.

수직 정렬 속성 값 설명 적용 예
flex-start 상단 위치를 기준선으로 수직 정렬. 아이템들이 상단 맨위에 정렬됩니다.
flex-end 바닥 위치를 기준선으로 수직 정렬. 아이템들이 하단 바닥에 정렬됩니다.
center 플랙스박스 상단에서 50% 위치의 가로선과 각 아이템 높이의 50% 가로선을 맞춰서 정렬합니다.
baseline 아이템 안에 텍스트 내용이 있을 경우 가장 큰 텍스트의 베이스라인 선을 기준으로 아이템들이 정렬됩니다.
아이템 요소가 플렉스박스 외부로 벗어날 수 있습니다.
stretch 다른 정렬 속성 값과 달리 아이템에 높이 값이 없는 경우에만 적용되며, 아이템 높이를 플렉스박스 높이만큼 늘려서 수직 방향 빈공 간을 모두 채웁니다.
높이 값이 있을 경우 "flex-start"와 동일합니다.

예를 들어 다음과 같이 수평 방향으로 "space-between"을, 수직 방향으로 가운데 정렬을 하면 

.content{
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    background-color: #9a9;
    padding: 20px;
    height: 200px;
    align-items: center;
}
.content .item{
    width: 100px;
    background-color: #a99;
    text-align: center;
}
.content .item:nth-child(1){height:50px;font-size: 2em;}
.content .item:nth-child(2){height:150px;font-size: 3em;}
.content .item:nth-child(3){height:100px;font-size: 5em;}
.content .item:nth-child(4){height:180px;font-size: 1em;}

다음과 같이 배치가 됩니다.

아이템별 수직 정렬

수직 정렬 속성은 플렉스박스 안의 개별 아이템에도 각각 적용할 수 있습니다.

아이템에 수직 정렬을 개별적으로 적용하면 다음과 같이 수직 위치를 임의로 설정할 수 있습니다.

개별 아이템에 수직 정렬을 적용하는 속성은 "align-self" 이며, 속성 값은 플렉스박스 수직 정렬과 동일합니다.

.content .item:nth-child(1){align-self:flex-start;}
.content .item:nth-child(2){align-self:center;}
.content .item:nth-child(3){align-self:flex-end;}
.content .item:nth-child(4){height:auto;align-self:stretch;}