본문 바로가기
프론트엔드/HTML&CSS

[CSS] CSS 중급 (2)

by 토마토베이컨수프 2021. 10. 27.

페이지의 레이아웃 작성을 위해 사용하는 flex와 grid에 대해 정리해 보았습니다.

 


<Flex>

flex는 부모 요소인 컨테이너(container)와 자식 요소인 아이템(item)으로 구성되며, 각각 플렉스 컨테이너, 플렉스 아이템이라고 부릅니다.

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

 

이들에게 다양한 속성들을 적용하여 컨테이너 내부의 아이템 크기나 아이템 배치 형태를 조절해 유연한 플렉스 구조를 설계할 수 있습니다.

하나하나 알아보도록 합시다.

 


flex 적용하기

.container {
    display: flex;
}

flex가 일반 block배치와 다른 점은, 바로 block은 세로 방향으로 배치되지만 flex는 마치 inline처럼 가로 방향으로 배치된다는 점입니다. 그리고 float이랑은 다르게 아이템들의 높이가 자동으로 같게 유지됩니다.

 

배치 방향 설정

아이템들이 배치되는 메인축의 방향을 설정하는 속성입니다. 컨테이너 요소에 적용되는 속성으로, 총 4가지가 있습니다.

.container {
    flex-direction: row;		/*아이템들이 행(가로) 방향으로 배치됩니다*/
    flex-direction: column;		/*아이템들이 역순으로 가로 배치됩니다*/
    flex-direction: row-reverse;	/*아이템들이 마치 block처럼 열(세로) 방향으로 배치됩니다*/
    flex-direction: column-reverse; 	/*아이템들이 역순으로 세로 배치 됩니다*/
}

 

줄 넘김 처리 설정

컨테이너가 더 이상 아이템들을 한 줄에 담을 여유 공간이 없을 때 아이템 줄바꿈을 어떻게 할지 결정하는 속성입니다. 컨테이너 요소에 적용되는 속성으로, 총 3가지가 있습니다.

.container {
    flex-wrap: nowrap;		/*줄바꿈을 하지 않고 컨테이너에서 삐져나갑니다*/
    flex-wrap: wrap;		/*줄바꿈을 합니다*/
    flex-wrap: wrap-reverse;	/*줄바꿈과 동시에 아이템들을 역순으로 배치합니다*/ 
}

 

flew-flow

flex-directionflex-wrap을 한꺼번에 지정할 수 있는 속성입니다. flex-direction, flex-wrap의 순으로 한 칸 떼고 써주시면 됩니다.

.container {
    flex-flow: row wrap;
}

 

메인축 방향 정렬

flex-direction으로 정해지는 메인축 방향으로 아이템들을 정렬하는 속성으로, 컨테이너 요소에 적용되는 속성 입니다.

.container {
    justify-content: flex-start;	/*아이템들을 시작점으로 정렬합니다*/
    justify-content: flex-end; 		/*아이템들을 끝점으로 정렬합니다*/
    justify-content: center; 		/*아이템들을 가운데로 정렬합니다*/
    justify-content: space-between; 	/*아이템들의 사이에 균일한 간격을 만들어 줍니다*/
    justify-content: space-around; 	/*아이템들의 둘레에 균일한 간격을 만들어 줍니다*/
    justify-content: space-evenly; 	/*아이템들의 사이와 양 끝에 균일한 간격을 만들어 줍니다*/
}

 

수직축 방향 정렬

justify-content와 수직 방향으로 아이템들을 정렬하는 속성으로, 컨테이너 요소에 적용됩니다.

.container {
    align-items: stretch;		/*아이템들이 수직축 방향으로 끝까지 늘어납니다*/
    align-items: flex-start; 		/*아이템들을 시작점으로 정렬합니다*/
    align-items: flex-end; 		/*아이템들을 끝으로 정렬합니다*/
    align-items: center; 		/*아이템들을 가운데로 정렬합니다*/
    align-items: baseline; 		/*아이템들을 텍스트 베이스라인 기준으로 정렬합니다*/
}

 

여러 행 정렬

flex-wrap: wrap;이 설정된 상태에서, 아이템들의 행이 2줄 이상 되었을 때의 수직축 방향 정렬을 결정하는 속성으로, 컨테이너 요소에 적용됩니다.

속성값과 그 효과는 justify-content와 동일합니다. 

.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; 
}

 

아이템의 기본 크기

지금부터 나오는 속성들은 모두 아이템에 적용되는 속성입니다.

.item {
    flex-basis: 100px;
}

이런 식으로 아이템의 크기를 100px로 설정하면, 원래의 width가 100px이 안되는 아이템은 100px로 늘어나고, 원래 100px이 넘는 아이템은 그대로 유지됩니다.

일반 width랑의 차이는, 만약 width의 속성을 100px로 설정했다면 원래 100px을 넘는 아이템도 100px로 맞춰집니다.

 

유연하게 늘리기

기존에 아이템이 가지고 있는 flex-basis를 제외한 여백 부분에 대해 아이템을 얼마나 늘려줄지를 정해주는 속성입니다. flex-grow속성은 기본값으로 0을 가지고, 일단 0보다 큰 값이 세팅이 되면 해당 아이템이 유연한(Flexible) 박스로 변하고 원래의 크기보다 커지며 빈 공간을 메우게 됩니다.

 

.item {
    flex-grow: 1;
}

컨테이너에 3개의 아이템들이 있다 가정하고 이렇게 모든 아이템들에게 flex-grow의 속성값을 1로 주면 아이템들의 여백의 크기의 비율이 1:1:1이 되고

 

.item:nth-child(1) { flex-grow: 1; }
.item:nth-child(2) { flex-grow: 2; }
.item:nth-child(3) { flex-grow: 1; }

이런식으로 각각 1, 2, 1의 값을 주면 여백의 크기 비율이 1:2:1이 됩니다.

 

 

유연하게 줄이기

flex-shrink속성은 1의 기본값을 가지고, 아이템들은 flex-basis보다 작아질 수 있습니다. 만약 flex-shrink의 값을 0으로 하면 아이템의 크기가 flex-basis보다 작아지지 않기 때문에 고정폭의 컬럼을 만들 수 있습니다. 고정 크기는 width로 설정하면 됩니다.

.container {
    display: flex;
}
.item:nth-child(1) {
    flex-shrink: 0;
    width: 100px;
}

 

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-basis을 0으로 하면 됩니다.

 

수직축으로 아이템 정렬

align-items의 아이템 버전입니다. align-items가 전체 아이템의 수직축 방향 정렬이라면, align-self는 해당 아이템의 수직축 방향 정렬입니다. 속성값들은 align-items속성과 동일하고, 효과 또한 같습니다.

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

 

배치 순서

각 아이템들의 시각적 나열 순서를 결정하는 속성입니다. 숫자값이 들어가며, 작은 숫자일 수록 먼저 배치됩니다. 시각적인 효과만 바뀌는 것이기 때문에 기존 HTML코드의 구조는 변함이 없습니다.

.item:nth-child(1) { order: 3; } 	/*가장 뒤에 나옵니다*/
.item:nth-child(2) { order: 1; } 	/*가장 앞에 나옵니다*/
.item:nth-child(3) { order: 2; } 	/*중간에 나옵니다*/

 


<Grid>

grid의 구성 요소는 다음과 같습니다.

<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>
  • 그리드 컨테이너 (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 라인으로 둘러싸인 사각형 영역으로, 그리드 셀의 집합입니다.

그리드는 다음과 같이 display 속성값을 grid로 주는 것으로 시작합니다.

.container {
    display: grid;
}

 


그리드 형태 정의

.container {
    /*행의 배치 입니다*/
    grid-template-rows: 200px 200px 500px;	/*각각 200, 200, 500 픽셀*/
    grid-template-rows: 1fr 1fr 1fr; 		/*전체를 균일하게 1:1:1의 비율로*/
    grid-template-rows: 200px 1fr;		/*행은 총 2개 하나는 200픽셀, 나머지는 자동으로*/
    grid-template-rows: 100px 200px auto;	/*두 행은 각각 100, 200 픽셀, 나머지는 자동으로*/
    
    /*열의 배치 입니다*/
    grid-template-columns: 200px 200px 500px;
    grid-template-columns: 1fr 1fr 1fr; 
    grid-template-columns: 200px 1fr;		/*열은 총 2개 하나는 200픽셀, 나머지는 자동으로*/
    grid-template-columns: 100px 200px auto;	/*두 열은 각각 100, 200 픽셀, 나머지는 자동으로*/
}

repeat함수는 repeat(반복횟수, 반복값) 형태로 반복되는 값을 자동으로 처리합니다.

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

minmax함수는 최솟값, 최댓값을 지정할 수 있는 함수입니다. 예를 들어 minmax(100px, auto)의 의미는 아무리 내용의 양이 적더라도 최소한 높이 100px은 확보하고, 내용이 많아 100px이 넘어가면 알아서 늘어나게 한다는 뜻입니다.

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

auto-fillauto-fit은 개수를 미리 정하지 않고 설정된 너비가 허용하는 한 최대한 셀을 채웁니다.

.container {
    /*1개의 row에는 5개의 셀이 들어가고, 셀의 개수가 5개보다 모자라면 공간이 남게 됩니다*/
    grid-template-columns: repeat(auto-fill, minmax(20%, auto));
    
    /*auto-fit을 사용하면 남는 공간을 채웁니다*/
    grid-template-columns: repeat(auto-fit, minmax(20%, auto));
}

 

간격 만들기

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

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

 

그리드 형태를 자동으로 정의

그리드의 형태를 정의할 때 grid-template-columnsgrid-template-rows을 사용했는데요, 만약 행이나 열의 개수를 미리 알 수 없다면 template 대신 auto가 들어간 속성을 사용해주면 됩니다.

.container {
    /*grid-template-rows: repeat(3, minmax(100px, auto)); 이렇게 한 것을 밑 코드처럼*/
    grid-auto-rows: minmax(100px, auto);
}

굳이 횟수를 지정해서 반복할 필요 없이 알아서 처리됩니다.

 

각 셀의 영역 지정

각 셀의 영역의 영역을 표시하는 방법은 다음과 같습니다. 만약 가로 세로 각각 3개의 셀들이 있다면 이처럼 1부터 4까지의 grid 라인 번호를 갖습니다.

이미지 출처: 1분코딩

/*grid 아이템에 적용해줍니다*/
.item:nth-child(1) {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-column: 1 / 3;		/*하나의 속성으로 표현*/
    
    grid-row-start: 1;
    grid-row-end: 2;
    grid-row: 1 / 2;		/*하나의 속성으로 표현*/
}

이처럼 시작번호와 끝번호를 지정해 영역을 표시하는 방법도 있지만, 몇 개의 셀을 차지하게 할 것인지를 지정해줄 수도 있습니다.

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

 

영역 이름으로 그리드 정의

각 grid 영역에 이름을 붙이고 배치하는 방법입니다.

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

이처럼 각 셀 마다 공백을 줘서 구분하고 빈칸은 마침표를 사용합니다. 그리고 각 영역에 대한 이름은

.header { grid-area: header; }
.sidebar-a { grid-area: a; }
.main-content { grid-area: main; }
.sidebar-b { grid-area: b; }
.footer { grid-area: footer; }

이렇게 해당 아이 요소에 grid-area 속성으로 이름을 지정해주면 됩니다.

 

가로, 세로 방향 정렬

아이템들을 어떻게 정렬할지를 결정하며, 컨테이너에 적용하는 속성입니다.

.container {
    /*세로 방향*/
    align-items: stretch;
    align-items: start; 
    align-items: center; 
    align-items: end; 
    
    /*가로 방향*/
    justify-items: stretch;
    justify-items: start; 
    justify-items: center; 
    justify-items: end; 
    
    /*align-items와 justify-items를 같이 쓸 수 있는 단축 속성입니다*/
    place-items: center start;
}

 

아이템 그룹가로, 세로 정렬

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: stretch;
    justify-content: start; 
    justify-content: center; 
    justify-content: end; 
    justify-content: space-between; 
    justify-content: space-around; 
    justify-content: space-evenly; 
    
    /*align-content와 justify-content를 같이 쓸 수 있는 단축 속성입니다*/
    place-content: space-between center;
}

 

개별 아이템 정렬

아이템에 적용하는 속성입니다.

.item {
    /*세로 정렬*/
    align-self: stretch;
    align-self: start; 
    align-self: center; 
    align-self: end; 
    
    /*가로 정렬*/
    justify-self: stretch;
    justify-self: start; 
    justify-self: center; 
    justify-self: end; 
    
    /*align-self와 justify-self를 같이 쓸 수 있는 단축 속성입니다*/
    place-self: start center;
}

 


참고 자료

'프론트엔드 > HTML&CSS' 카테고리의 다른 글

[CSS] CSS 중급 (1)  (0) 2021.10.23
[CSS] CSS 기초  (0) 2021.10.20
[HTML] 기본 태그 총 정리  (0) 2021.10.18