플렉스와 그리드

flex

Flex플렉스는 플렉서블박스, 플렉스박스라고 부르기도 한다. 레이아웃 배치 전용 기능으로 고안되었으며 float나 inline-block등을 이용한 기존 방식보다 강력하고 편리하다. 처음 개발을 시작하고나서 html,css를 배운지 얼마 지나지 않아서 flex를 배웠고 (물론 아주 기본만, 지금도 마찬가지) 그 후로 간단한 정렬들을 모두 플렉스를 사용해서 했지만, 항상 사용하는 부분만 사용하고 활용을 잘 하지 못하는 것같아서 정리하기로 하였다.
Grid가 나왔다해서 Flex가 마냥 뒤떨어진다거나 불편하거나 하지는 않다. 오히려 Grid로 구현이 까다로운 레이아웃이 Flex로 편하게 잡힐 수 있고, 브라우저 지원같은경우 Flex가 호환이 잘되기 떄문에 둘 다 잘알아두고 적재적소에 활용하는것이 중요!

기본적인 구조

<div class="container">
  <div class="item">item1</div>
  <div class="item">item2</div>
  <div class="item">item3</div>
</div>

부모 요소인 div.container를 Flex Container라고 부르고, 자식 요소인 item들을 Flex Item이라고 부른다. 쉽게 생각하면 컨테이너가 Flex의 영향을 받는 전체 공간이고, 설정된 속성에 따라 각각의 아이템들이 속성에 따라 배치되는것 이런 느낌이다.
Flex 의 속성들은 컨테이너에 적용하는 속성, 아이템에 적용하는 속성 이렇게 두 가지로 나뉜다.

컨테이너에 적용하는 속성

display: flex;

일단 Flex다보니 display:flex를 적용하는게 우선이다.

.container {
  display: flex;
}

위의 코드로 아이템들이 인라인형태로 정렬되서 배치가 된다.
아이템들은 가로 방향으로 배치되고, 내용물의 넓이만큼 차지하게 된다. 마치 인라인 ㄴ요소와 같다. 높이는 컨테이너의 높이만큼 느어난다.

.container {
  display: inline-flex;
}

인라인플렉스도 있다. 얼마전에 정리한 내용인데 block과 inline-block의 관계를 생각하면 된다. 컨테이너가 주변의 요소들과 어떻게 어우러질지 결정하는 값이며 컨테이너 자체가 inline속성을 띈다.

배치방향 flex-direction

말 그대로 아이템들이 배치되는 축의 방향을 결정하는 속성이다. 방향을 가로로 할것이냐 세로로 할것이냐

.container {
  flex-direction: row;
  /* flex-direction: column; */
  /* flex-direction: row-reverse; */
  /* flex-direction: column-reverse; */
}
row (기본값)

아이템들이 가로방향으로 배치된다

row-reverse

아이템들이 역순으로 가로 배치된다.

column

아이템들이 세로방향으로 배치된다.

column-reverse

아이템들이 역순으로 세로 배치된다.

줄넘김 처리 flex-wrap

컨테이너가 아이템들을 한 줄에 담을 공간이 없을 떄 아이템 줄바꿈을 어떻게 할지 결정하는 속성.

.container {
  flex-wrap: nowrap;
  /* flex-wrap: wrap; */
  /* flex-wrap: wrap-reverse; */
}
nowrap(기본값)

줄바꿈을 하지 않는다, 넘으면 튀어 나간다.

wrap

줄바꿈을 한다. float이나 inline-block으로 배치한 요소들과 비슷하게 동작

wrap-reverse

줄바꿈을 하며, 아이템을 역순으로 배치한다.

flex-flow

flex-direction과 flex-wrap을 한꺼번에 지정할 수 있는 단축 속성이다. flex-direction, flex-wrap 순으로 한칸 떼고 써준다.

.container {
  flex-flow: row wrap;
}

가로 방향 정렬 justify-content

정렬에서 justify키워드와 align키워드가 많이 쓰이는데, justify는 가로 방향으로 정렬, align은 세로 방향으로 정렬의 키워드이다.
justify-conten는 가로 방향으로 아이템들을 정렬하는 속성이다

.container {
  justify-content: flex-start;
  justify-content: flex-end;
  justify-content: center;
  justify-content: space-between;
  justify-content: space-around;
  justify-content: space-evenly;
}
flex-start(기본값)

아이템들을 시작점으로 정렬한다. 가로일때는 왼쪽, 세로일때는 위이다.

flex-end

아이템들을 끝점으로 정렬한다. 스타트와 반대

center

아이템들을 가운데로 정렬한다.

space-between

아이템들의 사이에 균일한 간격을 만들어준다.

space-around

아이템들의 둘레에 균일한 간격을 만들어 준다.

space-evenly

아이템들의 사이와 양 끝에 균일한 간격을 만들어 준다. 이 속성은 IE와 Edge에서는 지원이 되지 않는다.

수직 정렬 align-items

align키워드 이므로 수직축 방향으로 아이템들을 정렬하는 속성이다.

.container {
  align-items: stretch;
  align-items: flex-start;
  align-items: flex-end;
  align-items: center;
  align-items: baseline;
}
stretch(기본값)

아이템들이 수직축 방향으로 끝까지 쭉 늘어난다.

flex-start

아이템들을 시작점으로 정렬한다.

center

아이템들을 가운데로 정렬한다.

baseline

아이템들을 텍스트 베이스라인 기준으로 정렬한다.

.container {
  justify-content: center;
  align-items: center;
}

위처럼 한가운데로 정렬할 수 있따.

여러행 정렬 align-content

flex-wrap: wrap;이 설정된 상태에서, 아이템들의 행이 2줄 이상이 되었을 때 수직축 방향 정렬을 결정하는 속성이다.

.container {
flex-wrap: wrap;
align-content: stretch;
 align-content: flex-start;
align-content: flex-end;
align-content: center;
align-content: space-between; _/
}

아이템에 적용하는 속성들

flex-basis

flex-basis는 아이템의 기본 크기를 설정한다. flex-direction이 row일때는 너비, column일때는 높이

.item {
  flex-basis: auto; //기본값
  flex-basis: 0;
  flex-basis: 50%;
  flex-basis: 100px;
}

flex-basis의 값으로는 width,height 등에 사용하는 각종 단위의 수가 들어갈 수 있으며 기본값 auto는 아이템의 width값을 사용한다. content는 컨텐츠의 크기로, width를 따로 설정하지 않은 경우와 같다. 아이템의 기본 점유 크기를 설정한다고 생각하면됨. flex-basis를 100px로 설정하면 100px안되는 요소들을 100px로 늘리고, 100px이 넘었던 요소들은 원래 크기를 유지한다. 반면 width값은 100이 넘어도 100으로 맞춰줌.

flex-grow

flex-grow는 아이템이 flex-basis의 값보다 커질 수 있는지를 결정하는 속성이다. 값으로는 숫자가 들어가는데, 일단 0보다 큰 값이 세팅되면 해당 아이템이 유연한 박스로 변하고 원래의 크기보다 커지며 빈 공간을 메운다. 기본값이 0이기 때문에 따로 적용하기 전까지는 아이템이 늘어나지 않았던것.

.item {
  flex-grow: 1;
  flex-grow: 0; // 기본값
}

flex-grow에 들어가는 숫자의 의미는, 아이템들이 flex-basis를 제외한 여백 부분을 flex-grow에 지정된 숫자의 비율로 나누어 가진다고 생각하면 된다.

.item1 {
  flex-grow: 1;
}

.item2 {
  flex-grow: 2;
}

아이템1과 아이템2의 내용물을 제외한 늘어난 부분(화면상의 아이템안의여백) 의 비율이 1:2이다

flex-shrink

flex-shrink는 flex-grow와 쌍을 이루는 속성으로, 아이템이 flex-basis의 값보다 작아질 수 있는지를 결정한다. flex-shrink에는 숫자값이 들어가는데, 0보다 큰값이 세팅되면 해당 아이템이 유연한 박스로 변하고 flex-basis보다 작아진다. 기본값은 1

.item {
  flex-basis: 100px;
  flex-shrink: 1;
}

flex-shrink를 0으로 세팅하면 아이템의 크기가 flex-basis보다 작아지지 않기 떄문에 고정폭의 칼럼을 쉽게 만들 수 있다.

.container {
  display: flex;
}

.item1 {
  flex-shrink: 0;
  width: 100px;
}

.item2 {
  flex-grow: 1;
}

flex

flex-grow, flex-shrink, flex-basis를 한번에 쓸 수 있는 축약형 속성이다. 이 세 속성들은 서로 관련이 깊기에 축약형을 쓰는 편이 여러모로 편하다.

.item {
  flex: 1
  /* flex-grow: 1; flex-shrink: 1; flex-basis: 0% */
  flex: 1 1 auto;
  /* flex-grow: 1; flex-shrink: 1; flex-basis: auto */
}

flex-basis의 값을 생략해서 쓴따면 값은 0이 된다.

수직축으로 아이템 정렬 align-self

align-item의 아이템 버전이다.

.item {
  align-self: auto;
  align-self: stretch;
  align-self: flex-start;
  align-self: flex-end;
}

기본값은 auto이며 기본적으로 align-items의 설정을 삭송 받는다. align-self는 align-items보다 우선권이 있따. 전체 설정보다 각각의 개별 설정이 우선한다.

배치 순서 order

각 아이템들의 시각적 나열 순서를 결정하는 속성 숫자값이 들어가며, 작은 숫자일수록 먼저 배치된다. 시각적 순서이므로 HTML자체의 구조를 바꾸는 것은 아니므로 접근성 측면에서 주의해야함.

//나중에보임
.item1 {
  order: 3;
}

//먼저보임
.item2 {
  order: 1;
}

z-index

z-index로 Z축 정렬을 할 수 있다. position에서의 z-index랑 같다.

.item {
  z-index: 1;
}

설정 안하면 0이므로 1만 설정해도 나머지 아이템들보다 위로 올라온다.

Grid

Flex와의 큰 차이점은 Flex는 한 방향 레이아웃 시스템(1차원)이고 Grid는 두 방향 레이아웃 시스템(2차원) 이다. 따라서 FLex보다 더 복합적인 레이아웃 표현이 가능하다.

기본 구조

기본 구조는 플렉스와 마찬가지로, 컨테이너와 아이템이 있으면 된다

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>

시작은 컨테이너에 display속성 부여

.container {
  display: grid;
}

그리드의 용어들

일단 좀 복잡해보이고 까다로워 보이는데 정리

  • 그리드 컨테이너 display: grid를 적용하는, Grid의 전체 영역이다. 그리드 컨테이너 안의 요소들이 Grid의 규칙의 영향을 받아 정렬된다.
  • 그리드 아이템 Grid컨테이너의 자식 요소들. 이 아이템들이 Grid 규칙에 의해 배치된다.
  • 그리드 트랙 Grid의 행 또는 열
  • 그리드 셀 그리드의 한 칸을 가리키는 말이며 html요소는 그리드 아이템이고 이런 그리드 아이템 하나가 들어가는 가상의 칸이 그리드 셀이다.
  • 그리드 라인 그리드 셀을 구분하는 선
  • 그리드 번호 그리드 라인의 각 번호이다
  • 그리드 갭 그리드 셀 사이의 간격
  • 그리드 영역 그리드 라인으로 둘러싸인 사각형 영역으로, 그리드 셀의 집합.

그리드의 속성들도 플렉스와 마찬가지로 컨테이너에 적용하는 속성과 아이템에 적용하는 속성으로 나뉜다.

display: grid

컨테이너에 grid를 적용하는게 시작이며 아이템들이 block요소라면 딱히 변화는 없다.

.container {
  dispay: grid;
}

inline-grid도 있고 이것또한 블락과 인라인블락의 관계를 생각하면 된다.

그리드 형태 정의 grid-template-rows grid-template-columns … -ms-grid-rows -ms-grid-columns

컨테이너에 그리드 트랙의 크기들을 지정해주는 속성이다. 여러가지 단위를 사용할 수 있고 섞어서 사용도 가능하다.

.container {
  grid-template-columns: 200px 200px 500px;
  /* grid-template-columns: 1fr 1fr 1fr;
  grid-template-columns: repeat(3, 1fr);
  grid-template-columns: 150px 1fr; */

  grid-template-rows: 200px 100px 200px;
  /* ... */
}

grid-template-row는 행의 배치, grid-template-columns는 열의 배치이다.

.container {
  grid-template-columns: 200px 200px 500px;
}

은 컬럼을 200px, 200px, 500px로 만들겠다는 의미이다.

.container {
  grid-template-columns: 1fr 1fr 1fr;
}

여기서 fr은 fraction이고, 숫자 비율대로 트랙의 크기를 나눈다. 균일하게 1:1:1 비율인 3개의 column을 만든다는 의미. 고정 크기와 가변 크기를 섞어 쓸 수도 있다.

repeat 함수

.container {
  grid-template-columns: repeat(4, 1fr);
}

반복되는 값을 자동으로 처리할 수 있는 함수이다. repeat(반복횟수, 반복값)

간격 만들기 row-gap column-gap gap

그리드 셀 사이의 간격을 섧정한다.

.container {
  row-gap: 10px;
  /* row의 간격이 10px */
  column-gap: 20px;
  /* column의 간격이 20px */
}
.container {
  gap: 10px 20px;
  /* row-gap: 10px; column-gap: 20px */
}
.container {
  gap: 30px;
  /* row-gap: 30px;
  column-gap: 30px; */
}

초기에는 앞에 grid-를 붙여서 grid-gap, grid-row-gap, grid-column-gap이었는데, 브라우저 호환 범위를 넓히기 이전버전의 이름과 현재 버전의 이름을 둘다 쓰기도 한다.

.container {
  grid-gap: 20px;
  gap: 20px;
}

IE에서는 gap의 대체 속성이 없으므로 통일하고싶다면 처음부터 gap을 사용하지 않고 구조를 설계해야 한다.

그리드 형태를 자동으로 정의 grid-auto-columns grid-auto-rows

grid-template-columns또는 grid-template-rows의 통제를 벗어난 위치에 있는 트랙의 크기를 지정하는 속성이다. template 자리에 auto가 들어간다고 보면됨
예를들어 repeat으로 반복을 해줬는데 row개수를 미리 알 수 없는 경우라면?

.container {
  grid-auto-rows: 100px;
}

이렇게 하면 굳이 횟수를 지정해서 반복할 필요 없이 알아서 처리된다. 즉 grid-template-rows로 미리 세팅해 둔 값이 없어 template-rows의 통제를 벗어난 row가 되고 auto로 처리가 된다.

각 셀의 영역 지정

  • grid-column-start
  • grid-column-end
  • grid-column
  • grid-row-start
  • grid-row-end
  • grid-row
  • -ms-grid-row
  • -ms-grid-column
  • -ms-grid-row-span
  • -ms-grid-column-span

이 속성들은 Grid 아이템에 적용하는 속성으로, 각 셀의 영역을 지정한다.
그리드 아이템들의 양옆으로 순서대로 번호가 매겨진다고 생각하고 그 번호를 이용해서 컬럼과 로우의 범위를 결정한다. grid-column-start가 시작번호, grid-column-end가 끝번호 이며 grid-column은 두 속성을 한번에 쓰는 축약형이다.

.item {
  grid-column-start: 1;
  grid-column-end: 3;
}
.item {
  grid-column: 1 / 3;
}

두 코드는 같은 코드이다. 간단하게 화면을 나눈 뒤 어디부터 어디까지 공간을 잡을지 설정.
grid-column을 이용해 통제받지 않는 column들을 만들 수 있다.

.container {
  grid-template-columns: 50px;
  grid-auto-columns: 1fr 2fr;
}

.item1 {
  grid-column: 2;
}
.item2 {
  grid-column: 3;
}
.item3 {
  grid-column: 4;
}
/* 위의 요소들처럼 end를 생략하면 그냥 한 칸이다 */

이렇게하면 첫번쨰 컬럼만 grid-template-columns의 통제를 받아 50픽셀이 되고, 나머지들은 오토컬럼의 규칙에 따라 1:2의 비율이 반복된다.

영역 이름으로 그리드 정의 grid-template-areas

각 영역에 이름을 붙이고, 그 이름을 이용해서 배치하는 방법이다. 직관적인 방법이다.

.container {
  grid-template-areas:
    'header header header'
    ' a main b '
    ' . . . '
    'footer footer footer ';
}

위의 형태로 각자 차지하는 셀의 개수만큼 해당 위치에 이름을 써준다. header는 첫번쨰 row에서 3개의 column을 차지하니 맨 위에 3번 쓰고, 빈칸은 마침표 또는 “none”을 사용하면 된다. 요소와 매칭은 해당 아이템 요소에 grid-area속성으로 이름을 지정해준다.

.header {
  grid-area: header;
}
.sidebar_a {
  grid-area: a;
}

위와 같이 매칭을 시켜주며 이름 값에 따옴표가 없다. css인데 css 같지 않은 신기한 방법이다

자동배치 grid-auto-flow

아이템이 자동 배치되는 흐름을 결정하는 속성

세로 방향 정렬 align-items

아이템들을 세로방향으로 정렬한다 컨테이너에 적용

.container {
  align-items: stretch;
}

다른 속성들도 플렉스와 유사하다

가로 방향 정렬 justify-items

아이템들을 가로 방향으로 정렬한다. 컨테이너에 적용하며

.container {
  justify-items: stretch;
}

place-items

align-items와 justify-items를 같이 쓸 수 있는 축약형 속성이며 align-items, justify-items의 순서대로 작성하고 하나만 쓰면 두 속성 모두에 적용된다.

.container {
  place-items: center start;
}

아이템 그룹 세로 정렬 align-content

그리드 아이템들의 높이를 모두 합한 값이 그리드 컨테이너의 높이보다 작을 떄 아이템들을 통째로 정렬한다

.container {
  align-content: stretch;
  /* align-content: start;
  align-content: center;
  align-content: end; */
}

아이템 그룹 가로 정렬 justify-content

그리드 아이템들의 너비를 모두 합한 값이 그리드 컨테이너의 너비보다 작을 때 아이템들을 통째로 정렬

.container {
  justify-content: stretch;
  /* justify-content: start;
  justify-content: center;
  justify-content: end; */
}

place-content

place-items의 content 버전이다.

개별 아이템 세로 정렬 align-self -ms-grid-row-align

해당 아이템을 세로 방향으로 정렬한다. 아이템에 적용한다

.item {
  align-self: stretch;
  /* align-self: start;
  align-self: center; */
}

개별 아이템 가로 정렬 justify-self -ms-grid-column-align

해당 아이템을 가로 방향으로 정렬하며 아이템에 적용한다.

.item {
  justify-self: stretch;
  /* justify-self: start;
  justify-self: center; */
}

배치 순서 order

각 아이템들의 시각적 나열 순서를 결정하는 속성이다. 플렉스의 order와 같다.

z-index

z-index로 Z축 정렬을 하며 flex의 z-index와 같다.
그리드 정리도 해보았는데 속성 정렬 개념이나 방식은 사용해오던 플렉스와 많이 다르지만 속성 이름같은것은 또 조금의 차이는 있으나 많이 비슷한것같다. 조금만 정리하고 개념을 잡으면 잘 활용할 수 있을것 같다.


Written by@jaeyoung-son
배운것을 기록하는 공간입니다.

GitHub