CSS / Flex / align-items

Flexbox의 align-items는 한 줄 안의 아이템을 교차축 방향으로 정렬하는 CSS 속성입니다. 일반적인 가로쓰기에서 row는 세로 방향, column은 가로 방향이 교차축입니다. 부모에 정렬 기준을 지정하고, 한 아이템만 다르게 정렬하려면 그 아이템의 align-self를 사용합니다.

기본 정렬 값과 교차축

값 교차축 방향의 동작
stretch 교차축 크기가 auto인 아이템을 크기 제한 안에서 늘림
flex-start 교차축 시작에 맞춤
flex-end 교차축 끝에 맞춤
center 교차축 가운데에 맞춤
baseline 아이템의 글자 기준선에 맞춤

현재 기본값 normal은 Flex 아이템에서 stretch처럼 동작합니다. 다만 높이나 너비를 무조건 강제로 같게 만드는 것은 아닙니다. 교차축 크기가 auto인지, 최소·최대 크기 제한과 자동 여백이 있는지 등의 조건을 함께 봐야 합니다.

교차축은 주축에 수직인 축입니다. flex-direction을 column으로 바꾸면 align-items를 세로 정렬이라고 설명할 수 없게 됩니다. 주축의 묶음 정렬은 justify-content가 담당합니다.

전체 예제: 높이와 글자 크기가 다른 아이템 비교

아래 코드를 align-items.html로 저장한 뒤 브라우저에서 엽니다. 외부 파일은 필요하지 않습니다. 글자 크기를 14·22·30px로 달리하고 아이템 높이는 지정하지 않아 각 정렬 값의 차이가 드러나게 했습니다. 작은 노란 선은 글자 기준선 위치를 비교하는 표시입니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>교차축 정렬과 기준선 비교</title>
  <style>
    body { margin: 20px; font: 16px/1.6 "Noto Sans KR", sans-serif; color: #203348; }
* { box-sizing: border-box; }
    h1 { font-size: 24px; }
    h2 { margin: 14px 0 6px; font-size: 16px; }
    .samples { max-width: 560px; }
    .box { display: flex; gap: 12px; height: 110px; padding: 10px;
      border: 1px solid #84a3b7; background: #edf4f8; }
    .item { flex: none; padding: 8px; line-height: 1.3;
      color: white; background: #176b86; }
    .item:nth-child(1) { font-size: 14px; }
    .item:nth-child(2) { font-size: 22px; }
    .item:nth-child(3) { font-size: 30px; }
    .mark { display: inline-block; width: 8px; height: 0;
      border-top: 1px solid #f3ce5b; }
    .stretch { align-items: stretch; }
    .flex-start { align-items: flex-start; }
    .flex-end { align-items: flex-end; }
    .center { align-items: center; }
    .baseline { align-items: baseline; }
  </style>
</head>
<body>
<h1>align-items 비교</h1>
<div class="samples">
<h2>stretch</h2>
<div class="box stretch">
  <div class="item">가<i class="mark" aria-hidden="true"></i></div>
  <div class="item">나<i class="mark" aria-hidden="true"></i></div>
  <div class="item">다<i class="mark" aria-hidden="true"></i></div>
</div>
<h2>flex-start</h2>
<div class="box flex-start">
  <div class="item">가<i class="mark" aria-hidden="true"></i></div>
  <div class="item">나<i class="mark" aria-hidden="true"></i></div>
  <div class="item">다<i class="mark" aria-hidden="true"></i></div>
</div>
<h2>flex-end</h2>
<div class="box flex-end">
  <div class="item">가<i class="mark" aria-hidden="true"></i></div>
  <div class="item">나<i class="mark" aria-hidden="true"></i></div>
  <div class="item">다<i class="mark" aria-hidden="true"></i></div>
</div>
<h2>center</h2>
<div class="box center">
  <div class="item">가<i class="mark" aria-hidden="true"></i></div>
  <div class="item">나<i class="mark" aria-hidden="true"></i></div>
  <div class="item">다<i class="mark" aria-hidden="true"></i></div>
</div>
<h2>baseline</h2>
<div class="box baseline">
  <div class="item">가<i class="mark" aria-hidden="true"></i></div>
  <div class="item">나<i class="mark" aria-hidden="true"></i></div>
  <div class="item">다<i class="mark" aria-hidden="true"></i></div>
</div>
</div>
</body>
</html>

stretch에서는 세 아이템이 상자 안쪽 높이에 맞춰 늘어납니다. flex-start는 위쪽, flex-end는 아래쪽, center는 각 아이템의 세로 중심을 맞춥니다. baseline은 상자 윗면이나 아랫면을 맞추는 대신 글자 기준선을 맞추므로, 글자 크기가 다르면 아이템의 위쪽 위치도 달라집니다.

다른 글자 크기의 세 아이템을 stretch, flex-start, flex-end, center, baseline으로 정렬한 브라우저 화면

첫 .stretch 규칙의 stretch만 center로 바꾸면 아이템은 필요한 높이로 줄어들며 가운데에 놓입니다. 원래대로 복원한 뒤 컨테이너 높이만 150px로 바꾸어, stretch는 더 높아지고 center는 높아진 공간의 가운데에 남는지 확인하세요. 실습 후 110px로 되돌립니다.

stretch가 안 늘어날 때와 한 아이템만 정렬하기

row 배치에서 아이템에 height: 70px처럼 높이를 정했다면 stretch가 그 높이를 임의로 지우고 전체 높이까지 늘리지 않습니다. min-height·max-height 같은 제약도 결과에 영향을 줍니다. column에서는 교차축이 가로이므로 width 쪽의 auto 여부와 제약을 확인해야 합니다.

/* 전체 예제의 style 마지막에 추가해 비교 */
.stretch .item {
  height: 70px;
}
.center .item:last-child {
  align-self: flex-end;
}

첫 규칙은 stretch 상자에서도 아이템 높이를 70px로 고정합니다. 두 번째 규칙은 center 상자의 마지막 다 아이템만 아래쪽으로 옮기며, 앞의 두 아이템은 가운데를 유지합니다. 두 선언을 지우면 원래 비교 화면으로 돌아갑니다. align-self는 컨테이너가 아니라 해당 Flex 아이템에 지정한다는 점이 핵심입니다.

교차축의 자동 여백은 align-self보다 우선해 공간을 사용할 수 있습니다. 예를 들어 row 배치에서 margin-top: auto가 적용된 아이템은 아래로 밀릴 수 있습니다. align-items가 무시되는 것처럼 보이면 해당 아이템의 align-self와 교차축 margin도 함께 확인하세요.

column의 가로 정렬과 align-content의 차이

전체 예제의 .center 규칙에 아래 세 선언을 추가하면 아이템은 세로로 쌓이면서 가로 가운데에 놓입니다. 높이는 세 아이템이 들어갈 만큼 주었습니다. 같은 center라도 방향 변경으로 정렬 축이 달라지는 비교입니다.

.center {
  flex-direction: column;
  height: 240px;
  align-items: center;
}

실습 후 flex-direction과 height를 제거하면 원래 row·110px 배치로 돌아갑니다. 다른 CSS에서 width를 100%로 강제했다면 가로 가운데 이동이 눈에 보이지 않을 수 있으므로 아이템 크기와 부모 폭을 함께 확인하세요.

flex-wrap으로 줄이 여러 개가 되면 align-items는 각 줄 안에서 아이템을 정렬합니다. 줄 묶음 전체의 교차축 공간 분배는 align-content의 역할입니다. 한 줄 예제에서 align-content만 바꾸어 높이가 다른 아이템의 정렬을 해결하려고 하지 마세요. Grid에도 align-items가 있지만 그리드 영역 안의 축과 조건을 별도로 해석해야 합니다.

교차축 정렬과 stretch의 조건은 MDN align-items 문서, 개별 정렬과 자동 여백의 관계는 align-self 문서에서 확인할 수 있습니다.