본문 바로가기

CSS

CSS 가운데정렬 : 완벽 가이드

Centering in CSS: A Complete Guide

목차

항상 검색하는게 성질나서 저장을 위한 번역글. 의미없는 사족은 뺐습니다.

원글은 이곳입니다.





수평 Horizontally

Inline 혹은 Inline-* 레벨의 엘리먼트인가요? (텍스트 혹은 링크처럼)

block 레벨 부모 엘리먼트 안에서 수평으로 inline 엘리먼트를 중앙정렬 할 수 있어요 :

.center-children {
  text-align: center;
}
cs


inline, inline-block, inline-table, inline-flex, 기타 등등에 적용됩니다.

block 레벨의 엘리먼트인가요?

block 레벨 엘리먼트는  margin-left 와  margin-right 가  auto 이면 가운데 정렬이 가능합니다. 
( width 를 갖고 있다면요. 그렇지 않다면 전체 너비가 될 것이고, 그럼 정렬이 필요없겠죠)
다음과 같이 축약됩니다: 

.center-me {
  margin: 0 auto;
}
cs

이 방법은 중심에 놓을 block 레벨 엘리먼트 혹은 부모의 폭에 상관없이 적용됩니다. 
가운데로 요소를  float 할 수 없다는 것을 알아두세요. 하지만 트릭이 있긴 합니다.

하나 이상의 block 레벨 엘리먼트가 있나요?

두 개 이상의 block 레벨 엘리먼트가 가로로 가운데에 위치해야 하는 경우, 다른 유형의  display 타입으로 만드는 것이 더 나을 수도 있습니다. 아래 엘리먼트들을  inline-block 으로 만든 예와,  flexbox의 예가 있습니다:


서로 다른 block 레벨 엘리먼트들이 서로의 상단에 쌓여 있는 것이 아니라면, auto margin 테크닉은 여전히 유효합니다:

수직 Vertically

수직 센터링은 CSS에서 약간 더 까다롭죠.

Inline 혹은 Inline-* 레벨의 엘리먼트인가요? (텍스트 혹은 링크처럼)

수직정렬엔 단계가 더 있습니다.

single line 인가요?

때로는 inline/text 엘리먼트들이 수직으로 가운데 정렬되어 나타날 수 있어요. 
위아래로 동일한 padding이 있기 때문이죠.

.link {
  padding-top: 30px;
  padding-bottom: 30px;
}
cs

만약 몇몇 이유로 padding을 사용할 수 없고, wrap 하지 않을 텍스트를 가운데 정렬하려고 한다면,
line-height 와 height 를 동일하게 만들어서  center 정렬하는 트릭도 있어요.

.center-text-trick {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}
cs

multiple lines 인가요?

위쪽과 아래쪽에 같은 padding을 사용하면 여러 줄의 텍스트에도 가운데정렬 효과를 줄 수 있습니다. 
그러나 이 방법이 작동하지 않는다면, 텍스트가 들어있는 엘리먼트를  table cell 로 만들 수 있죠.
이 경우 일반적으로 row에 정렬된 엘리먼트의 정렬을 처리하는 것과는 달리 vertical-align 속성이 이걸 제어할 수 있어요. ( 참고)


아마 flexbox를 사용할 수도 있지 않을까요? flex 부모 안에 있는 하나의 flex-child는 넘모 쉽게 정렬할 수 있어요.

.flex-center-vertically {
  display: flex;
  justify-content: center;
  flex-direction: column;
  height: 400px;
}
cs

부모 컨테이너가 고정된 높이(fixed height: px, %, etc)를 갖는 경우에만 관련있다는 것을 기억하세요. 
위 예제의 컨테이너가 높이를 갖고 있는게 보이실 겁니다.

위의 두 가지 테크닉 모두 아웃이면, "ghost element" 테크닉을 사용할 수 있습니다. 
이 테크닉에서는 전체 높이(full-height)의 가짜 엘리먼트가 컨테이너 안에 위치하고, 텍스트는 수직정렬됩니다.

.ghost-center {
  position: relative;
}
.ghost-center::before {
  content: " ";
  display: inline-block;
  height: 100%;
  width: 1%;
  vertical-align: middle;
}
.ghost-center p {
  display: inline-block;
  vertical-align: middle;
}
cs

block 레벨의 엘리먼트인가요?

엘리먼트의 높이를 알고 있나요?

많은 이유 때문에 웹페이지 레이아웃의 높이를 모르는 것이 일반적입니다:
  • 너비가 변경되면, text reflow가 높이를 변경할 수 있습니다.
  • 텍스트 스타일을 변경하면 높이가 변경될 수도 있습니다.
  • 텍스트의 양에 따라 높이가 변경될 수도 있습니다.
  • 이미지와 같이 고정된 종횡비를 지닌 엘리먼트들은 리사이즈될때 높이가 변합니다.... 등등등.
그러나 높이를 알고 있다면 다음과 같이 수직으로 가운데에 정렬할 수 있습니다.

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px; /* account for padding and border if not using box-sizing: border-box; */
}
cs

엘리먼트의 높이를 모른다구요?

절반의 높이에서 밀어 올려서 중심을 맞추는 것이 여전히 가능합니다.

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
cs

flexbox를 사용할 수 있나요?

놀랍지도 않죠. flexbox에선 너무 쉽다구요.

.parent {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
cs

수직 & 수평 모두 Both Horizontally and Vertically

위의 테크닉을 어떤 방식으로든 결합해 완벽하게 가운데 배치된 엘리먼트들을 얻을 수 있습니다. 

너비와 높이가 고정된 엘리먼트인가요?

너비와 높이의 절반에 해당하는 음수 margin을 사용하면 postion: absolute 로 50% / 50% 에 배치한 후에 크로스브라우저 지원을 통해 가운데 배치합니다. 

.parent {
  position: relative;
}
.child {
  width: 300px;
  height: 100px;
  padding: 20px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -70px 0 0 -170px;
}
cs

너비와 높이를 모르는 엘리먼트인가요?

너비나 높이를 모르면 transform 속성과 양방향으로 50% 크기의 역변환(negative translate)을 사용할 수 있습니다. 
(엘리먼트의 현재 너비/높이를 기준으로 합니다.)

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
cs

flexbox를 사용할 수 있나요?

flexbox를 사용해 양방향으로 중심을 맞추려면 두 가지 centering 속성을 사용해야 됩니다:

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

grid를 사용할 수 있나요?

이건 귀여운 트릭인데, 하나의 엘리먼트에 꽤 잘 적용됩니다.

body, html {
  height: 100%;
  display: grid;
}
span { /* thing to center */
  margin: auto;
}
cs


오역은 댓글로 알려주세요.