flexbox
에 관한 내용을 다뤄보려고 한다
이를 위해서는 먼저 inline-block
에 대해 알아야 할텐데
block
과 inline
의 성질을 둘 다 갖는 것이라고 이해하면 되는데 예를들면
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-content
로 column
방향을 조정하려면 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 axis
와 cross axis
를 center로 지정해 줬지만 결과물을 보면
내가원하는 곳으로 가지 않았다
이는 cross axis
의 사이즈가 box
의 height
와 동일하기 때문이므로 이를 움직이기 위해서는 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
도 묵살되었고 각 box
의 width
는 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;
}
두번째 box
에 flex-shrink: 2
를 주자 browser의 크기를 줄이니 2번째 box
가 좀 더 많이 줄어드는 것을 알 수 있다
얼마나 많이 줄어들었을까? 정답은 다른 element들 보다 2배
많이 줄어들었다
flex-grow
는 flex-shrink
와 반대로 작용한다(grow란 말 그대로 공간이 있으면 자란다)
flex-grow
의 default는 0이다 이를 확인하는 건 여러분 스스로에게 맡기기로 하겠다(살짝 힘들어짐)
flex-grow
와 flex-shrink
는 responsive web design
을 할 때 굉장히 유용하게 사용될 것이다
마지막으로 flex-basis
에 대해 배워보자
flex-basis
는 찌그러지거나 늘어나기 전 주어지는 width
와 비슷한 개념이라 생각하면 된다
왜 비슷한 개념인가? flex-basis
는 main 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
였다
- align-self
- order
flex box
에 대한 기본적인 개념은 끝났다
좀 더 깊게 다뤄보고 싶은 사람 혹은 연습이 필요한 사람은 reference
를 참고하길 바란다
reference
learn flexbox with game
flexbox froggy