본문으로 건너뛰기

CSS 상하좌우 중앙 정렬

무료2017-07-30#Solution#CSS#css绝对居中#css水平竖直居中#css水平垂直居中#垂直居中#IE7居中

2 가지 흥미로운 중앙 정렬 방안

서두에

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 단계의 실제 의미는 다음과 같습니다:

  1. margin 의 계산 방식을 지정하고, 다른 필요한 값이 계산 가능한 경우, automargin 이 남은 공간을 균등하게 나누도록 요구합니다

  2. 필요한 값의 계산 방식을 지정합니다

여기서의 "필요한 값"은 나누어 생각해야 합니다. 수평 방향은 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 의 차이를 상쇄할 수도 있습니다

장단점

단점:

  • 높가가不定한 콘텐츠에 대응할 수 없음 (heightauto 여야 하는 경우)

  • 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 단계를 다시 봅니다:

  1. 수평 중앙 정렬은 문제가 아닙니다

  2. 가상 요소가 행 박스 높이를 컨테이너 가득撑어, vertical-align: middle; 과 협력하여 행 박스 베이스라인 위치를 컨테이너 중심 근처로 끌어내립니다

  3. 콘텐츠 중심점을 행 박스 베이스라인 위쪽0.5ex위치에 맞춥니다

여기까지 보면 분명합니다. 수직 방향은 실제로 중앙 정렬이 아닙니다:

  • 행 박스 베이스라인은 컨테이너 중심과 같지 않습니다

  • 행 박스 베이스라인 위쪽0.5ex위치도 컨테이너 중심과 같지 않습니다

최종적으로 두 중심은 일치하지 않으므로, 이 방식으로 실현하는 중앙 정렬에는 결함이 있으며, 픽셀 수준의 차이가 존재합니다. 아래 그림과 같습니다:

[caption id="attachment_1456" align="alignnone" width="900"]css-center-inline 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. 스타일, 구조 및 주의사항은 모두 소스 코드에 있습니다

참고 자료

댓글

아직 댓글이 없습니다

댓글 작성