CSS 레이아웃(2)

깨진알·2023년 11월 25일

CSS

목록 보기
8/10

CSS 레이아웃(2)

Flexbox

요소들을 일차원으로 배치하는 기능(가로방향 또는 세로방향)

1. 배치 방향

flex-direction을 사용하면 기본 축의 방향을 정할 수 있다. 기본 값은 row이다.

.container {
	border: 5px dashed #cacfd9;
	width: 500px;
	height: 500px;
	display: flex; /* 기본적으로 flexbox는 왼쪽에서 오른쪽 방향(가로) */
	flex-direction: column; /* 세로 방향 */ /* row-reverse, column-reverse => 반대 방향에서 시작 */
}

2. 기본 축 정렬 : justify-content

3. 교차 축 정렬 : align-items

기본 값은 stretch(늘려서 배치하기)이다.

.container {
	border: 5px dashed #cacfd9;
	width: 500px;
	height: 500px;
	display: flex;
	justify-content: center; <!-- 기본축에서 중앙 정렬 -->
	align-items: center; <!-- 교차축에서 중앙 정렬 -->
}

justify-content: space-between은 가로 축 방향에서 양쪽으로 배치하게 만든다.

4. 요소가 넘칠 때 : flex-wrap

<div class="container">
      <div class="red box">1</div>
      <div class="green box">2</div>
      <div class="blue box">3</div>
      <div class="red box">4</div>
      <div class="green box">5</div>
      <div class="blue box">6</div>
      <div class="red box">7</div>
      <div class="green box">8</div>
      <div class="blue box">9</div>
    </div>
.container {
	display: flex;
	flex-wrap: wrap; /* 넘치는 부분은 교착 축 방향으로 넘어가게 된다 -> column도 마찬가지 */
}

5. 간격 : gap

숫자 하나를 쓰면 모든 방향의 간격을 지정할 수 있다. 세로 가로 순서대로 숫자를 두 개 쓰면 세로 간격, 가로 간격을 지정할 수 있다. 이때 세로와 가로는 기본 축 방향이라는 상관없다.

.container {
	display: flex;
	flex-wrap: wrap;
	gap: 30px 60px; /* 넘쳤을 때 가로 방향뿐만 아니라 세로 방향에도 적용됨*/
}

6. 요소 늘려서 채우기 : flex-grow

기본 값은 0이다. flex-grow값이 클수록 많이 늘어난다.

7. 요소 줄여서 채우기 : flex-shrink

요소들의 크기가 커서 넘치는 경우, 요소의 크기를 줄여서 플렉스박스 안에 가득 채운다. flex-shrink의 기본 값이 1이기 때문에 기본적으로 요소를 줄여서 배치하고, 0으로 지정하면 크기가 줄어들지 않는다. flex-shirnk값이 클수록 상대적으로 많이 줄어든다.

플렉스박스에서 요소의 크기를 늘리거나 줄이지 않으려면 flex-shrink: 0을 추가해주면 된다.

8. flex-basis 속성

flex-grow와 flex-shirnk를 사용할 때 width나 height 값으로 크기가 결정되는게 아니다. 사실 플렉스박스에서는 고정된 크기가 있는 게 아니라 시작 크기와 최종 크기가 있다. 기본 축(Main Axis)에서는 시작 크기를 정해 놓으면 플렉스박스 안에서 유연하게 최종 크기가 결정된다. 빗금을 친 부분만큼의 시작 크기에서, 화살표만큼 최종 크기로 늘어나거나 줄어드는 걸 볼 수 있다. (width값이 큰 값이지만, flex-shrink에 의해서 줄어들었다.)
플렉스박스에서 요소의 시작 크기는 flex-basis라는 속성으로 지정할 수 있다.(기본 값 auto) 기본 축의 방향이 가로 방향이면 width, 세로 방향이면 height를 참고해서 시작 크기를 정한다. 그렇기 때문에 width나 height만 잘 정해주면 별문제 없이 잘 작동한다. 하지만 플렉스박스에서 크기를 정하고 싶을 때는 보다 정확하게 flex-basis를 사용하는 걸 추천한다.

* flex 속성

/* width 속성으로 시작 크기를 지정하기 */
flex-grow: 1;
flex-shrink: 0;
width: 100px;

/* flex-basis 속성으로 시작 크기를 지정하기 */
flex-grow: 1;
flex-shrink: 0;
flex-basis: 100px;

/* flex 속성으로 짧게 쓰기 */
flex: 1 0 100px;

9. 인라인 안에서 flexbox 만들기

  • 인라인 안에서 세로 정렬을 하고 싶을 때
<p>
  코딩, 쉬워질 때도 됐다. 
  <a class="new-window-link" href="https://codeit.kr">
    코드잇
    <img class="icon" src="new-window-link.svg" alt="새 창 열기" width="13" height="13">
  </a>
  에서 지금 바로 시작해보세요.
</p>
.logo {
  width: 13px;
  height: 13px;
}

.new-window-link {
}

새 창 열기 아이콘을 정확히 글 가운데다가 세로로 정렬하고 싶을 때, 우선 <a> 태그에 적용된 .new-window-link 클래스에다가 display:flex로 플렉스박스를 만들고, 여기다 정렬이랑 간격을 넣어 보아라.

.new-window-link {
  display: flex;
  align-items: center;
  gap: 4px;
}

이런 식으로 아예 줄이 넘어가게 된다. .new-window-link 클래스에서 <a> 태그의 display: inline이라는 기본 값을 display: flex로 바꿔 줬기 때문이다. display: flex라고 하면 그 안에서는 플렉스박스의 규칙에 따라 배치되고, 그 바깥에서 플렉스박스 전체에 대해서는 마치 display: block처럼 위에서 아래로 배치되기 때문이다.
이럴 때는 display: inline-flex를 쓰면 된다. 플렉스박스를 만들어서 동시에 플렉스박스 전체를 마치 display: inline처럼 배치하는 방식이다.

.new-window-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

10. Flexbox 안에서 포지셔닝하기

플렉스박스의 요소에 position을 지정하면 어떻게 되는지 알아보자.
결론부터 말하자면 자기 자신의 원래 위치를 기준으로 배치되는 static, relative, sticky를 제외하고는 플렉스박스의 흐름에서 벗어나게 배치된다. 흐름에서 벗어난다는 건, 플렉스박스 바깥에 있는 요소처럼 동작한다는 것이다.
absolute랑 fixed는 원래 자리를 차지하지 않고 글의 흐름에서 아예 빠졌는데, 플렉스박스에서도 마찬가지로 플렉스박스 영향을 받지 않는다.

  • 플렉스박스에 배치되는 경우 : relative, sticky
<div class="container">
    <div class="red box">RED</div>
    <div class="green box">GREEN</div>
    <div class="blue box">BLUE</div>
</div>
.container {
  border: 5px dashed #cacfd9;
  width: 100%;
  height: 500px;
  display: flex;
  position: relative;
  align-items: flex-start;
}

.box {
  border-radius: 15px;
  color: #f9fafc;
  padding: 10px;
}

.red {
  background-color: #e46e80;
}

.green {
  background-color: #32b9c1;
  flex-grow: 1;
    position: relative;
  top: 100px;
  left: 100px;
}

.blue {
  background-color: #5195ee;
}

relative 포지션은 요소의 원래 위치를 기준으로 배치하는 거라고 했다. 일단 플렉스박스 안에서 다를 요소들처럼 배치된 다음에 그 위치를 기준으로 배치된다. 즉, 원래 자리를 차지하고 있는다.

.green {
  background-color: #32b9c1;
  flex-grow: 1;
    position: sticky;
  top: 0;
}

sticky도 마찬가지이다. sticky 포지션은 기본적으로 static처럼 원래 위치에 있다가 지정한 위치에 스크롤되면 fixed처럼 화면에 고정된다. 그렇기 때문에 일단은 플렉스박스 안에서 배치되고 그다음에 sticky로 배치된다.

  • 플렉스박스에서 벗어나는 경우 : absolute, fixed
<div class="container">
  <div class="red box">RED</div>
  <div class="green box">GREEN</div>
  <div class="blue box">BLUE</div>
</div>
.container {
  border: 5px dashed #cacfd9;
  width: 100%;
  height: 500px;
  display: flex;
  position: relative;
  align-items: flex-start;
}

.box {
  border-radius: 15px;
  color: #f9fafc;
  padding: 10px;
}

.red {
  background-color: #e46e80;
}

.green {
  background-color: #32b9c1;
  flex-grow: 1;
    position: absolute;
  top: 100px;
  left: 100px;
}

.blue {
  background-color: #5195ee;
}

absolute 포지션은 포지셔닝된 가장 가까운 조상을 기준으로 배치되고, fixed는 브라우저 화면을 기준으로 배치된다고 했다. 이 둘의 공통점은 요소의 원래 자리를 차지하지 않는다는 것이다. 즉, 글의 흐름에서 벗어나는 건데, 마찬가지로 플렉스박스 안에서도 아예 벗어난다.
플렉스박스 안에서 마치 .green <div>가 없는 것처럼 배치되었다. 그리고 flex-grow: 1도 적용이 되지 않았다.

.green {
  background-color: #32b9c1;
  flex-grow: 1;
    position: fixed;
  top: 100px;
  left: 100px;
}

fixed는 브라우저 화면을 기준으로 배치되기 때문에 플렉스박스와 상관없이 배치된다. 나머지 요소들은 .green <div>가 없는 것처럼 배치되었고, flex-grow도 적용이 되지 않았다.

profile
프론트엔드 지식으로 가득찰 때까지

0개의 댓글