커닝은 텍스트의 시각적 균일성을 달성하기 위해 특정 문자 쌍 사이의 공간을 선택적으로 조정하는 것입니다. 모든 문자 사이의 거리를 균일하게 변경하는 트래킹과 달리, 커닝은 각 문자 쌍(A와 V, T와 o, W와 a)의 모양을 고려합니다. 커닝이 없으면 돌출된 요소가 있는 조합이 불균일하게 보이며 문자 사이에 시각적 공백이나 압축이 발생합니다. Apple NSAttributedString 문서에 따르면, iOS에서 커닝은 .kern 속성을 통해 구성되며 양수와 음수 값을 모두 지원합니다.
핵심 요점
커닝은 시각적 아티팩트를 제거하기 위해 특정 문자 쌍 사이의 거리를 수동 또는 자동으로 조정하는 프로세스입니다. 각 문자가 고유한 기하학적 구조를 가지고 있기 때문에 문제가 발생합니다. A는 정점, V는 오른쪽 기울임, T는 넓은 가로 막대를 가지고 있습니다. 이러한 문자가 나란히 있을 때 설정된 너비(set width)가 같더라도 윤곽선 사이의 거리가 불균일해 보입니다.
글꼴 커닝 테이블에는 미리 설정된 조정 값이 있는 문자 쌍이 포함되어 있습니다. 좋은 서체에는 300~2000개의 커닝 쌍이 있을 수 있습니다. 전문 서체 — Apple의 SF Pro 또는 Google의 Roboto — 는 라틴 문자와 키릴 문자의 모든 가능한 조합을涵盖하는 정교하게 제작된 커닝 테이블을 포함합니다. Fontshop Guide to Kerning에 따르면, 커닝 테이블의 품질은 전문 글꼴의 주요 지표 중 하나입니다.
커닝의 시각적 효과는 특히 제목, 로고 및 큰 글꼴 크기(24pt 이상)에서 두드러집니다. 작은 텍스트(12~14pt)에서는 문자 간격이 좁아 커닝이 덜 눈에 띄지만 여전히 작동합니다. 웹 브라우저와 모바일 OS는 기본적으로 내장 커닝을 적용하지만, 개발자는 특정 디자인에 대해 비활성화하거나 조정할 수 있습니다.
초보 개발자는 종종 커닝과 트래킹을 혼동하지만, 이들은 근본적으로 다른 타이포그래피 매개변수입니다. 커닝은 문자 쌍 수준에서 작동하며 문자 기하학이 시각적 불균형을 만드는 특정 조합 사이의 간격만 조정합니다. 트래킹(letter-spacing)은 선택한 텍스트 조각의 모든 문자 사이의 간격을 균일하게 변경합니다 — 균일하게 증가시키거나 감소시킵니다.
트래킹이 사용되는 경우: 작은 텍스트의 가독성을 향상시키기 위해(양수 트래킹), 강조 제목을 만들기 위해(음수 트래킹), 인터페이스 디자인에서 텍스트 스타일링을 위해. 트래킹은 숫자 값으로 설정되며 이미 커닝된 쌍을 포함한 모든 문자에 적용됩니다 — 커닝 보정은 유지되지만 그 위에 전체적인 이동이 추가됩니다.
| 매개변수 | 커닝 | 트래킹 |
|---|---|---|
| 적용 범위 | 개별 문자 쌍 | 전체 텍스트 조각 |
| 값 | 각 쌍마다 고유 | 모든 문자에 균일 |
| 목적 | 시각적 균일성 | 텍스트 밀도 조정 |
| iOS 속성 | NSAttributedString의 .kern | CSS의 letter-spacing |
| 시인성 | 24pt 이상의 제목에서 | 모든 글꼴 크기에서 |
중요한 규칙: 음수 트래킹(압축)에서는 커닝 쌍에 주의하세요 — 원하지 않는 문자 겹침이 발생할 수 있습니다. CSS에서 letter-spacing 속성은 글꼴의 커닝 테이블 위에 적용되며, 강한 압축(letter-spacing: -1px)에서는 커닝 보정으로 인해 문자가 합쳐질 수 있습니다.
iOS에서 커닝은 NSAttributedString의 .kern 속성을 통해 관리됩니다. 속성 값은 Float이며, 양수는 간격을 늘리고, 음수는 줄이며, 0은 커닝을 비활성화합니다. 기본값은 nil로, 글꼴의 커닝 테이블을 사용함을 의미합니다. 커닝 작업을 위한 기본 API는 텍스트 범위에 속성을 추가하는 NSMutableAttributedString입니다.
let text = "Kerning in mobile interfaces"
let attributedText = NSMutableAttributedString(
string: text
)
// 커닝 활성화 (글꼴 테이블 사용)
attributedText.addAttribute(
.kern,
value: 0.5,
range: NSRange(
location: 0,
length: text.count
)
)
// UILabel에 적용
label.attributedText = attributedText
기본값 .kern = nil은 글꼴 테이블의 커닝을 활성화합니다. 커닝을 완전히 비활성화해야 하는 경우 .kern = 0을 설정합니다. 값 0.0과 nil은 다른 상태입니다. nil은 테이블을 사용하고, 0은 모든 커닝 쌍을 강제로 0으로 만듭니다. Apple Text Programming Guide에 따르면, 명시적으로 0을 설정하는 것은 고정폭 텍스트나 커닝이 방해가 되는 경우(예: 고정 너비 버튼)에 유용합니다.
SwiftUI는 Text에 .kerning() 수정자를 제공합니다. UIKit과 달리 SwiftUI에서는 커닝이 속성 문자열이 아닌 뷰 수준에서 설정됩니다. 수정자는 CGFloat을 허용하며 Text 블록 내의 모든 텍스트에 적용됩니다. SwiftUI에서 부분 커닝을 위해서는 Text의 + 연산자와 개별 수정자의 조합이 사용됩니다.
struct KerningView: View {
var body: some View {
Text("커닝이 있는 제목")
.kerning(1.0)
.font(.title)
}
}
성능: 커닝 속성이 있는 NSAttributedString은 렌더링 중에 문자 위치를 다시 계산합니다. 정적 텍스트의 경우 한 번만 발생합니다. 동적 텍스트(UICollectionView에서 변경되는 텍스트)의 경우 변경될 때마다 발생합니다. 긴 문자열(500자 이상)에서 커닝이 포함된 큰 범위를 사용하면 스크롤 중 FPS가 저하될 수 있습니다.
Android에서 커닝은 TextView 및 XML 레이아웃의 letterSpacing 속성을 통해 관리됩니다. 속성은 Float 유형이며 글꼴의 em 크기의 배수로 작동합니다. 값 0은 기본 커닝에 해당하고, 양수는 간격을 늘리며, 음수는 줄입니다. letterSpacing은 API Level 21(Android 5.0 Lollipop)부터 사용 가능합니다.
SpannableString을 통한 구현은 전체 텍스트 대신 문자열의 일부에 커닝을 적용할 수 있게 합니다. 정밀한 제어를 위해 ScaleXSpan 클래스 또는 사용자 정의 ReplacementSpan이 사용됩니다. Android Developer Guide에 따르면, ScaleXSpan은 문자를 수평으로 확대/축소하여 문자 간격 변경을 시뮬레이션하지만 직접적인 커닝 쌍 제어는 제공하지 않습니다.
// XML 레이아웃에서
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text with kerning"
android:letterSpacing="0.05" />
// Kotlin에서 프로그래밍 방식으로
val textView = findViewById<TextView>(R.id.myTextView)
textView.letterSpacing = 0.05f
제한 사항: Android는 커닝 테이블을 직접 지원하지 않습니다 — letterSpacing은 모든 문자에 대해 트래킹으로 작동합니다. Android에서 쌍 커닝을 위해서는 내장 커닝 테이블(OpenType GPOS feature kern)이 있는 글꼴이 사용됩니다. 지원 여부는 OS 버전과 렌더링 엔진에 따라 다릅니다. Android 10+에서는 Minikin이 완전한 OpenType 기능 지원과 함께 사용되고, 이전 버전에서는 HarfBuzz가 제한적으로 사용됩니다. 권장 사항: Android 8.0 미만 기기에서 커닝 표시를 테스트하세요.
웹에서 커닝은 CSS 속성 font-kerning을 통해 제어되며, 글꼴의 내장 커닝 테이블을 활성화 또는 비활성화합니다. 값: auto(브라우저가 결정), normal(커닝 활성화), none(커닝 비활성화). 이 속성은 2016년부터 모든 최신 브라우저에서 지원됩니다. MDN Web Docs에 따르면, font-kerning은 커닝 테이블이 있는 OpenType 글꼴에만 적용됩니다.
CSS 속성 letter-spacing은 트래킹과 유사하지만 커닝과 같은 효과에도 사용됩니다. font-kerning과 달리 letter-spacing은 커닝 쌍을 고려하지 않고 모든 문자 사이의 간격을 균일하게 변경합니다. 두 속성이 모두 사용되는 경우 font-kerning이 먼저 적용된 다음 letter-spacing이 그 위에 균일한 이동을 추가합니다.
/* Enable kerning for headings */
h1 {
font-kerning: normal;
letter-spacing: 0.02em;
}
/* Disable kerning for monospace */
code, pre {
font-kerning: none;
}
TypeScript 유틸리티는 커닝을 고려한 최적의 letter-spacing을 계산하기 위해 Canvas API를 통해 글꼴의 커닝 테이블을 분석할 수 있습니다. 하지만 실제로 웹 개발자는 font-kerning: normal에 의존하며, 대부분의 경우 최적의 결과를 제공합니다. 추가 letter-spacing 조정은 디자인 악센트(예: 큰 타이포그래피를 사용한 랜딩 페이지)에만 필요합니다.
커닝은 미세 조정 도구이며, 잘못 적용하면 가독성이 저하됩니다. 첫 번째 규칙: 본문 텍스트의 커닝을 변경하지 마세요. 전문 글꼴의 커닝 테이블에는 이미 12~16pt 크기에 최적화된 값이 포함되어 있습니다. 본문 텍스트 커닝에 간섭하면 불균일성과 시각적 노이즈가 발생합니다.
두 번째 규칙: 24pt 이상의 제목에는 양수 커닝(서체에 따라 0.5~1.5pt)을 사용하세요. 큰 텍스트는 가독성을 위해 더 많은 문자 간격이 필요합니다. x-height가 낮은 글꼴(Didot 등)은 x-height가 높은 글꼴(Helvetica 등)보다 더 많은 커닝이 필요합니다. 참고 데이터: iOS Apple Music 앱에서 제목은 0.8pt 커닝을 사용합니다.
세 번째 규칙: Lorem Ipsum이 아닌 실제 문자열에서 항상 커닝을 테스트하세요. 다른 문자 조합은 다른 시각적 효과를 만듭니다. 돌출된 요소가 있는 모음과 자음 쌍(AV, Te, To, Wa, LT)에 특히 주의하세요. 음수 커닝에서는 fi, fl, fj 쌍에 주의하세요 — 일부 글꼴에서는 합자 없이 합쳐질 수 있습니다.
접근성 측면: 난독증이 있는 사용자는 약간의 양수 커닝(0.3~0.5pt)이 적용된 텍스트를 더 잘 읽습니다. iOS와 Android는 앱 커닝을 재정의할 수 있는 접근성 설정을 지원합니다. Dynamic Type과 함께 UIFontDescriptor를 사용하고 UIAccessibility를 통해 접근성 설정에서 커닝을 고려하세요. 중요: 시스템 커닝 설정을 차단하지 마세요 — 이는 텍스트 적응에 관한 WCAG 2.2 지침 1.4.12를 위반합니다.
자주 묻는 질문
NSAttributedString에서 .kern = 0 속성을 설정하세요. 값 0은 내장 글꼴 테이블을 포함한 모든 커닝 쌍을 강제로 0으로 만듭니다. 전체 텍스트 수준에서 완전히 비활성화하려면 attributedText를 통해 UILabel 매개변수에서 .kern = 0을 설정하세요.
커닝은 문자 간의 거리를 변경하며 모양은 그대로 유지합니다. 합자는 두 개 이상의 문자를 하나의 글리프로 대체합니다. 합자는 커닝이 원하지 않는 병합을 제거할 수 없는 경우(예: fi 쌍)에 자주 사용됩니다.
네, Android 10(API 29)부터 OpenType GPOS feature kern을 완전히 지원하는 Minikin 렌더링이 사용됩니다. 이전 버전에서는 지원 여부가 기기 제조업체와 HarfBuzz 버전에 따라 다릅니다. 여러 기기에서 테스트하는 것이 좋습니다.
AVOWaToLt 문자열을 사용하세요 — 여기에는 문제가 있는 커닝 쌍이 포함되어 있습니다. 시각적 간격이 육안으로 보이면 글꼴의 커닝 테이블 품질이 낮은 것입니다. 전문적인 확인을 위해 FontForge 또는 Glyphs 도구를 사용하세요.
네. UICollectionView에서 커닝이 있는 NSAttributedString을 동적으로 업데이트할 때 문자 위치 재계산으로 인해 스크롤 중 FPS가 저하될 수 있습니다. 긴 목록의 경우 속성 문자열을 캐시하거나 기본 설정으로 UILabel을 사용하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.