LY Corporation Tech Blog

LY Corporation과 LY Corporation Group(LINE Plus, LINE Taiwan and LINE Vietnam)의 기술과 개발 문화를 알립니다.

3단계로 완성하는 유연한 디자인 시스템

안녕하세요. LINE Plus ABC Studio에서 일본 음식 배달 서비스 Demaecan(出前館, 이하 데마에칸)의 디자인을 담당하고 있고, 사용자의 다양한 목소리를 담을 수 있는 ABC User Feedback도 함께 만들고 있는 오관식입니다. 이번 글에서는 디자이너와 웹 프런트엔드 엔지니어 간의 디자인 리소스 관리를 일원화하기 위해 디자인 시스템을 만들어서 코드에까지 연결한 작업을 소개하고, 그 결과물을 ABC User Feedback에서 어떻게 활용하고 있는지 말씀드리고자 합니다.

ABC User Feedback 프로덕트의 일반적인 소개는 앞서 발행된 사용자의 피드백을 잘 관리하고 활용하기 위한 서비스, ABC User Feedback을 참고하시기 바랍니다.

이 글이 특히 규모가 작은 조직이나 MVP(minimum viable product)를 빠르게 검증해야 하는 프로덕트 메이커 분들에게 도움이 되길 바라며 시작하겠습니다.

디자인 시스템의 정의와 도입하기 어려운 이유

디자인 시스템은 디자인 원칙과 규격, 재사용 가능한 UI 패턴과 컴포넌트, 코드 등을 전체적으로 포괄하는 집합체를 말합니다. 조직의 운영 스타일이나 방향에 따라 다르게 적용될 수 있어서 단순히 스타일 가이드나 패턴 라이브러리로서의 역할만 담당할 수도 있습니다.

디자인 시스템의 주 목적은 제품을 만들 때 디자인 관점에서의 표준 규칙을 설정해 작업을 보다 효율적이고 일관적으로 수행할 수 있도록 지원하는 것입니다. 이를 통해 보다 쉽고 빠르게 프로젝트를 확장할 수 있으며 각 조직의 목표에 맞게 제품 디자인을 쉽게 조정할 수 있습니다.

그동안 디자이너의 관점에서 현실적으로 디자인 시스템을 도입하기 어려웠던 이유는 아래와 같습니다.

  • 개발과의 단절: 개발 팀이 여럿인 경우 디자인 관점에서는 통일할 수 있지만 각 팀의 코드는 달라서 디자인 시스템을 도입해도 전체 효율은 그다지 올라가지 않는 경우가 있습니다.
  • 초기 설정의 어려움: 프로덕트의 방향이나 목적에 따라 필요한 사양이 달라지기 때문에 디자인 시스템 구축 시 기본 컴포넌트의 범위를 어디까지 정해야 할지 어렵습니다.
  • 유지 보수: 디자인 시스템에 너무 많은 컴포넌트를 포함할 경우 갱신이나 수정 시 많은 리소스가 필요합니다.

이번 글에서는 위 문제 중 '개발과의 단절'과 '유지 보수' 관점에서의 어려움을 어떻게 해결했는지 살펴보고, 그 결과물인 3단계 디자인 시스템과 적용 사례를 소개하겠습니다.

(디자이너 한 명과 웹 개발자 두 명으로 가능한) 디자인 시스템 개발 방향 설정 

디자인 시스템은 장점이 충분한 시스템이지만 리소스는 늘 한정돼 있기에 디자인 시스템 구축에는 항상 어려움이 따릅니다. 제 경우 두 명의 프런트엔드 엔지니어와 한 명의 디자이너라는 최소한의 리소스만 활용할 수 있었는데요. 이 정도의 리소스로 디자인 시스템을 만든다면 어떤 방향으로 제작하면 좋을지 고민했고, 논의 결과 최소한의 핵심 컴포넌트 위주로 빠르게 검증할 수 있는 디자인 시스템을 만들자는 결론이 나왔습니다. 

Figma, Storybook과 이 둘을 연계하는 토큰으로 구축하는 디자인 시스템

저희는 디자인부터 개발에 이르기까지 리소스를 일관적으로 관리할 수 있도록 FigmaStorybook을 도입한 뒤 이 둘을 연계하기 위한 토큰을 설계했습니다.

여기서 토큰이란 디자인의 핵심 스타일 속성을 추상화해 코드로 표현한 기본 단위를 말합니다. 이 토큰을 이용해 컴포넌트의 색상과 글꼴 크기, 여백, 그림자와 같은 디자인 속성을 통일하고 일관적으로 관리할 수 있습니다(디자인 토큰에 대한 더 자세한 설명은 이곳을 참고하세요). 

토큰은 디자인의 다양한 구성 요소를 결정하는 역할을 합니다. 토큰을 사용하면 아래와 같은 장점을 얻을 수 있습니다.

  • 일관성 확보: 모든 디자인 요소에서 동일한 토큰을 사용함으로써 디자인의 일관성을 효율적으로 유지할 수 있습니다.
  • 유지 보수 용이: 토큰을 변경하면 해당 토큰이 사용된 모든 디자인 요소에 반영되므로 디자인 업데이트가 용이합니다.
  • 재사용성 증가: 토큰은 여러 프로젝트나 제품에서 재사용할 수 있으며 이를 통해 작업 효율을 높일 수 있고 브랜드의 일관성을 유지하는 데 도움이 됩니다.

디자인 시스템의 산출물은 HeadlessUI로

이번 디자인 시스템은 저희 팀에서 개발하고 있는 사용자 의견 수집 도구인 ABC User Feedback에 적용하는 것이 목표였기에 ABC User Feedback에서 사용하는 프런트엔드 기술인 ReactTailwind CSS를 적용 대상으로 삼았으며, Tailwind CSS의 뼈대라고 할 수 있는 HeadlessUI를 디자인 시스템의 산출물로 사용하기로 결정했습니다.

HeadlessUI는 Tailwind CSS에서 디자인 없이 기능만 제공해 주는 JavaScript 라이브러리입니다. 대부분의 외부 UI 라이브러리는 자신들의 디자인이 적용돼 있어서 사용자의 요구에 맞게 디자인이나 기능을 수정하기 어려운데요. 이와 비교해 HeadlessUI는 아래와 같은 세 가지 장점이 있습니다.

  • 디자인 시스템과의 통합: HeadlessUI는 스타일이 없기 때문에 기존의 디자인 시스템과 쉽게 통합할 수 있습니다.
  • 커스터마이징 용이: 개발자는 UI의 기능을 그대로 유지한 채 스타일을 완전히 커스터마이징할 수 있습니다.
  • 경량화: 스타일이 포함돼 있지 않기 때문에 컴포넌트가 경량화돼 있습니다.

HeadlessUI는 디자인 요소는 없지만 인터랙션과 상태값은 갖고 있습니다. 이를 통해 컴포넌트 제작 시 검토와 리뷰 과정을 최소화할 수 있습니다.

아래 그림은 UI 라이브러리와 HeadlessUI, 커스텀 CSS를 기술 지원과 커스터마이징 측면에서 비교한 그래프입니다. 기술 지원 그래프의 세로축은 사전에 코드로 구현돼 있는 정도를 의미하고, 커스터마이징 그래프의 세로축은 커스터마이징 난이도와 가능 영역을 의미합니다. 

위와 같이 HeadlessUI는 커스터마이징 측면에서는 Ant Design과 같은 UI 라이브러리보다 유리하고, 기술 지원 측면에서 커스텀 CSS보다 작업량이 적은 것이 장점입니다. 예를 들면 <select> 컴포넌트의 드롭다운 메뉴 열기/닫기의 상태값이나 <button> 컴포넌트의 호버 시 전환 인터랙션 등의 기본적인 컴포넌트 요소들은 기본적인 코드가 제공됩니다.

유연하게 커스터마이징할 수 있는 3단계 토큰 구조 도입

토큰은 토큰을 어떤 구조로 설계하느냐에 따라 다양하게 활용할 수 있습니다. 기본적으로 2단계 또는 3단계 구조로 설계할 수 있는데요. 2단계 구조는 디자인 가이드라인을 타이트하게 설정해 일관성을 유지하는데 유리하고, 3단계 구조는 다양한 스타일을 적용하기에 유리합니다. 저희는 토큰의 장점을 최대한 활용하기 위해 3단계 구조를 선택했습니다.

3단계 토큰 구조 소개

Primitive 토큰은 기본 단위의 토큰입니다. Semantic 토큰은 뒤에 등장할 Component-specific 토큰과 비교해 디자이너가 상황에 맞게 보다 자유롭게 이곳저곳에 사용할 수 있는 토큰으로 기본적인 화면을 구성하는 데 사용할 수 있습니다. Component-specific 토큰은 명칭 그대로 컴포넌트 구조를 세분화해 적용할 수 있는 토큰으로 각 토큰마다 사용 범위가 제한돼 있습니다(참고). 저희가 설계한 각 토큰 구성 기준은 아래와 같습니다.

  • Primitive 토큰
    • 색상값이나 크기값 등의 기본값을 갖는 가장 기본적인 토큰으로 3단계 토큰 구조의 첫 번째 계층입니다.
    • '색상(혹은 크기)-위계'의 구조입니다(예: zinc-100, radius-200).
  • Semantic 토큰
    • Primitive 토큰을 값으로 갖는 두 번째 계층으로, 화면에서 Component-specific 토큰이 적용된 부분을 제외한 모든 요소에 위계에 맞는 토큰을 사용합니다.
    • '컴포넌트 구조-위계'의 구조입니다(예: text-neutral-primary, fg-neutral-primary).
  • Component-specific 토큰
    • Semantic 토큰 또는 Primitive 토큰을 값으로 갖는 세 번째 계층으로 가장 구체적으로 사용처가 정해지는 계층입니다.
    • '컴포넌트 명칭-위계-컴포넌트 구조-상태값'의 구조입니다(예: button-primary-text-default).

아래 그림은 'Button' 토큰의 예시입니다. Primitive 토큰에서 색상(color)과 곡률(radius) 값을 정의하고, 이를 바탕으로 Semantic 토큰을 설정한 뒤 Component-specific 토큰 계층에 적용합니다.

토큰을 만들 때에는 토큰이 컴포넌트의 어떤 구성 요소를 가리키는지 명확히 알 수 있도록 이름을 짓는 것이 중요합니다. 그래야 소통할 때 혼란을 줄여 소통 효율을 높일 수 있습니다. 이에 저희는 Semantic과 Component-specific 토큰을 만들 때 아래 네 가지 요소(토큰 카테고리)를 사용해 이름을 짓도록 규칙을 정했습니다. 모든 컴포넌트는 기본적으로 아래 네 가지 요소로 구성되며, 각 컴포넌트마다 요소를 추가하거나 제외할 수 있습니다. 

  • Text: 컴포넌트의 글자
  • Icon: 컴포넌트의 아이콘
  • Border: 컴포넌트의 외곽선
  • Fg(foreground): 컴포넌트의 면(面)

이를 통해 개발자와 디자이너, 각 담당자들과 보다 빠르고 효율적으로 커뮤니케이션할 수 있습니다(참고로 현재 토큰 명명 규칙을 확인할 수 있는 토큰 비주얼라이저(token visualizer)도 개발하고 있습니다).

3단계 토큰 구조에서 토큰을 이용해 커스터마이징하는 방법

다른 테마로 전환하려면 변경을 원하는 Semantic 토큰에 다른 Prmitive 토큰을 적용하면 됩니다. 예를 들어 <button> 컴포넌트의 스타일을 변경하고자 한다면, 아래와 같이 Semantic 토큰에 다른 Primitive 토큰을 사용해 fg(foreground)와 radius 값을 변경합니다.

Figma에서 3단계 토큰 구조 활용하기

Figma의 Variables 기능을 사용하면 위와 같은 토큰 구조를 디자인에서 동일하게 구현할 수 있습니다(Figma의 Variables의 기능과 사용 방법은 공식 문서를 참고하세요). 저희는 아래와 같이 Variables의 Collection 기능을 이용해 토큰과 동일한 3단계 구조(Primitive, Semantic, Component)를 제작했습니다(Component-specific은 길이 문제로 Component로 표현).

또한 Collection에서 Mode 기능을 사용해 Semantic에는 디스플레이 모드(Light, Dark)를 적용하고, Component에는 다양한 스타일의 컬러(Neutral, Blue, Green, Orange)를 적용했습니다. 여기에 테두리의 곡률(radius)을 자유롭게 변경할 수 있도록 Radius Collection을 추가하고  Small, Medium, Large라는 Mode를 추가했습니다(참고로, 개념적으로 Radius는 Component Collection에 포함해야 하나, 현재 Figma에서 Mode를 변경하려면 별도 Collection으로 정의해야 수정이 가능합니다. 이런 배경을 고려해 개발 팀과 별도 협의를 거쳐 Figma에서만 분리하는 것으로 결정했습니다).

여기까지만 적용해도 아래 그림처럼 Figma에서 원하는 테마로 손쉽게 변경할 수 있습니다. Variables를 통한 토큰 설정이 완료되면 Appearance 기능을 통해 원하는 스타일로 컴포넌트 일부 혹은 전체를 변경할 수 있습니다. 이 글을 쓰는 시점을 기준으로 Semantic의 두 가지 Mode와 Component의 네 가지 Mode, Radius의 세 가지 Mode를 조합해 총 24개의 테마를 자유롭게 넘나들 수 있습니다. 

Figma의 Variables에서 코드까지 연결하기

이 모든 과정은 결국 개발까지 연결돼야 진정으로 효율을 높일 수 있기에 디자인 영역에서의 표현 방식(Figma의 Variables)과 개발에서의 표현 방식(코드에서 토큰 표현 방식)을 모두 다음 예시와 같이 동일한 토큰 구조로 정리했습니다. 

  • Figma Variables의 토큰: button/primary/text/default
  • 코드에서의 토큰: --button-primary-text-default

아래 그림 왼쪽은 Figma의 Variables이고, 오른쪽은 코드에서 토큰을 표현한 것입니다. Figma는 '/'로, 코드에서는 '-'로 위계를 구분한다는 것 외에 토큰의 구조는 동일합니다.

3단계 토큰 구조의 디자인 시스템을 활용해 더 효율적으로 일하는 방법

이제 앞서 소개한 3단계 토큰 구조의 디자인 시스템을 활용해 더 효율적으로 일할 수 있는 몇 가지 방법을 소개하겠습니다.

디자인과 개발의 프로퍼티명 통일

컴포넌트의 프로퍼티 구성 및 명칭을 통일하면 개발자와 디자이너가 같은 단어를 사용해 더 효율적으로 커뮤니케이션할 수 있습니다. 디자인에서 정리된 내용은 Figma에서, 개발에서 정리된 내용은 Storybook에서 확인할 수 있기 때문에 명칭을 통일해 각각에 정리해 놓으면 불필요한 커뮤니케이션을 줄이고 더욱 원활히 협업하며 개발 주기를 단축할 수 있습니다. Storybook과 관련해서는 이 프로젝트에 함께 참여하신 개발자분들이 향후 다른 글로 상세히 공유해 주실 예정이니 많은 기대 바랍니다. 

아래 그림에서 보듯 현재 저희 디자인 시스템에서 Figma와 Storybook의 프로퍼티가 완벽히 일치하지는 않습니다. 이상적으로는 100% 일치하는 게 좋다고 생각합니다. 

컴포넌트의 상태값 최소화

컴포넌트에는 다양한 상태값이 있기 때문에 관리해야 할 토큰의 개수가 많아집니다. 저희는 이를 간소화 하기 위해 Hover와 Disabled 상태를 공통 규칙으로 도출해 Hover는 'opacity-80' 토큰 적용, Disabled는 'opacity-50' 토큰을 적용했습니다. 이를 통해 <button> 컴포넌트에서 사용하는 색상 관련 토큰의 수를 6개에서 2개로 기존 대비 67% 줄일 수 있었습니다.

Mode를 추가해 나만의 테마 만들기

앞서 살펴봤듯 Figma Variables의 Component Collection은 네 가지(Neutral, Blue, Green, Orange), Radius Collection은 세 가지(Small, Medium, Large) Mode를 갖고 있는데요. 이 글에서 제시하는 Collection 구조는 하나의 예시입니다. Mode에 설정된 토큰을 수정하거나 추가해 여러분이 원하는 테마를 만들 수 있습니다. 예를 들어 만약 새로운 컬러의 테마를 원하면 아래 그림과 같이 Mode를 추가하면 됩니다. 또한 새로운 곡률 값을 적용하고 싶다면 Radius Collection에 Mode를 추가하면 됩니다.

프로덕트 적용 사례

디자인 시스템이 제공하는 일관성과 유연성을 활용하면 프로덕트 메이커는 스타일이나 구조에 대한 고민을 덜 수 있습니다. 실제로 ABC User Feedback의 경우 디자인 시스템을 사용해 다양한 테마를 테스트해 보며 브랜드에 맞는 UI를 신속하게 구축할 수 있었습니다. 모듈화된 구조를 갖춘 디자인 시스템 덕분에 버튼이나 카드, 모달 등 다양한 UI 컴포넌트의 토큰 값을 변경하며 그 결과를 즉시 확인할 수 있었고, 이를 통해 시간을 대폭 절약할 수 있었으며, 결과적으로 보다 더 중요한 사용자 요구와 문제 해결에 집중할 수 있었습니다. 이는 단지 시간을 절약한 것 이상의 가치가 있다고 생각합니다.

아래는 디자인 시스템을 적용해 개발하고 있는 ABC User Feedback의 프로덕트 화면입니다.

이번에 사용자 경험을 개선하는 작업을 진행하면서 디자인 시스템을 사용했는데요. 전체 페이지의 80% 이상의 커버리지(Figma 파일에서 디자인 시스템을 통해 사용된 컴포넌트 비율)를 달성했습니다.

아래 그림은 디자인 시스템의 컴포넌트 커버리지 분석 화면입니다. 'Total instances'(Figma 파일에서 디자인 시스템을 통해 사용된 컴포넌트 총량) 지표와 'Inserts'(컴포넌트가 사용된 횟수) 지표를 통해 컴포넌트 적용 내역을 확인할 수 있습니다. Inserts 지표 옆 'Detaches' 지표는 디자인 시스템에서 제공하는 원본 컴포넌트를 활용하지 못하고 분리(detach)된 컴포넌트를 의미하는데요. 분리된 컴포넌트 없이 프로덕트에 잘 활용되고 있다는 것을 확인할 수 있습니다.

마치며

저희는 이번 글에서 소개한 디자인 시스템에 'Def(Definitely Elements Foundation)'라는 이름을 붙이고, 더욱 다양한 프로덕트가 Def를 이용해 서로 효율적으로 협력하고 더 나은 사용자 경험을 제공할 수 있도록 오픈소스로 공개하기 위해 준비하고 있습니다. 

앞으로 Def가 제공하는 기본적인 필수 컴포넌트를 이용해 더욱 효율적으로 프로덕트를 개발할 수 있도록 꾸준히 개선해 나갈 예정입니다. 추후 저희가 공개한 오픈소스를 통해 더욱 많은 사람이 보다 쉽게 문제를 해결하며 더욱 창의적인 제품을 만들 수 있기를 바라며 이만 마치겠습니다. 읽어주셔서 감사합니다.