프론트엔드/CSS

Flexbox 수업 - 요약

syleemomo 2022. 7. 6. 18:28
728x90
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
  </div>
  <script src="app.js"></script>
</body>
</html>

index.html 을 위와 같이 작성하자! container 라는 div 엘리먼트 내부에 item 이라는 3개의 div 엘리먼트가 있다. 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
}
.item{
  border: 1px solid blue;
}

style.css 를 위와 같이 작성하자! 

초기화면

div 엘리먼트는 블록요소이기 때문에 웹 화면에서 한줄 전체를 다 차지한다. 그리고 스택처럼 세로로 쌓인다. 

 

* 컨테이너에 flexbox 적용하기 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
}
.item{
  border: 1px solid blue;
}

display: flex 는 리스트 아이템을 감싸고 있는 컨테이너에 적용한다. 

display: flex 를 적용한 화면

이렇게 하면 각 아이템의 너비는 기본적으로 컨텐츠 크기만큼 차지하고, 가로로 나열된다. 

 

* 리스트 아이템  정렬하기 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

컨테이너의 너비와 높이를 웹 화면에 꽉 차도록 width, height 을 설정한다. 

컨테이너 크기를 웹화면과 동일하게 한 화면

아이템의 높이는 기본적으로 컨테이너 높이에 맞춰진다. 

 

정렬을 하기 위해서는 우선 메인축과 교차축에 대하여 알아야 한다. flexbox 는 기본적으로 가로방향이 메인축이다. 이는 flex-direction: row 로 설정할 수 있지만 설정하지 않아도 동일하다. 

flex-direction: row 인 경우 (또는 해당 속성을 설정하지 않은 경우) 메인축은 가로방향이다. 그리고 교차축은 세로방향이다. 메인축에 대한 정렬은 justify-content 로 하면 된다. 또한, 교차축에 대한 정렬은 align-items 로 하면 된다. 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축 시작점에 위치하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

align-items 는 기본적으로 stretch 로 설정된다. 다시 말해 교차축 방향으로 늘어난다. 그렇게 때문에 아이템의 높이가 웹화면의 높이만큼 차지하게 된 것이다. align-items: flex-start 는 아이템을 교차축의 시작점부터 정렬한다. 즉, 세로방향에 대하여 상단에 위치시킨다. 

align-items: flex-start 를 적용한 화면

이렇게 하면 아이템의 높이는 웹화면의 높이만큼 차지하는게 아니라 컨텐츠 크기만큼 차지하게 된다. 

 

이제 아이템을 가로로 정렬해보자! 메인축이 가로방향이므로 가로로 정렬하기 위해서는 justify-content 속성을 사용하면 된다. 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축 시작점에 위치하도록 설정 */
  justify-content: center; /* 아이템을 메인축 중앙지점에 위치하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

justify-content: center 는 아이템을 메인축의 중앙에 정렬한다. 

justify-content: center 를 적용한 화면

 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축 시작점에 위치하도록 설정 */
  justify-content: flex-end; /* 아이템을 메인축 끝에 위치하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

justify-content: flex-end 는 아이템을 메인축 끝에 정렬한다. 

justify-content: flex-end 를 적용한 화면

 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축 시작점에 위치하도록 설정 */
  justify-content: flex-start; /* 아이템을 메인축 시작점에 위치하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

justify-content: flex-start 는 아이템을 메인축 시작점에 정렬한다. 

justify-content: flex-start 를 적용한 화면

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축 시작점에 위치하도록 설정 */
  justify-content: space-between; /* 아이템들 사이(between)에 동일한 간격으로 나열하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

justify-content: space-between 은 아이템을 사이(between)에 동일한 간격을 두고 정렬시킨다. 

justify-content: space-between 을 적용한 화면

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축 시작점에 위치하도록 설정 */
  justify-content: space-around; /* 아이템들의 둘레(around)에 동일한 간격으로 나열하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

justify-content: space-around 은 아이템의 둘레(around)에 동일한 간격을 두고 정렬시킨다. 

justify-content: space-around 를 적용한 화면

 

이제 아이템을 세로로 정렬해보자! 교차축이 세로방향이므로 세로로 정렬하기 위해서는 align-items 속성을 사용하면 된다. 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: center; /* 아이템을 교차축 중앙에 정렬하도록 설정 */
  justify-content: flex-start; /* 아이템을 메인축 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

align-items: center 는 아이템을 교차축의 중앙에 정렬시킨다. 

align-items: center 를 적용한 화면

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-end; /* 아이템을 교차축 끝에 정렬하도록 설정 */
  justify-content: flex-start; /* 아이템을 메인축 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

align-items: flex-end 는 아이템을 교차축 끝에 정렬시킨다. 

align-items: flex-end 를 적용한 화면

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축 시작점에 정렬하도록 설정 */
  justify-content: flex-start; /* 아이템을 메인축 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

align-items: flex-start 는 아이템을 교차축 시작점에 정렬시킨다. 

align-items: flex-start 를 적용한 화면

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: stretch; /* 아이템을 교차축에 대하여 꽉 차도록 늘어뜨리도록 설정 */
  justify-content: flex-start; /* 아이템을 메인축 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

align-items: stretch 는 교차축에 대하여 아이템의 너비나 높이를 늘어뜨린다. stretch 는 디폴트 값이라서 설정하지 않아도 된다. 

align-items: stretch 를 적용한 화면

 

flex-direction 은 아이템을 가로방향으로 나열할지 세로방향으로 쌓을지를 결정한다. 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  flex-direction: column; /* 세로방향이 메인축이 되도록 설정 */
  align-items: flex-end; /* 아이템을 교차축(가로방향)의 끝에 정렬하도록 설정 */
  justify-content: flex-start; /* 아이템을 메인축(세로방향)의 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item{
  border: 1px solid blue;
}

flex-direction: column 은 아이템을 세로방향으로 쌓는다. 또한 세로방향이 메인축이 되도록 설정한다. 

flex-direction: column 을 적용한 화면

메인축은 세로방향이므로 세로방향으로 정렬하기 위해서는 justify-content 속성을 설정하면 된다. 교차축은 가로방향이므로 가로방향으로 정렬하기 위해서는 align-items 속성을 설정하면 된다.

위에서 배운 정렬 속성값 (flex-start, center, flex-end, space-between, space-around) 를 바꿔가면서 아이템이 어느 위치에 정렬되는지 실험해보자!

 

* 아이템 유연하게 늘리기 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축의 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item:nth-child(1){
  background: green;
  flex-grow: 1; /* 아이템의 너비를 메인축으로 컨테이너 전체 너비의 1/4만큼 차지하도록 늘리기 */
}
.item:nth-child(2){
  background: blue;
  flex-grow: 2; /* 아이템의 너비를 메인축으로 컨테이너 전체 너비의 2/4만큼 차지하도록 늘리기 */
}
.item:nth-child(3){
  background: red;
  flex-grow: 1; /* 아이템의 너비를 메인축으로 컨테이너 전체 너비의 1/4만큼 차지하도록 늘리기 */
}

flex-grow 속성은 아이템의 크기를 메인축 방향으로 늘린다. 현재 flex-direction 은 설정되어 있지 않으므로 기본적으로 row 이고, 메인축 방향은 가로방향이다. 그러므로 flex-grow 는 아이템의 너비가 컨테이너 전체 너비를 다 차지하도록 가로방향으로 늘린다. flex-grow 가 각각 1:2:1 비율로 설정되어 있으므로 컨테이너 너비를 4등분해서 해당 비율만큼 너비가 늘어난다. nth-child 는 item 엘리먼트 중에서 하나의 엘리먼트를 선택한다. 

아이템 엘리먼트에 flex-grow 를 설정한 화면

body{
  margin: 0;
  padding: 0;
}

.container{
  /* border: 1px solid red; */
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  flex-direction: column; /* 메인축을 세로방향으로 설정 */
  align-items: flex-start; /* 아이템을 교차축의 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
.item:nth-child(1){
  background: green;
  flex-grow: 1; /* 아이템의 높이를 메인축(세로방향)으로 컨테이너 전체 높이의 1/4만큼 차지하도록 늘리기 */
}
.item:nth-child(2){
  background: blue;
  flex-grow: 2; /* 아이템의 높이를 메인축(세로방향)으로 컨테이너 전체 높이의 2/4만큼 차지하도록 늘리기 */
}
.item:nth-child(3){
  background: red;
  flex-grow: 1; /* 아이템의 높이를 메인축(세로방향)으로 컨테이너 전체 높이의 1/4만큼 차지하도록 늘리기 */
}

세로방향으로 아이템의 크기를 늘어뜨리려면 flex-direction: column 으로 설정하면 된다. 이렇게 하면 메인축이 세로방향이 되면서 flex-grow 가 설정된 아이템들이 세로방향으로 늘어난다. 즉, 아이템의 높이를 컨테이너 전체 높이에 대하여 1:2:1 비율로 늘어뜨린다. 

flex-direction: column 과 flex-grow 를 설정한 화면

 

* 아이템의 기본 크기 설정하기 

body{
  margin: 0;
  padding: 0;
}

.container{
  /* border: 1px solid red; */
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축의 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}
/* 메인축 방향에 대한 아이템의 기본 길이 */

.item:nth-child(1){
  background: green;
  /* flex-basis: 200px;  */
}
.item:nth-child(2){
  background: blue;
  /* flex-basis: 200px; */
}
.item:nth-child(3){
  background: red;
  /* flex-basis: 200px; */
}

기본적으로 div 엘리먼트의 크기는 컨텐츠 사이즈만큼 차지한다. 

flex-basis 를 적용하지 않은 아이템의 기본크기

body{
  margin: 0;
  padding: 0;
}

.container{
  /* border: 1px solid red; */
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축의 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}

.item:nth-child(1){
  background: green;
  flex-basis: 200px; /* 메인축 방향에 대한 아이템의 기본 길이 */
}
.item:nth-child(2){
  background: blue;
  flex-basis: 200px;
}
.item:nth-child(3){
  background: red;
  flex-basis: 200px;
}

flex-basis 속성은 메인축 방향에 대한 아이템의 기본크기를 설정한다. 현재 메인축은 가로방향이므로 아이템의 너비를 설정하게 된다. 이렇게 하면 div 엘리먼트는 컨텐츠 크기만큼이 아니라 flex-basis 로 설정한 길이만큼 크기를 가진다. 

flex-basis 를 적용한 화면

 

* 컨테이너가 줄어들때 아이템의 크기가 줄어들게 하기 

body{
  margin: 0;
  padding: 0;
}

.container{
  /* border: 1px solid red; */
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축의 시작점에 정렬하도록 설정 */

  width: 100%; /* 컨테이너 너비를 화면에 꽉 차도록 하기 */
  height: 100vh;
}

.item:nth-child(1){
  background: green;
  flex-basis: 200px; /* 메인축 방향에 대한 아이템의 기본 길이 */
  flex-shrink: 1; /* 메인축 방향으로 아이템의 크기가 줄어들도록 설정 */
}
.item:nth-child(2){
  background: blue;
  flex-basis: 200px;
  flex-shrink: 1; /* 메인축 방향으로 아이템의 크기가 줄어들도록 설정 */
}
.item:nth-child(3){
  background: red;
  flex-basis: 200px;
  flex-shrink: 3; /* /* 메인축 방향으로 아이템의 크기가 줄어들도록 설정 */
}

flex-shrink 는 아이템이 메인축 방향으로 줄어들지 말지를 결정한다. 또한, 얼마만큼 줄어들지도 결정한다. 기본값이 1이기 때문에 1인 경우 따로 설정하지 않아도 되며, 1은 컨테이너가 줄어들때 아이템도 기본적으로 함께 줄어들도록 한다. 

아이템이 줄어들기 시작하는 시점

모든 아이템은 flex-basis: 200px 으로 설정되어 있기 때문에 컨테이너 전체 너비가 아이템의 flex-basis 값을 합한 600px 보다 작아지면 각 아이템은 flex-shrink 에 설정한 비율대로 줄어들기 시작한다. 

컨테이너 크기가 아이템의 flex-basis 를 합한 것보다 작은 경우

flex-grow 와 다르게 숫자가 클수록 더 많이 줄어든다. 1:1:3 비율이므로 세번째 아이템은 첫번째와 두번째 아이템 크기에 비해 1/3 크기로 줄어들게 된다. 

flex: 1 1 200px;

flex-grow, flex-shrink, flex-basis 는 flex 라는 하나의 속성으로 설정할 수도 있다. 

 

* 아이템을 여러줄에 걸쳐서 나열하기 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
    <div class="item">aaa</div>
    <div class="item">bbb</div>
    <div class="item">ccc</div>
  </div>
  <script src="app.js"></script>
</body>
</html>

index.html 파일을 위와 같이 수정하자!

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  align-items: flex-start; /* 아이템을 교차축의 시작점에 정렬하도록 설정 */

  width: 500px; /* 컨테이너 너비를 500px 로 설정 */
  height: 100vh;
}

.item{
  background: orange;
  margin-right: 10px;
}

아래와 같이 아이템이 정렬되다가 컨테이너의 너비를 벗어나게 되는 경우가 존재한다. 

아이템들이 컨테이너 너비를 벗어난 경우

이러한 경우 아이템들이 컨테이너 너비를 벗어나지 않고 여러줄에 걸쳐서 정렬되게 할 수 있다. 

body{
  margin: 0;
  padding: 0;
}

.container{
  border: 1px solid red;
  display: flex; /* 컨테이너에 플럭스박스 적용 */
  flex-wrap: wrap; /* 아이템들이 컨테이너 너비를 벗어나지 않고 여러줄에 걸쳐서 정렬되도록 설정 */
  align-items: flex-start; /* 아이템을 교차축의 시작점에 정렬하도록 설정 */

  width: 50%; /* 컨테이너 너비를 화면의 절반 정도 차지하도록 하기 */
  height: 100vh;
}

.item{
  background: orange;
  margin-right: 10px;
}

컨테이너에 flex-wrap: wrap 을 설정하면 아래와 같이 컨테이너 너비 안에서 여러줄에 걸쳐서 정렬된다. 

컨테이너에 flex-wrap: wrap 을 설정한 화면

 

*  아이템 사이의 간격 설정하기

gap 속성을 사용하면 아이템 사이의 간격을 설정할 수 있다. gap: A B; 로 설정하면 A는 행간격이고, B는 열간격이다.

https://developer.mozilla.org/ko/docs/Web/CSS/gap

 

gap - CSS: Cascading Style Sheets | MDN

CSS gap 속성은 행과 열 사이의 간격 (gutters)을 설정합니다. row-gap (en-US)과 column-gap (en-US)의 단축 속성입니다.

developer.mozilla.org

 

728x90