Centering in CSS: A Complete Guide
목차
- 수평 중앙정렬 Horizontally Centering
- 인라인 엘리먼트
- 블록 엘리먼트
- 하나 이상의 엘리먼트
- 수직 중앙정렬 Vertically Centergin
- 인라인 엘리먼트
- single line
- multiple lines
- 블록 엘리먼트
- 높이를 아는 경우
- 높이를 모르는 경우
- flexbox
- 둘 다 Both Horizontally and Vertically Centering
- 너비와 높이가 고정된 경우
- 너비와 높이를 모르는 경우
- flexbox
- grid
수평 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 |
오역은 댓글로 알려주세요.