[React] 리빙 포인트: Css in JS로는 font-face를 유니코드 별로 다르게 넣을 수 없다.

2022. 9. 6. 20:41React/고민거리들

안녕하세요!

프로젝트를 세팅하다보면 이런 요구 사항을 받는 경우가 종종 있습니다.

 

한글은 Noto Sans KR로, 영어는 Arial로 가능한가요?

 

 

1. @font-face의 기본

 

당연히 가능하죠!

css에서는 @font-face라는 문법을 지원한답니다.

 

@font-face {
    font-family: Noto Sans KR;
    font-style: normal;
    font-weight: normal;
    // 여기에서 url로 지정해주면 됩니다.
    src: url("YOUR_FONT_PATHS");
}

 

기본적으로 이 스타일을 font-family로 지정해주고, style(Italic, oblique 등), weight(bold, bolder 등)도 지정해줄 수 있습니다. 만약 요청사항 처럼 다른 유니코드로 지정해준다면 이렇게 해주면 됩니다.

 

@font-face {
    font-family: Noto Sans KR;
    font-style: normal;
    font-weight: normal;
    src: url("YOUR_FONT_PATHS");
    
    // for korean;
    unicode-range: U+AC00-D7A3;
    
    // for ENGLISH(UPPERCASE), english(lowercase), number
    unicode-range: U+0041-005A, U+0061-007A, U+0030-0039;
}

 

영문 대문자 => U+0041-005A
영문 소문자 => U+0061-007A
숫자 => U+0030-0039
한글 => U+AC00-D7A3

 

이렇게 넣어주면 됩니다. Noto Sans KR은 Google Fonts에서 받으면 용량이 무려 4.5MB 정도 되네요 ....!

클라이언트에게 극한의 이득을 주기 위해 woff, woff2 설정까지 해줍시다. (이러면 각 용량이 300KB 정도로 줄어들어요.)

 

 

예시) 한글 Bold로 Noto Sans KR을 쓰는 경우

@font-face {
    font-family: Noto Sans KR;
    font-style: normal;
    font-weight: bold;
    src: url("./assets/fonts/NotoSansKR-Bold.otf")format("opentype"),
    url("./assets/fonts/NotoSansKR-Bold.woff")format("woff"),
    url("./assets/fonts/NotoSansKR-Bold.woff2")format("woff2");
    unicode-range: U+AC00-D7A3;
}

 

 

2. CSS in JS에서 적용..?(@emotion/styled)

 

자..! 그러면 이걸 이제 어디에 선언 해주느냐가 중요할텐데요..

보통 root에 넣어줍니다.

 

전 css 라이브러리로 styled-component를 선호합니다. (사실 @emotion/styled 지만..)

@emotion/styled는 styled-component와는 다르게 코드 자동완성이 자동으로 됩니다. styled-component는 매번 css 리터럴을 넣어줘야 자동완성이 되거든요. 

 

그러면 제가 저번에 선언해놨던 GlobalStyle.tsx에 한 번 넣어볼까요?

(하지마세요. 안됩니다. 작은 버그가 아닐까 싶은데, unicode-range가 되지 않더라구요.)

 

import React from 'react';
import { Global, css } from "@emotion/react";

const style = css`
  *, *::before, *::after {
    box-sizing: border-box;
  }
  :root {
    --black: #12101D;
    --white: #FFFFFF;
    --primary: #B672FD;
    --secondary: #E7266C;
    --highlight: #E2FAFF;
    
    --desktop-content: 1083px;
    
    @font-face {
    font-family: Noto Sans KR;
    font-style: normal;
    font-weight: bold;
    src: url("./assets/fonts/NotoSansKR-Bold.otf")format("opentype"),
    url("./assets/fonts/NotoSansKR-Bold.woff")format("woff"),
    url("./assets/fonts/NotoSansKR-Bold.woff2")format("woff2");
    unicode-range: U+AC00-D7A3;
}

@font-face {
    font-family: Noto Sans KR;
    font-style: normal;
    font-weight: bold;
    src: url("./assets/fonts/Arial-Bold.otf")format("opentype"),
    url("./assets/fonts/Arial-Bold.woff")format("woff"),
    url("./assets/fonts/Arial-Bold.woff2")format("woff2");
    unicode-range: U+0041-005A, U+0061-007A, U+0030-0039;
}
  }
`;

const GlobalStyle = () => {
  return <Global styles={style} />
};

export default GlobalStyle;

 

위에 미리 스포했듯이,

제대로 된 코드가 들어가지 않는 걸 확인할 수 있습니다. 어떻게 해결할 수 있을까요?

 

사실 별거 없습니다. App.css에 그냥 넣어주면 되어요..!

 

App.css

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@font-face {
    font-family: Noto Sans KR;
    font-style: normal;
    font-weight: bold;
    src: url("./assets/fonts/NotoSansKR-Bold.otf")format("opentype"),
    url("./assets/fonts/NotoSansKR-Bold.woff")format("woff"),
    url("./assets/fonts/NotoSansKR-Bold.woff2")format("woff2");
    unicode-range: U+AC00-D7A3;
}

@font-face {
    font-family: Noto Sans KR;
    font-style: normal;
    font-weight: bold;
    src: url("./assets/fonts/Arial-Bold.otf")format("opentype"),
    url("./assets/fonts/Arial-Bold.woff")format("woff"),
    url("./assets/fonts/Arial-Bold.woff2")format("woff2");
    unicode-range: U+0041-005A, U+0061-007A, U+0030-0039;
}

 

자 잘 되나 볼까요?

 

Noto Sans KR인데 폰트가 상당히 힙하네요..!

 

Arial은 아니지만 힙한 폰트로 설정할 수 있었습니다.

 

꼭 여러분들은 저처럼 unicode-range를 의심하지 말고, CSS in JS를 의심하세요..!

(저는 유니코드 표 30분동안 보고 있었어요ㅠㅠ)

 

그럼 이만!