Reference/At-rules/@font-feature-values

김동현·2026년 3월 28일

mdn 학습 번역 - CSS

목록 보기
175/190

@font-feature-values

Baseline | Widely available

Chrome, Edge, Firefox, Safari에서 지원돼요.

이 기능은 잘 확립되어 있고 많은 기기와 브라우저 버전에서 작동해요. 2023년 3월부터 모든 브라우저에서 사용 가능했어요.

@font-feature-values CSS at-rule을 사용하면 OpenType에서 다르게 활성화되는 기능들에 대해 font-variant-alternates 프로퍼티에서 공통 이름을 사용할 수 있어요. 여러 폰트를 사용할 때 CSS를 단순화하는 데 도움이 될 수 있어요.

@font-feature-values at-rule은 CSS의 최상위 레벨에서 사용하거나 CSS 조건부 그룹 at-rule 내부에서 사용할 수 있어요.

구문 (Syntax)

/* "Font Name"이라는 폰트에 대해 기능을 정의합니다 */
@font-feature-values Font Name {
  font-display: swap;
  @styleset {
    nice-style: 12;
  }
  @swash {
    fancy: 2;
  }
}

@font-feature-values 블록은 아래에 나열된 특징 값 블록(feature value blocks) 리스트를 포함할 수 있고, font-display 디스크립터도 함께 사용할 수 있어요.


특징 값 블록 (Feature value blocks)

@swash

font-variant-alternates 속성의 swash() 함수와 함께 작동할 기능 이름을 지정해요. 스워시(swash) 특징 값 정의는 단 하나의 값만 허용합니다. 예를 들어 ident1: 2는 괜찮지만, ident2: 2 4처럼 두 개를 쓰는 건 안 돼요.

@annotation

font-variant-alternatesannotation() 함수와 연동될 이름을 지정해요. 주석(annotation) 특징 값 정의도 딱 하나의 값만 가질 수 있습니다.

@ornaments

font-variant-alternatesornaments() 함수와 연동될 이름을 지정해요. 장식(ornaments) 특징 값 정의 역시 단 하나의 값만 허용합니다.

@stylistic

font-variant-alternatesstylistic() 함수와 연동될 이름을 지정해요. 스타일 특징(stylistic) 값 정의도 단 하나의 값만 가질 수 있어요.

@styleset

font-variant-alternatesstyleset() 함수와 연동될 이름을 지정해요. 스타일 세트(styleset) 특징 값 정의는 개수 제한 없이 값을 나열할 수 있어요. 예를 들어 ident1: 2 4 12 1이라고 쓰면 OpenType 값인 ss02, ss04, ss12, ss01에 각각 매핑됩니다. 참고로 99보다 큰 값도 문법적으로는 유효하지만, 실제 OpenType 값에는 매핑되지 않아서 무시될 거예요.

@character-variant

font-variant-alternatescharacter-variant() 함수와 연동될 이름을 지정해요. 문자 변형(character-variant) 정의는 한 개 또는 두 개의 값을 가질 수 있습니다. ident1: 3cv03=1에 매핑되고, ident2: 2 4cv02=4에 매핑되는 식이죠. 하지만 ident2: 2 4 5처럼 세 개를 쓰는 건 안 됩니다.


형식적인 구문 (Formal syntax)

@font-feature-values = 
  @font-feature-values <family-name># { <declaration-rule-list> }  

<family-name> = 
  <string>          |
  <custom-ident>+  

이 구문은 CSS Fonts Module Level 4의 최신 표준을 반영하고 있습니다. 모든 브라우저가 모든 기능을 지원하는 것은 아니니, 브라우저 호환성 정보를 확인해 보세요.


예제 (Examples)

@font-feature-values 규칙에서 @styleset 사용하기

이 예제는 서로 다른 폰트에 같은 이름의 스타일 규칙을 적용하는 방법을 보여줍니다. 폰트마다 "nice-style"이 가리키는 실제 OpenType 번호는 다르지만, 사용할 때는 똑같은 이름을 쓸 수 있어서 코드가 훨씬 깔끔해져요.

/* "Font One" 폰트를 위한 "nice-style" 정의 */
@font-feature-values Font One {
  @styleset {
    nice-style: 12;
  }
}

/* "Font Two" 폰트를 위한 "nice-style" 정의 */
@font-feature-values Font Two {
  @styleset {
    nice-style: 4;
  }
}

/* 단 한 줄의 선언으로 정의한 스타일들을 적용합니다 */
.nice-look {
  font-variant-alternates: styleset(nice-style);
}

공식문서에 대한 추가적인 설명

공식 문서의 내용이 조금 딱딱하고 추상적이라서 이해하기 어려우셨죠? 당연히 그럴 수 있어요.

@font-feature-values는 쉽게 말해 "복잡한 폰트 기능 번호에, 우리가 알아보기 쉬운 예쁜 별명을 붙여주는 기능"입니다.

스마트폰 연락처에 '010-1234-5678'이라는 복잡한 번호 대신 '엄마', '팀장님'이라고 이름을 저장해두고 부르는 것과 완벽하게 똑같은 원리예요. 자, 영어 폰트와 한국어 폰트를 예시로 들어 아주 자세하고 실용적으로 설명해 드릴게요!


1. 도대체 왜 필요한가요? (문제점)

고급 폰트(OpenType 폰트) 안에는 숨겨진 디자인들이 많아요.
예를 들어, 숫자 '1, 2, 3'을 높낮이가 다르게 나오는 '고전 스타일'로 바꾸거나, 'Q'나 'R' 같은 알파벳의 꼬리를 아주 화려하게 길게 빼는 기능들이 들어있죠.

예전에는 이걸 쓰려면 아래처럼 암호 같은 코드를 써야 했어요.

/* 예전 방식: 암호를 외워야 함 */
.text {
  /* ss01이 뭔지, swsh가 뭔지 폰트 제작자가 만든 매뉴얼을 봐야만 알 수 있음 */
  font-feature-settings: "ss01" 1, "swsh" 2; 
}

폰트마다 이 번호(ss01, ss02 등)가 뜻하는 디자인이 다릅니다. A라는 영어 폰트에서는 ss01이 '화려한 대문자'인데, B라는 한국어 폰트에서는 ss01이 '동그라미 숫자(①, ②)'일 수도 있어요. 폰트가 바뀔 때마다 저 암호 같은 번호를 다 수정해야 하니 미칠 노릇이죠.

이걸 해결하기 위해 나온 것이 바로 @font-feature-values입니다!


2. 주요 기능 (특징 값 블록)

별명을 붙일 때, 그 기능이 어떤 종류인지 카테고리를 정해줘야 해요. 자주 쓰는 4가지만 확실히 아시면 됩니다.

  • @swash (스워시): 글자의 시작이나 끝 꼬리를 화려하게 둥글게 말아주는 장식 효과입니다. (주로 영어 영문 필기체/세리프 폰트에 많음)
  • @styleset (스타일 세트): 폰트 디자이너가 미리 묶어둔 글자 스타일 세트예요. "대문자를 전부 고전적으로 바꿔라" 같은 세트입니다.
  • @annotation (주석): 글자 주변에 동그라미(①)나 네모 괄호를 쳐주는 등의 형태입니다. (주로 한국어/일본어/한자 폰트에 많음)
  • @character-variant (글자 변형): 딱 특정 알파벳이나 글자 하나의 모양만 살짝 바꾸는 기능이에요. (예: 소문자 'a'를 1층 모양(ɑ)으로 쓸지, 2층 모양(a)으로 쓸지 결정)

3. 실전 예시: 영어 폰트 편 (EB Garamond)

클래식하고 우아한 영문 폰트인 EB Garamond를 사용한다고 가정해 볼게요. 이 폰트는 알파벳 꼬리를 길게 빼는 화려한 스워시(swsh 1번) 기능과, 숫자의 높낮이를 다르게 하는 옛날식 숫자 스타일(ss01)을 지원합니다.

CSS로 별명 짓기

/* 1. EB Garamond 폰트에 대한 별명을 정의합니다 */
@font-feature-values "EB Garamond" {
  
  /* 화려한 꼬리 장식에 'fancy-tail'이라는 별명을 붙입니다 (내부 코드는 1번) */
  @swash {
    fancy-tail: 1;
  }

  /* 옛날식 숫자 스타일에 'old-numbers'라는 별명을 붙입니다 (내부 코드는 1번) */
  @styleset {
    old-numbers: 1;
  }
}

/* 2. 이제 암호 대신 내가 지은 별명으로 스타일을 적용합니다! */
.title-text {
  font-family: "EB Garamond", serif;
  /* font-variant-alternates 속성을 사용해서 별명을 불러옵니다 */
  font-variant-alternates: swash(fancy-tail); 
}

.price-text {
  font-family: "EB Garamond", serif;
  font-variant-alternates: styleset(old-numbers);
}

이렇게 해두면 나중에 코드를 읽을 때 "아, .title-text는 화려한 꼬리를 썼고, .price-text는 옛날 숫자를 썼구나!" 하고 단번에 알아볼 수 있습니다.


4. 실전 예시: 한국어 폰트 편 (본고딕 / Noto Sans KR)

한국어 폰트는 영문 폰트와 다르게 화려한 꼬리(@swash) 같은 것보다는, 대체 글꼴(@styleset 또는 @character-variant)이나 주석(@annotation) 기능이 들어있는 경우가 많습니다.

예를 들어, Noto Sans KR (본고딕) 폰트에서 숫자 '0'에 빗금을 그어서 알파벳 'O'와 구분하게 해주는 기능(ss04)이 있고, 괄호 (1)을 동그라미 기호 로 바꿔주는 주석 기능(nalt 1번)이 있다고 가정해 볼게요.

CSS로 별명 짓기

/* 1. Noto Sans KR 폰트에 대한 별명을 정의합니다 */
@font-feature-values "Noto Sans KR" {
  
  /* 0에 빗금 치는 스타일에 'slashed-zero'라는 별명을 붙입니다 (내부 코드는 4번) */
  @styleset {
    slashed-zero: 4; 
  }

  /* 동그라미 숫자 기능에 'circle-num'이라는 별명을 붙입니다 (내부 코드는 1번) */
  @annotation {
    circle-num: 1;
  }
}

/* 2. 적용하기 */
.korean-code {
  font-family: "Noto Sans KR", sans-serif;
  /* 숫자 0을 빗금 친 0으로 보여줌 */
  font-variant-alternates: styleset(slashed-zero); 
}

.korean-list {
  font-family: "Noto Sans KR", sans-serif;
  /* 목록의 (1), (2) 등을 ①, ② 로 렌더링함 */
  font-variant-alternates: annotation(circle-num); 
}

5. 이 규칙이 진짜 강력한 이유 (끝판왕 활용법)

자, 이제 이 기능이 왜 '시니어급' 지식인지 보여드릴게요.
우리가 웹사이트를 만들 때 영어는 'EB Garamond'로, 한국어는 'Noto Sans KR'로 나오게 폰트를 섞어서 쓰잖아요?

그런데 기획자가 "숫자는 무조건 각 폰트에 맞는 특수 스타일(고전 숫자 or 빗금 친 0)로 예쁘게 나오게 해주세요!"라고 요청했다고 칩시다.

과거 방식(font-feature-settings)을 쓰면 영어가 나올지 한국어가 나올지 몰라서 코드가 엄청나게 꼬입니다. 하지만 @font-feature-values를 쓰면 마법처럼 해결됩니다.

CSS

/* 1. 영문 폰트 세팅: 1번 스타일을 'pretty-numbers'로 지정 */
@font-feature-values "EB Garamond" {
  @styleset {
    pretty-numbers: 1; /* EB Garamond의 1번은 고전적 숫자 */
  }
}

/* 2. 국문 폰트 세팅: 4번 스타일을 똑같이 'pretty-numbers'로 지정 */
@font-feature-values "Noto Sans KR" {
  @styleset {
    pretty-numbers: 4; /* Noto Sans KR의 4번은 빗금 친 숫자 0 */
  }
}

/* 3. 공통 클래스 생성 */
.special-text {
  /* 영어는 가라몬드, 한글은 노토산스가 먹힘 */
  font-family: "EB Garamond", "Noto Sans KR", sans-serif;
  
  /* 폰트가 뭐든 상관없이 'pretty-numbers' 별명을 실행해라! */
  font-variant-alternates: styleset(pretty-numbers);
}

HTML

<p class="special-text">Since 1990</p> 
<p class="special-text">비밀번호 0000</p> 

어떤가요? 소름 돋지 않나요?
우리는 .special-textstyleset(pretty-numbers)라는 공통 별명만 불러왔을 뿐입니다. 브라우저가 글자를 보고 알아서 영문 폰트일 때는 1번 옵션을 켜고, 한글 폰트일 때는 4번 옵션을 켜주는 겁니다. 이게 바로 @font-feature-values가 존재하는 진짜 이유입니다!

profile
프론트에_가까운_풀스택_개발자

0개의 댓글