웹 라벨에서 특정 합자 하나를 비활성화하려면 해당 글자를 인라인 span으로 감싸고 그 부분에서 관련 합자 기능을 비활성화하세요. 다른 텍스트는 설정을 그대로 유지합니다. CSS에는 글꼴 전체에서 이름이 지정된 합자 하나만 비활성화하는 일반적인 스위치가 없습니다. MDN의 합자 제어는 개별 대체 항목이 아니라 기능 범주를 정의합니다.
이 가이드는 웹 페이지의 HTML과 CSS를 편집하는 Mac 사용자를 위한 것입니다. 구체적인 작업은 합성 라벨 fine flake office fine에서 첫 번째 fi를 분리하면서 나머지 텍스트의 합자는 유지하는 것입니다. 간단한 로컬 테스트를 통해 특정 항목 하나를 바꾸는 것과 기능 전체를 바꾸는 것의 차이를 확인할 수 있습니다.
CSS로 선택적으로 비활성화할 수 있는 것은 무엇인가요?
하나의 합자 기능에는 여러 대체 항목이 포함될 수 있습니다. liga을 비활성화한다는 것은 해당 텍스트에 대해 그 기능을 비활성화한다는 뜻입니다. 특정 글자 쌍 하나를 선택한다는 뜻은 아닙니다. 마찬가지로 font-variant-ligatures: no-common-ligatures는 liga과 clig을 통해 일반 합자를 제어합니다. 실제 대체 항목은 글꼴에 따라 달라집니다. MDN: font-variant-ligatures
유용한 구분은 설정이 적용되는 위치와 설정이 제어하는 글꼴 기능입니다. 기능 자체에 여러 합자가 포함되어 있어도 마크업을 사용하면 설정 범위를 두 글자로 좁힐 수 있습니다. 따라서 글꼴 전체를 대상으로 하는 제외 스위치 없이 특정 항목에만 적용하는 우회 방법이 됩니다.
| 원하는 결과 | 적절한 방법 | 조건 |
|---|---|---|
fi의 특정 항목 하나를 분리 |
해당 항목을 감싸고 그 부분에서 기능을 비활성화 | 마크업을 편집할 수 있음 |
| 일반 합자는 유지하면서 임의 합자를 제거 | 대상 요소에 no-discretionary-ligatures 사용 |
원치 않는 대체 항목이 dlig에 속함 |
다른 모든 일반 합자는 유지하면서 모든 fi 제거 |
가능한 경우 문서화된 글꼴별 기능 사용 | 글꼴에서 필요한 제어 기능을 제공해야 함 |
| 편집할 수 없는 애플리케이션에서 특정 항목 하나 변경 | 해당 애플리케이션에 문서화된 문자 단위 서식 기능 확인 | 웹 CSS로는 데스크톱 애플리케이션의 지원 여부를 알 수 없음 |
지원되는 범주에는 font-variant-ligatures을 우선 사용하세요. MDN은 사용 가능한 경우 상위 수준 글꼴 속성을 권장합니다. 다른 경우에는 font-feature-settings을 사용해 하위 수준 OpenType 기능에 접근할 수 있습니다. font-feature-settings: \"liga\" off라고 작성해도 쌍별 제어 기능이 생기는 것은 아닙니다. MDN: font-feature-settings
Mac에서 로컬 비교하기
관련 없는 페이지 스타일의 영향을 받지 않고 결과를 비교할 수 있도록 먼저 독립 파일을 사용하세요. TextEdit에서 File > New를 선택한 다음 Format > Make Plain Text를 선택합니다. 아래의 완전한 예제를 입력하고 ligature-demo.html로 저장한 뒤, 메시지가 나타나면 Use .html을 선택하세요. TextEdit에서 HTML 파일을 만드는 방법은 Apple이 문서화한 절차입니다. Apple: Mac의 TextEdit에서 HTML 문서 작업하기
저장한 파일을 브라우저에서 엽니다. 이 예제는 로컬에서 사용할 수 있는 글꼴을 쓰며 라이브러리나 다운로드가 필요하지 않습니다. 글꼴 목록은 예시일 뿐입니다. 선택한 글꼴에 관련 합자가 있어야 차이가 눈에 보입니다. 테스트 대상은 브라우저 렌더링이며, 특정 글리프 모양을 전제로 하지 않습니다.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ligature comparison</title>
<style>
body {
margin: 2rem;
color: #222;
background: #fff;
font-family: system-ui, sans-serif;
}
main {
max-width: 42rem;
}
.sample {
font-family: Georgia, "Times New Roman", serif;
font-size: 2.5rem;
line-height: 1.5;
letter-spacing: normal;
font-variant-ligatures: common-ligatures;
}
.separate-pair,
.all-common-off {
font-variant-ligatures: no-common-ligatures;
}
</style>
</head>
<body>
<main>
<h2>Baseline</h2>
<p class="sample">fine flake office fine</p>
<h2>First pair separated</h2>
<p class="sample"><span class="separate-pair">fi</span>ne flake office fine</p>
<h2>All common ligatures disabled</h2>
<p class="sample all-common-off">fine flake office fine</p>
</main>
</body>
</html>
가운데 행에서는 span이 대상 fi의 두 글자를 모두 포함합니다. 해당 행의 나머지 부분에는 일반 합자 설정이 상속됩니다. 이처럼 순전히 스타일을 묶을 때는 span이 적절합니다. WHATWG는 span을 자체적으로 의미를 추가하지 않고 자식 요소를 나타내는 요소로 정의합니다. WHATWG: span 요소
다음 세 단계로 비교하세요.
- 기준 행과 가운데 행에서 첫 번째
fine를 비교합니다. 전체 너비만 보지 말고 글자 모양을 살펴보세요. - 두 행에서
flake,office, 마지막fine를 비교합니다. 이 글자들은 예외 범위 밖에 있으므로 원래 기능 설정을 유지해야 합니다. - 아래 행을 다른 행과 비교합니다. 이 행은 더 광범위한 제어 예시로, 행 전체에서 일반 합자를 비활성화합니다.
세 행이 모두 똑같아 보인다면 비교 결과가 명확하지 않은 것입니다. 샘플 글꼴을 실제 사용하려는 글꼴로 바꾸고 해당 글꼴에서 합자를 지원한다고 문서화된 글자 조합을 선택하세요. 선택한 글꼴에 없는 대체 항목은 CSS 선언으로 보여줄 수 없습니다.
텍스트 흐름을 방해하지 않고 예외 적용하기
짧은 라벨에서는 분리하려는 전체 문자열을 span으로 바로 감싸세요. 예제의 fi과 ne처럼 앞뒤 문자를 소스에서 서로 붙여 두세요. 마크업을 읽기 쉽게 만들려고 단어 안에 공백이나 줄바꿈을 넣지 마세요.
span에는 기능 설정 변경이 필요합니다. 스타일이 지정되지 않은 span 안에 글자 하나만 넣는 것으로는 합자를 안정적으로 끊을 수 없습니다. W3C의 텍스트 사양은 유효한 서식 변경이 없는 경우 인라인 경계를 넘어 셰이핑이 계속되어야 한다고 규정합니다. 또한 여백, 테두리, 패딩 또는 다른 서식이 셰이핑을 끊는 조건도 정의합니다. W3C: 요소 경계를 넘는 셰이핑
이 예외는 일반 인라인 span으로 유지하세요. inline-block, 간격 또는 레이아웃 래퍼를 추가하면 작업에 필요하지 않은 레이아웃 결정이 늘어납니다. 타이포그래피 설정을 적용한 뒤 브라우저 창의 너비를 줄이고 라벨을 실제 컨테이너에서 확인하세요. 글리프 선택이 바뀌면 텍스트가 차지하는 공간도 달라질 수 있으므로 줄바꿈이 그대로인지 확인하세요.
문자열이 더 긴 경우에는 의도한 경계를 명확히 정하세요. 원치 않는 대체 항목에 ffi이 포함된다면 fi만 감싸는 것도 더 큰 문자열 내부에 서식 경계를 만듭니다. 겹치는 각 대체 항목이 독립적으로 동작한다고 가정하지 말고 전체 단어와 주변 글자를 테스트하세요.
기존 페이지에 예제를 적용할 때는 소스나 컴포넌트에서 해당 라벨을 편집하세요. 예외 하나를 추가하려고 보이는 텍스트만 바탕으로 문단 전체를 다시 만들지 마세요. 기존 링크, 강조, 요소 구조를 유지하세요. 이 예제는 임의 페이지 전체에서 자동으로 바꾸려는 것이 아니라, 알고 있는 특정 항목 하나를 처리합니다.
합자가 그대로 남거나 다른 합자까지 사라진다면 어떻게 하나요?
곧바로 재정의를 더 추가하지 말고, 비교 결과를 순서대로 진단에 활용하세요.
먼저 기능 범주를 확인하세요. 이 예제는 일반 합자를 대상으로 합니다. 글꼴 설명에서 원치 않는 대체 항목이 dlig 아래에 있다고 명시한다면 대신 예외에 no-discretionary-ligatures을 적용하세요. 문맥 대체 항목에는 calt이 관련될 수 있으며, 이는 no-contextual로 제어합니다. 해당 설정은 선택한 텍스트의 다른 문맥 형태에도 영향을 줄 수 있습니다. MDN의 기능 범주 정의
다음으로 서로 충돌하는 설정을 확인하세요. 기존 font-feature-settings 선언이 font-variant-ligatures에서 암시되는 기능 선택을 덮어쓸 수 있습니다. W3C는 기능을 해석하는 과정에서 하위 수준 기능 설정이 나중에 적용된다고 명시합니다. span 방식이 지원되지 않는다고 결론 내리기 전에 해당 선언을 검토하세요. W3C: 글꼴 기능 및 변형 해석
그다음 범위를 확인하세요. 다른 단어의 합자까지 사라진다면 예외 클래스가 대상 span에만 적용되었는지 확인하세요. 문단이나 그 컨테이너에 설정을 적용하면 훨씬 더 넓은 텍스트 범위에 영향을 줍니다. 로컬 예제의 아래 행은 의도적으로 더 넓은 결과를 보여줍니다.
마지막으로 선택적 타이포그래피와 필수 셰이핑을 구분하세요. font-variant-ligatures: none은 이 작업에 필요한 범위보다 더 광범위하며, 필수 합자는 이 속성의 비활성화 제어 대상이 아닙니다. W3C는 이 속성에서도 필수 합자를 유지하도록 명시합니다. W3C: 합자
합자 유형 하나를 모든 곳에서 제거하려는 경우에는 로컬 span 기법을 원하는 각 항목에 적용해야 합니다. 글꼴별 기능이 더 간단한 해법일 수 있지만, 태그와 효과는 해당 글꼴의 문서를 따라야 합니다. 스타일 세트 번호가 글꼴마다 같은 의미를 가진다고 가정하지 마세요.
셰이핑 라이브러리는 더 세밀한 제어를 제공하나요?
HarfBuzz는 hb_feature_t를 통해 기능 범위를 제공합니다. 기능에는 태그, 값, 포함 시작값, 제외 종료값이 있으며 클러스터 값으로 표현됩니다. 이를 사용하면 셰이핑 라이브러리를 호출하는 애플리케이션에서 제한된 범위에 기능 설정을 적용할 수 있습니다. 그래도 범위는 기능의 적용 범위일 뿐, 이름이 지정된 합자 하나를 선택하는 보편적인 선택자는 아닙니다. HarfBuzz: hb_feature_t
이 API는 일반 페이지 CSS와 다른 계층에 속합니다. HarfBuzz가 문서화한 방법은 기능 요청을 hb_shape()에 전달합니다. 예제는 브라우저 스타일시트 옵션을 추가하는 방법이 아니라 셰이핑 버퍼와 글꼴 조회 규칙을 설명합니다. 이 Mac 웹 라벨 작업에 사용자 지정 셰이핑 파이프라인을 도입하면 인라인 예외를 적용하는 것보다 일이 늘어납니다. HarfBuzz: OpenType 기능
마지막으로 대상 글자 쌍과 주변 합자, 실제 표시 너비에서의 라벨을 확인하세요. 작동하는 가장 작은 예외를 유지하세요. 즉, 원치 않는 전체 문자열 하나를 span으로 감싸고 그 부분에서 적절한 기능을 비활성화하며 나머지 텍스트는 의도한 설정을 유지하도록 합니다.
출처
- font-variant-ligatures — MDN Web Docs.
- font-feature-settings — MDN Web Docs.
- Mac의 TextEdit에서 HTML 문서 작업하기 — Apple.
- 웹 개발자용 HTML 표준: span 요소 — WHATWG.
- CSS Text Module Level 3: 요소 경계를 넘는 셰이핑 — W3C.
- CSS Fonts Module Level 4 — W3C.
- hb-common: HarfBuzz 매뉴얼 — HarfBuzz.
- OpenType 기능 — HarfBuzz.