서두에
transform, flex 가 등장한 후, 수평 수직 중앙 정렬은 이미 쉬워졌습니다. 예를 들어 만능인:
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
/* 1.콘텐츠 좌상단 중앙 정렬 */
top: 50%; left: 50%;
/* 2.음의 반 너비와 높이로 콘텐츠를 되돌림 */
-webkit-transform: translate(-50%, -50%);
핵심은 transform 의 퍼센트가 자신의 너비와 높이에 상대적으로 계산되는 특성을 이용하는 것입니다. 만약 환경이 transform 을 지원하지 않는다면, 일부 오래되었지만 매우정교한 기술을 사용해야 합니다
margin 중앙 정렬
특징이 명확한 방법:
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
/* 1.자신의 콘텐츠를 포함 블록에 대해 중앙 정렬 */
margin: auto;
/* 2.자신의 너비와 높이 계산 방식 지정 */
width: 100px; height: 100px;
원리
핵심은 margin 의 계산 규칙을 이용하는 것입니다:
'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = 포함 블록의 너비
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = 포함 블록의 높이
(인용 10.3.7 절대 위치 지정의 치환 불가능한 요소、10.6.4 절대 위치 지정의 치환 불가능한 요소)
margin 중앙 정렬은 위의 방정식에 제한 조건을 추가하는 것입니다:
margin-top === margin-bottom && margin-left === margin-right
이것은 margin 으로 중앙 정렬을 실현하는 핵심입니다
CSS 의 2 단계의 실제 의미는 다음과 같습니다:
-
margin의 계산 방식을 지정하고, 다른 필요한 값이 계산 가능한 경우,auto는margin이 남은 공간을 균등하게 나누도록 요구합니다 -
필요한 값의 계산 방식을 지정합니다
여기서의 "필요한 값"은 나누어 생각해야 합니다. 수평 방향은 left, right, width 입니다. 다음과 같은 규칙이 있기 때문입니다:
만약'left', 'width', 'right'가 모두'auto'라면……
만약 이 3 개의 값이 모두'auto'가 아니라면……
그렇지 않은 경우,'auto'값을 가진'margin-left'와'margin-right'를 0 으로 설정한 후, 아래 6 개 규칙 중 적절한 1 개를 선택하여 적용합니다
5.'width'가'auto'이고, 'left'와'right'가'auto'가 아니면, 'width'를 구합니다
즉, 만약
left: 0;
right: 0;
width: auto;
라면
margin-left: auto;
margin-right: auto;
의 실제 효과는
left: 0;
right: 0;
margin-left: 0;
margin-right: 0;
width: auto;
가 됩니다
margin auto 가 무효화됩니다 (0 으로 리셋됩니다). 따라서 width 는 필요한 값이며, 그계산 방식을 지정해야 합니다. 예를 들어 수치, 퍼센트, 또는제한 조건(max-width 등) 입니다
수직 방향은 top, bottom, height 로, 대응하는 규칙은 수평 방향과 유사합니다:
5.'height'가'auto'이고, 'top'과'bottom'이'auto'가 아니면, 'auto'값을 가진'margin-top'과'margin-bottom'을 0 으로 설정한 후, 'height'를 구합니다
따라서 height 도 필요한 값입니다
이렇게 보면, 가장 눈에 띄는 tblr 전체 0 은중점이 아니며, width, height 와 마찬가지로, margin auto 를 계산 가능하게 하는 필요한 값일 뿐입니다. 따라서 이렇게 배열해야 합니다:
position: absolute;
/* 1.자신의 콘텐츠를 포함 블록에 대해 중앙 정렬 */
margin: auto;
/* 2.margin auto 계산에 필요한 필요한 값 지정 */
top: 0; bottom: 0; left: 0; right: 0;
width: 100px; height: 100px;
게다가, tblr 전체 0 은 분명히 불필요합니다:
top: 30px; bottom: 30px; left: 50px; right: 50px;
도 가능하며, 더 나아가서, tblr 을 사용하여 상하 (좌우) padding, border-width 의 차이를 상쇄할 수도 있습니다
장단점
단점:
-
높가가不定한 콘텐츠에 대응할 수 없음 (
height가auto여야 하는 경우) -
WP 하에서 무효 (무시할 수 있다고 가정)
장점:
-
[IE8+] 대응
-
resize지원 (사용자가 콘텐츠 우하단을 드래그해도 중앙 정렬 유지)
inline 중앙 정렬
매우 교묘한 방식:
.center-inline-container {
/* 1.콘텐츠 수평 중앙 정렬 */
text-align: center;
}
.center-inline-container:before {
/* 너비 0 스페이스 */
content: '\200B';
display: inline-block;
/* 2.콘텐츠 높이를撑음 */
height: 100%;
vertical-align: middle;
}
.center-inline-content {
display: inline-block;
/* 3.수직 중앙 정렬 */
vertical-align: middle;
}
원리
핵심은 vertical-align: middle; 을 이용하여 수직 중앙 정렬을 실현하는 것입니다:
이 박스의 수직 중점을 부모 박스의 베이스라인에 부모의 반 x-height 를 더한 위치에 맞춥니다
즉:
콘텐츠의 세로 방향 중점 위치 = 부모 박스의 베이스라인 위치 + 부모의 반 x-height 높이
먼저 부모 박스의 베이스라인 위치를 확정합니다:
'inline-block'(박스) 의 베이스라인은 마지막 일반 플로우 내 행 박스의 베이스라인입니다. 단, 플로우 내 행 박스가 없거나'overflow'속성의 계산값이'visible'이 아닌 경우는 제외합니다. 이 경우 베이스라인은 bottom margin 에지입니다
"마지막 일반 플로우 내 행 박스의 베이스라인"을 계속 찾아야 합니다:
같은 행의 박스를 포함하는 직사각형 영역을 행 박스라고 합니다
CSS 2.1 은 행 박스 베이스라인의 위치를 정의하지 않았습니다
문제에 부딪혔습니다. 명세는 행 박스의 베이스라인이 어느 위치에 있는지 말하지 않았지만, 제한 조건을 제공했습니다:
인라인 레벨 박스는'vertical-align'속성에 따라 수직으로 정렬됩니다.'top'또는'bottom'정렬인 경우, 행 박스 높이가 최소화되도록 정렬해야 합니다
이러한 간접적인 제한을 만족한 후, 행 박스 베이스라인 위치를 확정합니다. 행 박스 베이스라인 위치의 영향 요인은 다음과 같습니다:
-
행 박스 내 인라인 레벨 박스의
vertical-align,height,line-height -
행 박스가 위치한 컨테이너의
line-height -
기타 (다른 것도 있을 수 있음)
다른 케이스에서는 행 박스 베이스라인 위치가 다를 수 있지만, 최종 베이스라인 위치를 쉽게 표시할 수 있습니다:
Just add a character at the beginning of the line in questions
일반적으로 작은 알파벳 x 를 추가하고, x 바닥에 밀착된 위치가 베이스라인입니다
다음으로 "부모의 반 x-height 높이"를 확정합니다. 이는 비교적 쉽습니다:
ex: 관련 폰트의'x-height'
'ex'단위는 요소의 첫 번째 사용 가능한 폰트에 따라 정의됩니다. 예외는'ex'가'font-size'속성의 값에 나타나는 경우로, 이 경우 부모 요소의'ex'를 참조합니다
'x-height'라고 불리는 이유는 일반적으로 소문자"x"의 높이와 같기 때문입니다. 그러나"x"를 포함하지 않는 폰트에서도'ex'가 정의됩니다
폰트의 x-height 는 몇 가지 다른 방식으로 얻을 수 있습니다. 일부 폰트는 x-height 에 대한 신뢰할 수 있는 명세를 포함합니다. 신뢰할 수 있는 폰트 명세를 얻을 수 없는 경우, UA 는 소문자 자형의 높이에 따라 x-height 를 결정할 수 있습니다. 하나의 가능한 힌트는 소문자"o"자형이 베이스라인 아래로 얼마나 뻗어 있는지 보고, 그 바운딩 박스의 top 값을 빼는 것입니다. x-height 를 결정하는 것이 불가능하거나 비현실적인 경우, 0.5em 을 사용해야 합니다
즉:
x-height = 현재 폰트의 x-height || 소문자 자형의 높이에 따라 x-height 결정 || 0.5em
따라서 "반 x-height 높이"(0.5ex) 는 약0.25em입니다
CSS 의 3 단계를 다시 봅니다:
-
수평 중앙 정렬은 문제가 아닙니다
-
가상 요소가 행 박스 높이를 컨테이너 가득撑어,
vertical-align: middle;과 협력하여 행 박스 베이스라인 위치를 컨테이너 중심 근처로 끌어내립니다 -
콘텐츠 중심점을 행 박스 베이스라인 위쪽
0.5ex위치에 맞춥니다
여기까지 보면 분명합니다. 수직 방향은 실제로 중앙 정렬이 아닙니다:
-
행 박스 베이스라인은 컨테이너 중심과 같지 않습니다
-
행 박스 베이스라인 위쪽
0.5ex위치도 컨테이너 중심과 같지 않습니다
최종적으로 두 중심은 일치하지 않으므로, 이 방식으로 실현하는 중앙 정렬에는 결함이 있으며, 픽셀 수준의 차이가 존재합니다. 아래 그림과 같습니다:
[caption id="attachment_1456" align="alignnone" width="900"]
css-center-inline[/caption]
margin-top 을 사용하여 수정하는 것을 시도할 수 있지만, 행 박스 베이스라인에는 확정된 계산 방법이 없으므로, 완벽한 수정은できません. Demo 에서 보면, 0.25ex 가 가장 적절해 보입니다. 실제 적용에서는 미세 조정이 필요할 수 있습니다 (픽셀 수준 결함이気になる 경우)
장단점
단점:
-
픽셀 수준의 결함이 존재하여 해결할 수 없으며, 완벽한 수직 중앙 정렬이 아닙니다
-
HTML 공백 문자가 공간을 차지하는 문제가 존재하며 (HTML 압축, 또는 컨테이너
font-size: 0, 콘텐츠에서font-size리셋), 수평 중앙 정렬에 영향을 줍니다 -
추가 요소/가상 요소가 필요합니다
장점:
-
[IE8+] 대응
-
不定한 높이 콘텐츠 지원
온라인 Demo
Demo 주소:http://ayqy.net/temp/css-center.html
P.S. 스타일, 구조 및 주의사항은 모두 소스 코드에 있습니다
참고 자료
-
Vertical-Align: All You Need To Know: CSS 명세와 결합하여 line box, inline box, baseline 등을 정리, 번역 대기
아직 댓글이 없습니다