Programming Guide/CSS , SASS ( SCSS ) , Tailwind CSS

Css Flex / Grid 개념 알아보기

발효홍삼 2022. 12. 10. 05:54
728x90
https://studiomeal.com/archives/197
https://studiomeal.com/archives/533
해당 글을 참고해 작성한 포스트입니다.

What is Flex & Grid?

웹에는 "웹 레이아웃"이라는 개념이 있다.

우리는 아래 보이는 그림처럼 필요에 따라서 우리만의 레이아웃을 만들어 내용을 배치할 수 있다.

현재 레이 아웃하면 가장 많이 사용되는 것이 Flex와 Grid로 

Flex는 1차원의 수평, 수직 영역 중 하나의 방향으로 레이아웃을 나누고 

Grid는 2차원의 수평 수직을 동시에 레이아웃을 나눈다.

 

Flex

Flex 레이아웃을 만들기 위한 기본적인 HTML 구조는 다음과 같다.

<div class="container">
	<div class="item">helloflex</div>
	<div class="item">abc</div>
	<div class="item">helloflex</div>
</div>

부모 요소인 div.container를 Flex Container(플렉스 컨테이너)라고 부르고,

자식 요소인 div.item들을 Flex Item(플렉스 아이템)이라고 부른다.

 

"컨테이너가 Flex의 영향을 받는 전체 공간이고, 설정된 속성에 따라 각각의 아이템들이 어떤 형태로 배치되는 것"이라고 생각하면 된다.

Flex의 속성들은 컨테이너에 적용하는 속성과 아이템에 적용하는 속성으로 나뉜다.

Flex 컨테이너에 적용하는 속성

display : flex;

Flex 컨테이너에 display:flex;를 적용하는 게 시작이다.

이 한 줄의 CSS만으로 아이템들은 기본적으로 아래 그림과 같이 배치된다.

.container {
	display: flex;
	/* display: inline-flex; */
}

Flex 아이템들은 가로 방향으로 배치되고, 자신이 가진 내용물의 width만큼만 차지하게 된다. (마치 inline 요소들처럼)

height는 컨테이너의 높이만큼 늘어난다.

컬럼의 높이가 자동으로 맞는다.

inline-flex도 있는데, 이건 block과 inline-block의 관계를 생각하면 된다.

아이템의 배치와 관련이 있다기 보다는, 컨테이너가 주변 요소들이 어떻게 어우러질지 결정하는 값이다.

inline-flex는 inline-block처럼 동작한다.

아이템들이 배치된 방향의 축을 메인축(Main Axis),

메인 축과 수직인 축을 수직축 또는 교차축(Cross Axis)라고 부른다.

배치 방향 설정
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;
	/* 아래의 두 줄을 줄여 쓴 것 */
	/* flex-direction: row; */
	/* flex-wrap: wrap; */
}

 

“justify”는 메인 축 방향으로 정렬
“align”은 수직축 방향으로 정렬

메인 축 방향 정렬
justify-content

메인 축 방향으로 아이템들을 정렬하는 속성이다.

.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-direction이 row(가로 배치) 일 때는 왼쪽, column(세로 배치) 일 때는 위로 정렬된다.

flex-end

아이템들을 끝점으로 정렬한다.
flex-direction이 row(가로 배치)일 때는 오른쪽, column(세로 배치) 일 때는 아래로 정렬된다.

center

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

space-between

아이템들의 “사이(between)”에 균일한 간격을 만들어 줍니다.

space-around

아이템들의 “둘레(around)”에 균일한 간격을 만들어 줍니다.

space-evenly (IE와 Edge 지원 X)

아이템들의 사이와 양 끝에 균일한 간격을 만들어 줍니다.

수직축 방향 정렬
align-items

수직축 방향으로 아이템들을 정렬하는 속성(justify-content와 수직 방향의 정렬)

.container {
	align-items: stretch;
	/* align-items: flex-start; */
	/* align-items: flex-end; */
	/* align-items: center; */
	/* align-items: baseline; */
}

stretch (기본값)

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

flex-start

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

justify-content와 같이 flex-direction이 row(가로 배치)일배치) 일 때는 위, column(세로 배치) 일 때는 왼쪽으로 정렬된다.

flex-end

아이템들을 끝으로 정렬한다.

justify-content와 같이 flex-direction이 row(가로 배치)일 때는 아래, column(세로 배치) 일 때는 오른쪽으로 정렬된다.

center

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

baseline

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

justify-content: center;
align-item: 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; */
	/* align-content: space-around; */
	/* align-content: space-evenly; */
}

Flex 아이템에 적용하는 속성들

유연한 박스의 기본 영역
flex-basis

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

.item {
	flex-basis: auto; /* 기본값 */
	/* flex-basis: 0; */
	/* flex-basis: 50%; */
	/* flex-basis: 300px; */
	/* flex-basis: 10rem; */
	/* flex-basis: content; */
}

유연하게 늘리기
flex-grow

flex-grow는 아이템이 flex-basis의 값보다 커질 수 있는지를 결정하는 속성이다.

flex-grow에는 숫자값이 들어가는데, 몇이든 일단 0보다 큰 값이 세팅이 되면 해당 아이템이 유연한(Flexible) 박스로 변하고 원래의 크기보다 커지면 빈 공간을 메우게 된다.

기본값이 0이기 때문에, 따로 적용하기 전까지는 아이템이 늘어나지 않는다.

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

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

/* 1:2:1의 비율로 세팅할 경우 */
.item:nth-child(1) { flex-grow: 1; }
.item:nth-child(2) { flex-grow: 2; }
.item:nth-child(3) { flex-grow: 1; }

각 아이템의 컨텐츠가 "AAAAA", "B", "CCC", 로 원래의 크기가 다르기 때문에 전체 아이템의 크기가 살짝 애매한 비율로 보이지만, 여백의 비로 생각해보면 정확히 1:2:1이다.

정수뿐만 아니라 소수도 가능하다.

유연하게 줄이기
flex-shrink

flex-shrink는 flex-grow와 쌍을 이루는 속성으로, 아이템이 flex-basis의 값보다 작아질 수 있는지를 결정한다.

flex-shrink에는 숫자값이 들어가는데, 몇이든 일단 0보다 큰 값이 세팅이 되면 해당 아이템이 유연한(Flexible) 박스로 변하고 flex-basis보다 작아진다.

기본값이 1이기 때문에 따로 세팅하지 않았어도 아이템이 flex-basis보다 작아질 수 있다.

.item {
	flex-basis: 150px;
	flex-shrink: 1; /* 기본값 */
}

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

고정 크기는 width로 설정한다.

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: 1 500px;
	/* flex-grow: 1; flex-shrink: 1; flex-basis: 500px; */
}

주의할 점은, flex:1; 이런 식으로 flex-basis를 생략해서 쓰면 flex-basis의 값은 0이 된다.

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

align-items의 아이템 버전이다. align-items가 전체 아이템의 수직축 방향 정렬이라면, align-self는 해당 아이템의 수직축 방향 정렬이다.

.item {
	align-self: auto;
	/* align-self: stretch; */
	/* align-self: flex-start; */
	/* align-self: flex-end; */
	/* align-self: center; */
	/* align-self: baseline; */
}

기본값은 auto로, 기본적으로 align-items 설정을 상속받는다.

align-self는 align-items보다 우선권이 있다.전체 설정보다 각각의 개별 설정이 우선된다.

auto 외의 나머지 값들은 align-items와 동일하다.

배치 순서
order

각 아이템들의 시각적 나열 순서를 결정하는 속성이다.

숫자값이 들어가며, 작은 숫자일수록 먼저 배치된다. "시각적" 순서일 뿐, HTML 자체의 구조를 바꾸는 것은 아니므로 접근성 측면에서 사용에 주의해야 한다.

z-index

z-index로 Z축 정렬을 할 수 있다. 숫자가 클수록 위로 올라온다.

.item:nth-child(2) {
	z-index: 1;
	transform: scale(2);
}
/* z-index를 설정 안하면 0이므로, 1만 설정해도 나머지 아이템을 보다 위로 올라온다 */

Grid

Grid 레이아웃을 만들기 위한 기본적인 HTML 구조는 다음과 같다. Flex와 마찬가지로, 컨테이너와 아이템이 있으면 된다.

<div class="container">
	<div class="item">A</div>
	<div class="item">B</div>
	<div class="item">C</div>
	<div class="item">D</div>
	<div class="item">E</div>
	<div class="item">F</div>
	<div class="item">G</div>
	<div class="item">H</div>
	<div class="item">I</div>
</div>

부모 요소인 div.container를 Grid Container(그리드 컨테이너)라고 부르고,

자식 요소인 div.item들을 Grid Item(그리드 아이템)이라고 부른다.

"컨테이너가 Grid의 영향을 받는 전체 공간이고, 설정된 속성에 따라 각각의 아이템들이 어떤 형태로 배치되는 것"이라고 생각하면 된다.

 

Flex와 마찬가지로, Grid는 컨테이너에 display:grid;를 설정하는 것으로 시작한다.

.container {
	display: grid;
}

Grid 용어 정리

  • 그리드 컨테이너 (Grid Container)
    display: grid를 적용하는, Grid의 전체 영역. Grid 컨테이너 안의 요소들이 Grid 규칙의 영향을 받아 정렬된다고 생각하면 된다. 위 코드 <div class=”container”></div>가 Grid 컨테이너이다.
  • 그리드 아이템 (Grid Item)
    Grid 컨테이너의 자식 요소들. 바로 이 아이템들이 Grid 규칙에 의해 배치된다. 위 코드에서 <div class=”item”></div>들이 Grid 아이템이다.
  • 그리드 트랙 (Grid Track)
    Grid의 행(Row) 또는 열(Column)
  • 그리드 셀 (Grid Cell)
    Grid의 한 칸을 가리킨다. <div> 같은 실제 html 요소는 그리드 아이템이고, 이런 Grid 아이템 하나가 들어가는 “가상의 칸(틀)”이라고 생각하면 된다.
  • 그리드 라인(Grid Line)
    Grid 셀을 구분하는 선이다.
  • 그리드 번호(Grid Number)
    Grid 라인의 각 번호이다.
  • 그리드 갭(Grid Gap)
    Grid 셀 사이의 간격이다.
  • 그리드 영역(Grid Area)
    Grid 라인으로 둘러싸인 사각형 영역으로, 그리드 셀의 집합이다.

Grid의 속성들 또한 Flex와 마찬가지로,

  • 컨테이너에 적용하는 속성
  • 아이템에 적용하는 속성

두 가지로 나뉜다.

display: grid;

Grid 컨테이너에 display:grid;를 적용하는 게 시작이다.

아이템들이 block 요소라면 이 한 줄 만으로는 딱히 변화는 없다.

.container {
	display: grid;
	/* display: inline-grid; */
}

inline-grid도 있으며, block과 inline-block의 관계를 생각하면 된다.

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

-ms-grid-rows
-ms-grid-columns
컨테이너에 Grid 트랙의 크기들을 지정해주는 속성이다.
여러가지 단위를 사용할 수 있고 섞어서 쓸 수도 있다.
.container {
	grid-template-columns: 200px 200px 500px;
	/* grid-template-columns: 1fr 1fr 1fr */
	/* grid-template-columns: repeat(3, 1fr) */
	/* grid-template-columns: 200px 1fr */
	/* grid-template-columns: 100px 200px auto */

	grid-template-rows: 200px 200px 500px;
	/* grid-template-rows: 1fr 1fr 1fr */
	/* grid-template-rows: repeat(3, 1fr) */
	/* grid-template-rows: 200px 1fr */
	/* grid-template-rows: 100px 200px auto */
}
  • grid-template-rows는 행(row)의 배치
  • grid-template-columns는 열(column)의 배치

를 결정한다.

예를 들어

grid-template-columns: 200px 200px 500px;

는 column을 200px, 200px, 500px로 만들겠다는 의미이다.

grid-template-columns: 1fr 1fr 1fr;

fr은 fraction으로, 숫자 비율대로 트랙의 크기를 나눈다.

즉 위의 1fr 1fr 1fr은 균일하게 1:1:1 비율인 3개의 column을 만들겠다는 의미이다.

고정 크기와 가변 크기를 섞어 쓸 수도 있다.

repeat 함수

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

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

repeat(반복 횟수, 반복 값)

즉, 위 코드의 repeat(5, 1fr)은 1fr 1fr 1fr 1fr 1fr과 같다.

repeat(3, 1fr 4fr 2fr); 이런 식의 패턴도 가능하다.

minmax 함수

최솟값과 최댓값을 지정할 수 있는 함수이다.

 minmax(100px, auto)의 의미는 최소한 100px, 최대는 자동으로(auto) 늘어나게...이다. 즉 아무리 내용의 양이 적더라도 최소한 높이 100px은 확보하고, 내용이 많아 100px이 넘어가면 알아서 늘어나도록 처리해준 예시이다.

.container {
	grid-template-columns: repeat(3, 1fr);
	grid-template-rows: repeat(3, minmax(100px, auto));
}

auto-fill과 auto-fit

auto-fill과 auto-fit은 column의 개수를 미리 정하지 않고 설정된 너비가 허용하는 한 최대한 셀을 채운다.

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

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

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

grid-template-columns(또는 grid-template-rows)의 통제를 벗어난 위치에 있는 트랙의 크기를 지정하는 속성이다.

각 셀의 영역 지정
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 아이템에 적용하는 속성으로, 각 셀의 영역을 지정한다.
아래 그림을 보면,

 

1부터 4까지의 Grid 라인 번호가 매겨져 있는데, 바로 그 번호를 이용해서 column과 row의 범위를 결정하는 것이다.

column으로 살펴보면, grid-column-start가 시작 번호, grid-column-end가 끝 번호이다. grid-column은 start와 end 속성을 한 번에 쓰는 축약형이다.

.item:nth-child(1) {
	grid-column-start: 1;
	grid-column-end: 3;
	grid-row-start: 1;
	grid-row-end: 2;
}
.item:nth-child(1) {
	grid-column: 1 / 3;
	grid-row: 1 / 2;
}

위 두 코드처럼 설정하면 영역은 아래와 같다.

 

시작번호/ 끝번호를 지정하는 방법 외에, 몇 개의 셀을 차지하게 할 것인지를 지정해줄 수도 있다.

.item:nth-child(1) {
	/* 1번 라인에서 2칸 */
	grid-column: 1 / span 2;
	/* 1번 라인에서 3칸 */
	grid-row: 1 / span 3;
}

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

각 영역(Grid Area)에 이름을 붙이고, 그 이름을 이용해서 배치하는 방법이다.

정말 직관적인 방법이다.

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

위의 형태로 각자 차지하는 셀의 개수만큼 해당 위치에 이름을 써주면 된다.

각 셀마다 공백을 하나씩 넣어서 구분해주면 된다. 빈칸은 마침표 또는 "none"을 사용하면 되고, 마침표의 개수는 여러 개를 써도 상관없다.

각 영역의 이름을 해당 아이템 요소에 grid-area 속성으로 이름을 지정해주면 된다.

.header { grid-area: header; }
.sidebar-a { grid-area: a; }
.main-content { grid-area: main; }
.sidebar-b { grid-area: b; }
.footer { grid-area: footer; }
/* 이름 값에 따옴표가 없는 것에 주의하세요 */

자동 배치
grid-auto-flow

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

세로 방향 정렬
align-items

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

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

가로 방향 정렬
justify-items

아이템들을 가로(row 축) 방향으로 정렬한다. 컨테이너에 적용한다.

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

place-items

align-items와 justify-items를 같이 쓸 수 있는 단축 속성이다.

align-items, justify-items의 순서로 작성하고 하나의 값만 쓰면 두 속성 모두에 적용된다.

.container {
	place-items: center start;
}

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

Grid 아이템들의 높이를 모두 합한 값이 Grid 컨테이너의 높이보다 작을 때 Grid 아이템들을 통째로 정렬한다.

.container {
	align-content: stretch;
	/* align-content: start; */
	/* align-content: center; */
	/* align-content: end; */
	/* align-content: space-between; */
	/* align-content: space-around; */
	/* align-content: space-evenly; */
}

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

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

.container {
	justify-content: stretch;
	/* justify-content: start; */
	/* justify-content: center; */
	/* justify-content: end; */
	/* justify-content: space-between; */
	/* justify-content: space-around; */
	/* justify-content: space-evenly; */
}

place-content

align-content와 justify-content를 같이 쓸 수 있는 단축 속성이다.

align-content justify-content의 순서로 작성하고, 하나의 값만 쓰면 두 속성 모두에 적용된다.

.container {
	place-content: space-between center;
}

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

-ms-grid-row-align

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

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

개별 아이템 가로 정렬
justify-self

-ms-grid-column-align
해당 아이템을 가로(row축) 방향으로 정렬한다. 아이템에 적용한다.
.item {
	justify-self: stretch;
	/* justify-self: start; */
	/* justify-self: center; */
	/* justify-self: end; */
}

place-self

align-self와 justify-self를 같이 쓸 수 있는 단축 속성이다.

align-self, justify-self의 순서로 작성하고, 하나의 값만 쓰면 두 속성 모두에 적용된다.

.item {
	place-self: start center;
}

배치 순서
order

각 아이템들의 시각적 나열 순서를 결정하는 속성이다.

숫자 값이 들어가며, 작은 숫자일수록 먼저 배치된다. "시각적" 순서일 뿐, HTML 자체의 구조를 바꾸는 것은 아니므로 접근성 측면에서 사용에 주의해야 한다.

z-index

z-index로 Z 축 정렬을 할 수 있다. 숫자가 클수록 위로 올라온다.

728x90