• 쇼핑몰
  • 커뮤니티
  • 북마크

CSS

FLEXBOX? 강좌1 스크롤100%레이아웃,내비게이션영역

익명
2021.02.24 00:53 6,729 0

본문

마크업 개발자들은 종종 "이 레이아웃은 구현이 불가능합니다.", "CSS만으로는 안될 것 같습니다. 개발 처리가 필요합니다."라고 이야기합니다. 이 말은 사실입니다. 일반적으로 웹 페이지의 레이아웃은 CSS의 displayfloatposition 등과 같은 속성을 사용해 구현합니다. 하지만 이 속성을 사용하면 구현 방법이 복잡하고 레이아웃을 표현하는 데 많은 한계가 있습니다.

구현이 어려운 레이아웃을 간단하게 구현할 수 있게 CSS3에 추가된 레이아웃 방식이 flexbox입니다. flexbox를 사용하면 요소의 크기와 순서를 유연하게 배치할 수 있습니다.

이 글에서는 실무에서 많이 사용하지만 기존의 방식으로는 구현이 어렵거나 불가능한 레이아웃 10개를 선별해 flexbox로 구현하는 방법을 주요 속성 위주로 설명합니다.

flexbox란?

flexbox는 뷰포트나 요소의 크기가 불명확하거나 동적으로 변할 때에도 효율적으로 요소를 배치, 정렬, 분산할 수 있는 방법을 제공하는 CSS3의 새로운 레이아웃 방식이다. flexbox의 장점을 한 마디로 표현하면 '복잡한 계산 없이 요소의 크기와 순서를 유연하게 배치할 수 있다'라고 할 수 있다. 정렬, 방향, 순서, 크기 등을 유연하게 조절할 수 있기 때문에 별도의 분기 처리를 줄일 수 있고, CSS만으로 다양한 레이아웃을 구현할 수 있다.

flexbox의 구성

flexbox는 복수의 자식 요소인 flex item과 그 상위 부모 요소인 flex container로 구성된다.

그림

flexbox를 만드는 방법은 간단하다. 정렬하려는 요소의 부모 요소에 다음과 같이 display: flex 속성을 선언하면 된다.

.flex_container {
  display: flex;
}

display: flex 속성이 적용된 요소는 flex container가 되고, flex container의 자식 요소는 flex item이 된다. flex container와 flex item은 부모 요소와 자식 요소를 한 세트로 사용하는 ul과 li를 생각하면 쉽게 이해할 수 있다.

flex item은 주축(main axis)에 따라 정렬된다. 주축의 방향은 flex container의 flex-direction 속성으로 결정한다. flex-direction 속성을 따로 지정하지 않으면 기본값인 row가 적용된다. 속성값 row는 주축의 방향을 왼쪽에서 오른쪽 방향으로 흐르게 한다. flex-direction 속성의 또 다른 속성값인 column은 주축의 방향을 위에서 아래 방향으로 흐르게 한다.

부모 요소와 자식 요소에 정의하는 속성 구분

flexbox에서 사용하는 속성은 부모 요소인 flex container에 정의하는 속성과 자식 요소인 flex item에 정의하는 속성으로 나누어진다. 전체적인 정렬이나 흐름에 관련된 속성은 flex container에 정의하고, 자식 요소의 크기나 순서에 관련된 속성은 flex item에 정의한다. 이를 분리해 적용하는 것이 중요하다.

  • flex container 속성: flex-directionflex-wrapjustify-contentalign-itemsalign-content
  • flex item 속성: flexflex-growflex-shrinkflex-basisorder

그림

flexbox 지원 범위

flexbox는 Internet Explorer 10 이상이 지원한다. 하지만 Internet Explorer 10 이상이 완전히 지원하지는 않아 Internet Explorer 10과 Internet Explorer 11에서 버그가 발견되기도 한다. 그래서 PC용 서비스에 flexbox를 적용하기에는 아직 이른 감이 있다. 만약 Internet Explorer를 지원하지 않는 서비스를 운영한다면 flexbox를 적용해 봐도 좋다.

모바일 브라우저의 flexbox 지원율은 매우 높다. 거의 대부분의 iOS용 브라우저와 Android용 브라우저가 지원한다고 생각해도 된다(Can I use 사이트의 'flex' 검색 결과 참고).

그림

flexbox를 활용한 10가지 레이아웃 사례

이 글에서는 실무에서 많이 사용하는 다음 10가지 레이아웃을 flexbox로 구현하는 방법을 소개한다. 이 레이아웃은 기존의 display 속성이나 float 속성, position 속성 등으로는 구현이 어렵거나 구현이 불가능하다. 하지만 flexbox를 사용하면 쉽게 구현할 수 있다.

레이아웃 1 - 스크롤 없는 100% 레이아웃

스크롤 없는 100% 레이아웃은 전체 페이지를 구성할 때 자주 사용할 수 있는 레이아웃이다. 다음 그림과 같이 콘텐츠의 길이에 상관없이 브라우저 화면 전체를 채우는 레이아웃이다.

그림

이 레이아웃에서 웹 페이지의 위에 있는 메뉴 영역의 높이는 고정되어 있다. 부모 영역에서 메뉴 영역을 뺀 나머지 영역 전체를 자식 요소가 채운다. 콘텐츠의 길이가 길어지면 스크롤 막대가 브라우저가 아니라 콘텐츠 영역에 나타난다.

스크롤 없는 100% 레이아웃을 구현하는 기본 CSS는 다음과 같다. 구현 예제는 CodePen 사이트의 "1. 스크롤이 없는 100% 레이아웃"에서 확인할 수 있다.

.flex_container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.flex_item {
  flex: 1; /* flex: 1 1 0 */
  overflow: auto;
}

flex container(.flex_container 클래스)에 flex-direction: column 속성을 적용해 flex item을 수직으로 정렬한다. flex item(.flex_item 클래스)에는 flex: 1 속성을 적용해 flex item이 빈 공간을 채우게 한다.

flex-direction: column 속성으로 수직 방향 정렬 설정

flexbox 레이아웃에서 주축의 방향은 왼쪽에서 오른쪽으로 향하는 수평 방향이 기본이다. 하지만 요소를 수직으로 배열하려면 주축이 위에서 아래로 향하게 해야 한다. flex container의 flex-direction 속성의 값을 column으로 설정하면 주축의 방향을 바꿀 수 있다.

그림

flex : 1 속성으로 자식 요소의 크기 확장

flex item에 적용한 flex 속성은 flex item의 크기와 관련된 속성이며, 다음과 같이 flex-grow 속성과 flex-shrink 속성, flex-basis 속성을 축약한 표현이다.

그림

앞의 그림에서 표현한 flex: 1 1 0 속성은 다음과 같은 flex-grow: 1 속성과 flex-shrink: 1 속성, flex-basis: 0 속성을 줄인 표현이다.

.flex-item {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

flex: 1 1 0은 다음과 같이 flex: 1로 표현할 수도 있다.

.flex-item {
  flex: 1;
  /* flex: 1 1 0 */
}

flex-grow 속성

flex-grow 속성은 flex item의 확장에 관련된 속성이다. 0과 양의 정수를 속성값에 사용한다.

속성값이 0이면 flex container의 크기가 커져도 flex item의 크기가 커지지 않고 원래 크기로 유지된다. flex container의 크기가 커질 때 flex item의 크기도 커지게 하려면 1 이상의 값을 속성값으로 설정한다. 속성값이 1 이상이면 flex item의 원래 크기에 상관없이 flex container를 채우도록 flex item의 크기가 커진다.

그림

flex-shrink 속성

flex-shrink 속성은 flex item의 축소에 관련된 속성이다. 0과 양의 정수를 속성값에 사용한다. 기본값은 1이다.

속성값이 0이면 flex container의 크기가 flex item의 크기보다 작아져도 flex item의 크기가 줄어들지 않고 원래 크기로 유지된다. 속성값이 1 이상이면 flex container의 크기가 flex item의 크기보다 작아질 때 flex item의 크기가 flex container의 크기에 맞추어 줄어든다.

그림

flex-basis 속성

flex-basis 속성은 flex item의 기본 크기를 결정하는 속성이다. 기본값은 auto다.

width 속성에서 사용하는 모든 단위(px, %, em, rem 등)를 속성값에 사용할 수 있다. flex-basis 속성의 값을 30px이나 30%와 같이 설정하면 flex item의 크기가 고정된다.

그림

flex-basis 속성에서 auto와 함께 자주 사용하는 속성값이 0이다. flex-basis 속성의 값을 0으로 설정하면 flex item은 절대적 flex item(absolute flex item)이 되어 flex container를 기준으로 크기가 결정된다.

주의
flex-basis 속성의 값을 0으로 선언할 때에는 flex-basis: 0pxflex-basis: 0%와 같이 단위도 함께 설정해야 한다.

flex-basis 속성의 값을 auto로 설정하면 flex item은 상대적 flex item(relative flex item)이 되어 콘텐츠의 크기를 기준으로 크기가 결정된다.

그림

flex: 1의 의미

flex-grow 속성과 flex-shrink 속성, flex-basis 속성을 축약해서 flex 속성으로 표현할 때 flex: 1 속성은 flex: 1 1 0 속성을 의미한다. 즉, flex-grow 속성의 값이 '1'이고 flex-shrink 속성의 값이 '1'이기 때문에 flex container의 크기에 따라 flex item의 크기도 커지거나 작아진다는 의미다.

그림

flex 속성의 값으로 정수 하나만 선언하면 선언한 값은 flex-grow 속성의 값이 된다. 나머지는 기본값인 flex-shrink: 1 속성과 flex-basis: 0 속성이 적용된다. 다시 말해 flex 속성에 한 개의 정숫값만 있으면 이것은 flex-grow 속성의 값만 지정하는 단축 속성이다. 즉, flex: 2는 flex: 2 1 0을, flex: 3은 flex: 3 1 0을 나타내다.

레이아웃 2 - 내비게이션 영역

내비게이션은 웹 페이지에서 자주 사용하는 레이아웃이다. 다음 그림과 같이 메뉴의 대부분을 내비게이션 영역의 왼쪽으로 정렬하고, 1~2개의 메뉴만 오른쪽으로 정렬한 내비게이션을 쉽게 볼 수 있다. 주로 GNB(global navigation bar)에 해당하는 요소나 로그인 버튼을 오른쪽으로 정렬한다.

그림

내비게이션 영역을 구현하는 기본 CSS는 다음과 같다. 구현 예제는 CodePen 사이트의 "2. 네비게이션"에서 확인할 수 있다.

.flex-container {
  display: flex;
}

.flex-item {
  flex: none;
  /* flex: 0 0 auto */    
}

.flex-item-gnb {
  margin-left: auto;
}

크기가 고정되어야 하는 flex item(.flex-item 클래스)에는 flex: none 속성을 적용한다. 오른쪽으로 정렬할 GNB나 로그인 버튼에 해당하는 요소(.flex-item-gnb 클래스)에는 margin-left: auto 속성을 적용한다.

flex: none 속성으로 자식 요소의 크기 고정

내비게이션 영역의 기본 구조에서는 'logo' 요소와 'search' 요소, 'gnb' 요소의 크기가 커지거나 작아지지 않게 디자인했다. flex item의 크기에 관련된 속성인 flex 속성의 기본값은 flex: 0 1 auto다. 기본값을 적용하면 flex container의 크기가 flex item 전체의 크기보다 작아질 때 flex item의 크기가 작아진다. flex item의 크기를 고정하려면 반드시 flex: none 속성을 적용해야 한다.

flex: none은 flex-grow: 0 속성과 flex-shrink: 0 속성, flex-basis: auto 속성을 축약해 표현한 것이다. 하나의 정수를 사용해 축약하는 방법("flex: 1의 의미" 참고) 외에 세 개의 키워드인 initialnoneauto를 flex 속성의 값으로 설정해 속성을 축약할 수 있다.

flex 속성에 사용하는 키워드에 따라 축약되는 속성의 설정값은 다음과 같다.

flexflex-growflex-shrinkflex-basis
initial(기본값)01auto
none00auto
auto11auto
양의 정수숫자10

flex 속성의 값에 따라 flex item의 크기는 다음과 같이 변한다.

  • initial(기본값): flex container의 크기가 작아지면 flex item의 크기가 작아진다. 하지만 flex container의 크기가 커져도 flex item의 크기는 커지지 않는다.
  • none: flex item의 크기가 커지거나 작아지지 않는다. flex container의 크기에 영향을 받지 않고, flex item의 원래 크기를 유지한다.
  • auto: flex container의 크기에 맞추어 flex item의 크기가 커지거나 작아진다.
  • 양의 정수: flex container를 일정한 비율로 나눠 가지면서 flex container의 크기에 따라 flex item의 크기가 커지거나 작아진다.

그림

margin-left: auto 속성으로 자식 요소를 오른쪽에 배치

요소의 바깥 여백(margin)을 설정하는 속성에 속성값으로 auto를 적용하면 flexbox에서 flex item을 쉽게 배치할 수 있다. 예를 들어 margin: auto 속성을 적용하면 flex item의 바깥 여백이 자동으로 확장되어 flex item이 flex container의 가운데에 위치하게 된다.

flex item을 수평으로 배치할 때 다음과 같이 'auto' 속성값을 사용할 수 있다.

  • margin-right: auto: 바깥 여백이 오른쪽의 모든 공간을 차지하기 위해 flex item을 오른쪽에서 왼쪽으로 민다.
  • margin: 0 auto: 바깥 여백이 flex item을 양쪽에서 밀기 때문에 flex item이 수평 중앙에 위치한다.
  • margin-left: auto: 바깥 여백이 왼쪽의 모든 공간을 차지하기 위해 flex item을 왼쪽에서 오른쪽으로 민다.

그림

flex item을 수직으로 배치할 때 다음과 같이 'auto' 속성값을 사용할 수 있다.

  • margin-bottom: auto: 바깥 여백이 아래쪽의 모든 공간을 차지하기 위해 flex item을 아래쪽에서 위쪽으로 민다.
  • margin: auto 0: 바깥 여백이 flex item을 위아래로 밀기 때문에 flex item이 수직 중앙에 위치한다.
  • margin-top: auto: 바깥 여백이 위쪽의 모든 공간을 차지하기 위해 flex item을 위쪽에서 아래쪽으로 민다.

그림

flexbox에서 margin: auto 속성으로 레이아웃을 구현하는 방법이 핵(hack)이라고 생각하거나 버그를 일으키는 요인이 될 수도 있다고 생각할 수 있다. 하지만 

댓글목록 0

등록된 댓글이 없습니다.