문제
브라우저는 어센더 및 디센더와 같은 글꼴별 측정항목과 줄 높이를 수용하기 위해 텍스트 문자 위와 아래에 공백을 자동으로 추가합니다. 이 '고스트 공간'으로 인해 표준 CSS를 사용하여 완벽한 세로 정렬을 구현할 수 없습니다.
일반적인 문제는 다음과 같습니다.
- 정렬되지 않은 아이콘:
align-items: center를 사용해도 텍스트가 인접한 아이콘보다 시각적으로 낮거나 높게 표시됩니다. - 부정확한 패딩:
padding: 12px가 있는 버튼은 글꼴의 내부 행간으로 인해 시각적으로 상단 또는 하단에 더 많은 공간이 있는 것처럼 보입니다. - 정렬 플러시: '매직 넘버' 음수 여백을 사용하지 않으면 대문자의 상단을 컨테이너 또는 인접한 이미지의 상단과 정확하게 정렬할 수 없습니다.
해결 방법
text-box-trim 및 text-box-edge 속성 (약식 text-box)을 사용하면 특정 글꼴 측정항목을 기반으로 이 내부 선행을 자를 수 있습니다. 텍스트 상자를 cap-height (대문자 상단) 및 alphabetic baseline (대부분의 문자 하단)으로 자르면 요소의 경계 상자가 시각적 콘텐츠와 일치하도록 할 수 있습니다.
구현 전략
- 필수: 텍스트가 포함된 요소에
text-box-trim: trim-both(또는text-box약식)를 적용합니다. - 필수:
text-box-edge을 사용하여 자르기에 사용할 측정항목을 지정합니다. 대부분의 UI 정렬에는cap alphabetic를 사용합니다. - 권장사항: 플렉스 또는 그리드 컨테이너에서 시각적 세로 중앙 정렬을 위해 이 속성을 사용합니다.
- 권장사항: CSS
padding값이 텍스트와 컨테이너 가장자리 사이의 시각적 간격과 일치하도록 하는 데 사용합니다. - 가독성을 위해 기존 줄 간격이 필요한 긴 본문 텍스트에는 사용하지 마세요. 제목, 버튼, UI 라벨에 가장 적합합니다.
구현 가이드
사용 사례 1: 배지의 내부 선행 자르기
글꼴마다 텍스트 위아래에 기본 제공되는 간격이 다릅니다. 이로 인해 디자인을 일치시키거나 배지에서 텍스트를 시각적으로 중앙에 배치하는 데 어려움이 있을 수 있습니다. 컨테이너의 패딩이 텍스트를 정확하게 감싸도록 하려면 text-box: trim-both cap alphabetic를 사용합니다. 이는 배지나 태그와 같은 밀집된 UI 구성요소에 특히 유용합니다. 이렇게 하면 패딩이 모든 면의 텍스트 가장자리에서 바로 시작됩니다.
.badge {
padding: 10px;
background: hotpink;
border-radius: 10px;
/*
Trims the top to the cap-height and
the bottom to the alphabetic baseline.
*/
text-box: trim-both cap alphabetic;
}
사용 사례 2: 아이콘이 있는 텍스트 중앙 정렬
Flexbox를 사용하여 텍스트와 아이콘을 정렬할 때 '고스트 공간'으로 인해 텍스트가 약간 중심에서 벗어난 것처럼 보이는 경우가 많습니다. 상자를 자르면 레이아웃 엔진이 실제 표시되는 문자 높이를 사용하여 정렬합니다.
.button {
display: inline-flex;
align-items: center;
gap: 8px;
}
/*
text-box does NOT inherit, and must be applied directly to the text element.
*/
.button-text{
/*
The flex container now centers against the
visible letters, not the invisible font box.
*/
text-box: trim-both cap alphabetic;
}
사용 사례 3: 텍스트를 위쪽 가장자리에 맞추기
제목을 인접한 이미지 또는 장식 요소의 상단과 완벽하게 정렬하려면 trim-start cap alphabetic를 사용합니다. 끝부분이 잘리지 않더라도 끝 가장자리를 정의해야 합니다.
.hero {
display: flex;
align-items: flex-start;
}
h1 {
/* MANDATORY: The bottom edge must also be defined, even though only the top is trimmed. */
text-box: trim-start cap alphabetic;
}
권장사항
- 간결성을 위해
text-box약어를 사용합니다(text-box: <trim-direction> <edges>). - 한쪽 가장자리만 자르는 경우에도 항상 양쪽 가장자리를 모두 지정해야 합니다(기본
text가장자리를 사용하지 않는 경우). line-height와 결합하여 간격을 제어합니다(권장). 자르기를 사용하면 텍스트의 첫 번째 줄과 마지막 줄 앞의 행간이 삭제되지만line-height은 여러 줄 텍스트의 줄 간격에 여전히 영향을 미칩니다.- 모든 요소에 적용하지 않습니다. 정밀한 정렬이 필요한 경우에만 사용하세요.
대체 전략
text-box은 점진적 개선입니다. 이를 지원하지 않는 브라우저에서는 텍스트가 기본 행간으로 렌더링됩니다. 레이아웃은 계속 작동하지만 정밀도가 약간 떨어집니다. 이전 브라우저에서는 속성이 안전하게 무시되므로 특별한 대체 코드가 필요하지 않습니다.
기타 고려사항
- 글꼴 측정항목: 글꼴마다 내부 측정항목이 다릅니다.
cap alphabetic는 안정적인 기본값이지만 일부 글꼴이나 사용 사례에서는 소문자 정렬을 개선하기 위해ex(x-height)가 필요할 수 있습니다. - 여러 줄 텍스트: 블록의 첫 번째 줄과 마지막 줄에 트리밍이 적용됩니다. 내부 회선은 영향을 받지 않습니다.