Basic of Display: flex

Alpaca·2021년 4월 19일
0

html, css

목록 보기
2/5

flexbox에 관한 내용을 다뤄보려고 한다
이를 위해서는 먼저 inline-block에 대해 알아야 할텐데
blockinline의 성질을 둘 다 갖는 것이라고 이해하면 되는데 예를들면

html

<!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">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
</body>

</html>

css

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
  display: inline-block;
}

각각 위와 같이 입력하면

위와 같이 원치않은 빈공간들이 생긴다
나는 margin을 준적도 position을 줘서 이동한적도 없는데 멋대로 저런 공간이 생겨났다
이외에도 반응형웹사이트를 만들었을 때 각각의 div사이의 공간을 자동으로 균등하게 배분하고 싶다던지 할 때 굉장히 골치가 아픈데 이를 해결해준 것이 flex이다

flex를 사용하기 위해서는 무조건 parent element에게 주어야 한다는 것이다

html

<!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">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <div class="father">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
  </div>
</body>

</html>

css

body {
  background-color: black;
}

.father {
  display: flex;
}

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
}

위와 같이 class="father"를 만들어줘서 거기에 display: flex;를 해줘야한다

그러면 inline-block과는 다르게 사이에 있던 간격이 사라진 것을 볼 수 있다

flex에서 기본적으로 방향은 flex-direction property로 바꿀 수 있는데 default value는 row이고 방향은 horizontal(수평)방향이다

이렇게 방향을 정하면 row방향을 조정하려면 justify-contentcolumn방향을 조정하려면 align-items로 조정하면 된다

만약 flex-direction: column을 하게되면 row방향이 vertical이 되므로 이때는 align-items로 조정하고 column방향을 justify-content로 조정하면 된다

위 그림은 flex-direction: row일때의 axis다
이는 flex-direction: column으로 뒤바뀔 수 있다는 걸 염두해두자

많은 사람들이 item들을 center로 보내고 싶어하는데 align-items를 center로 보내고싶다면 먼저 height(or width)를 지정해주어야 한다는 것을 잊지말자

예를들어

html

<!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">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <div class="father">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
  </div>
</body>

</html>

css

body {
  background-color: black;
}

.father {
  display: flex;
  justify-content: center;
  align-items: center;
  
}

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
}

main axiscross axis를 center로 지정해 줬지만 결과물을 보면

내가원하는 곳으로 가지 않았다
이는 cross axis의 사이즈가 boxheight와 동일하기 때문이므로 이를 움직이기 위해서는 flex father에게 height를 주어야 한다

css

body {
  background-color: black;
}

.father {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 50vh;
}

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
}

inspector로 확인해보면 이렇게 50vh의 높이에서의 가운데정렬이 된 것을 볼 수 있다

또 다른 flexbox의 특성으로는 item들이 모두 같은 줄에 있도록 유지한다는 특성이다
이는 때로 우리를 열받게(?)만드는데 예를들면

html

<!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">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <div class="father">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
    <div class="box">8</div>
  </div>
</body>

</html>

css

body {
  background-color: black;
}

.father {
  display: flex;
  justify-content: space-around;
  height: 50vh;
}

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
}

나는 분명 width: 200px을 주었는데 한줄에 나열되는 특성으로 인해 space-around도 묵살되었고 각 boxwidth는 117.75가 되었다
(설정된 해상도와 browser의 크기마다 보여지는 값은 달라짐)

내가 지정한 크기를 유지하고 싶다면 이런식의 꾸겨넣기(?)는 원치 않을 것이다
이는 flex-wrap으로 해결할 수 있고 default는 nowrap이다

body {
  background-color: black;
}

.father {
  display: flex;
  justify-content: space-around;
  height: 50vh;
  flex-wrap: wrap;
}

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
}

위와 같이 flex-wrap: wrap을 통해 내가 지정한 크기를 유지할 수 있게 되었다
하지만 여기서도 마음에 안드는 부분이 있다
나는 첫째줄과 둘째줄 사이의 공간을 지정해 준적이 없는데 저 공간이 떨어져 있는 이유는 무엇인가?
이를 수정하기 위해서는 align-content를 사용하면 된다 default는 space-around이므로

body {
  background-color: black;
}

.father {
  display: flex;
  justify-content: space-around;
  height: 50vh;
  flex-wrap: wrap;
  align-content: flex-start;
}

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
}


위와 같이 flex-start로 수정할 수 있다

만약 nowrap의 상태에서 browser의 화면을 줄였을 때 좀 더 많이 찌그러지는 element를 내가 지정할 수 있을까?
이를 위해서 flex-shrink를 알아야 하는데 먼저 flex-shrink의 default는 1이다
그리고 이는 flex children에게 주어야한다는 점이다

html

<!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">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <div class="father">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
  </div>
</body>

</html>

css

body {
  background-color: black;
}

.father {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
}

.box:nth-child(2) {
  background-color: aliceblue;
  flex-shrink: 2;
}

두번째 boxflex-shrink: 2를 주자 browser의 크기를 줄이니 2번째 box가 좀 더 많이 줄어드는 것을 알 수 있다
얼마나 많이 줄어들었을까? 정답은 다른 element들 보다 2배많이 줄어들었다

flex-growflex-shrink와 반대로 작용한다(grow란 말 그대로 공간이 있으면 자란다)
flex-grow의 default는 0이다 이를 확인하는 건 여러분 스스로에게 맡기기로 하겠다(살짝 힘들어짐)

flex-growflex-shrinkresponsive web design을 할 때 굉장히 유용하게 사용될 것이다

마지막으로 flex-basis에 대해 배워보자
flex-basis는 찌그러지거나 늘어나기 전 주어지는 width와 비슷한 개념이라 생각하면 된다

왜 비슷한 개념인가? flex-basismain axis에 적용되기 때문에 flex-direction으로 main axis의 방향을 바꾸면 flex-basis의 적용방향도 바뀌기 때문이다

여기까지 flex father에서 어떻게 flex children을 배치하는가에 대해서였다
이제부터는 flex children을 직접적으로 움직이는 것을 배워보자

첫번째는 align-self property를 사용해야되는데 예를들면

html

<!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">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <div class="father">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
  </div>
</body>

</html>

css

body {
  background-color: black;
}

.father {
  display: flex;
  justify-content: space-around;
  height: 50vh;
}

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
}

.box:nth-child(2) {
  align-self: center;
}

2번째 box에만 align-self값을 주게되면

보이는 것과 같이 2번째 box에만 align-items: center를 준 것과 같은 일이 나타난다

또 다른 방법은 order를 사용하는 것이다

css

body {
  background-color: black;
}

.father {
  display: flex;
  justify-content: space-around;
  height: 50vh;
}

.box {
  width: 200px;
  height: 200px;
  background-color: peru;
}

.box:nth-child(2) {
  order: 1;
}

이번엔 2번째 box에만 order: 1을 주게되면

html에서는 1, 2, 3의 순서지만 browser상에서는 1, 3, 2가 된다
그 이유는 무엇인가?

이유는 간단하다 모든 flexbox들의 default value는 order: 0이다 그래서 먼저 그들(여기서는 1과 3)을 나열하고 그 뒤에 order: 1인 2를 나열했기 때문에 위와 같은 결과가 나온 것이다

order는 어떤이유에서든 html을 바꿀 수 없는 상황일 때 유용할 것이다

여기까지가 flex children에게 줄 수 있는 (정렬에 관한) 유일한 두가지의 property였다

  1. align-self
  2. order

flex box에 대한 기본적인 개념은 끝났다
좀 더 깊게 다뤄보고 싶은 사람 혹은 연습이 필요한 사람은 reference를 참고하길 바란다











reference

flexbox mdn
css-tricks

learn flexbox with game
flexbox froggy

profile
2020년 10월 15일 퇴사하고 개발자의 길에 도전합니다.

0개의 댓글