스타일이 없는 UI 라이브러리가 있다?!

안녕하세요, 소플입니다.
바로 이전 글인 UI 컴포넌트 라이브러리로 생산성 높이기에서는 UI 컴포넌트 라이브러리에 대해 소개했습니다.
UI 컴포넌트 라이브러리는 곧바로 사용할 수 있는 형태의 UI 컴포넌트들을 모아놓은 것이었죠.
그리고 리액트 생태계에서 대표적인 UI 컴포넌트 라이브러리로는 아래와 같은 것들이 있었습니다.

이러한 UI 컴포넌트 라이브러리들이 유용하긴 하지만, 이미 각자만의 스타일이 입혀져 있기 때문에 내가 실제로 개발하려고 하는 컴포넌트와 디자인이 다른 경우가 많습니다.

회사에서 UI/UX 디자이너가 만든 디자인은 어떤 디자인 시스템을 기반으로 하기 보다는, 디자이너 각자의 디자인 철학과 스타일에 따라 만들어지는 경우가 많기 때문이죠. 물론 규모가 있는 회사는 자체 디자인 시스템이 있기 때문에 제외하고요.

이런 상황을 극복하기 위한 한 가지 방법으로 UI 컴포넌트 라이브러리의 테마를 커스터마이징해서 사용할 수도 있지만, 완벽하게 내가 원하는 스타일의 컴포넌트를 만드는 과정이 꽤 번거로울 수 있습니다.

그래서 등장하게 된 것이 바로 스타일이 없는 UI 컴포넌트 라이브러리 입니다.
이러한 형태의 UI 라이브러리들은 말 그대로 스타일이 없고 뼈대만 있는 UI 컴포넌트 모음집이라고 할 수 있습니다.
그럼 여기에 해당하는 대표적인 UI 컴포넌트 라이브러리들에 대해서 한 번 살펴볼까요?

Headless UI

스타일이 없는 대표적인 UI 컴포넌트 라이브러리로 Headless UI가 있습니다.
Headless UI는 스타일이 입혀지지 않은 형태의 다양한 UI 컴포넌트들을 제공하는 라이브러리입니다.

Headless UI는 대표적인 스타일링 라이브러리 중 하나인 Tailwind CSS와 함께 사용할 수 있도록 개발되었습니다.
참고로 Headless UI와 Tailwind CSS 모두 Tailwind Labs에서 개발한 라이브러리입니다.
같은 패밀리 제품군(?)이라고 할 수 있는 것이죠.

Headless UI
🔗 Headless UI

위 화면은 Headless UI의 공식 홈페이지 화면을 나타낸 것입니다.
다른 UI 라이브러리와 비교했을 때 컴포넌트의 종류가 그리 많지는 않은 것을 볼 수 있습니다.
하지만 스타일링을 위해서 Tailwind CSS를 주로 사용하는 분들이라면 한 번쯤 사용해보기 좋은 라이브러리라고 생각합니다.

아래 코드는 Headless UI의 Switch컴포넌트를 사용하는 예시 코드입니다.

import { useState } from 'react';
import { Switch } from '@headlessui/react';

function MySwitch() {
    const [isChecked, setIsChecked] = useState(false);

    return (
        <Switch
            checked={isChecked}
            onChange={setIsChecked}
            className={`${
                isChecked ? 'bg-blue-600' : 'bg-gray-200'
            } relative inline-flex h-6 w-11 items-center rounded-full`}>
            <span className='sr-only'>Toggle switch</span>
            <span
                className={`${
                    isChecked ? 'translate-x-6' : 'translate-x-1'
                } inline-block h-4 w-4 transform rounded-full bg-white transition`}
            />
        </Switch>
    );
}

export default MySwitch;

이런 식으로 뼈대에 나만의 스타일을 입혀서 사용할 수 있다고 보면 됩니다.

Radix UI

다음으로 소개할 스타일이 없는 UI 컴포넌트 라이브러리로는 Radix UI가 있습니다.
엄밀히 말하면 Radix UI의 Primitives라는 패키지가 스타일이 없는 UI 컴포넌트 라이브러리입니다.

Radix UI는 스스로를 아래와 같이 정의하고 있습니다.

"Core building blocks for your design system"

해석해보면, "나만의 디자인 시스템을 만들기 위한 핵심 빌딩 블록"이라고 할 수 있겠네요.
Radix UI도 스타일이 입혀져있지 않은 다양한 UI 컴포넌트들을 제공합니다.

Radix UI Primitives
🔗 Radix UI Primitives

위 화면은 Radix UI Primitives의 공식 홈페이지 화면을 나타낸 것입니다.

Radix UI는 Headless UI에 비해서 훨씬 더 많은 UI 컴포넌트들을 제공합니다.
웹애플리케이션을 개발하는데 필요한 대부분의 컴포넌트는 다 있다고 봐도 무방합니다.
그렇기 때문에 개인적으로는 Headless UI보다는 더 다양한 컴포넌트들을 제공하는 Radix UI를 선호하긴 합니다.

아래 코드는 Radix UI의 Switch컴포넌트를 사용하는 예시 코드입니다.

import React from 'react';
import * as Switch from '@radix-ui/react-switch';
import './styles.css';

function MySwitch() {
    return (
        <Switch.Root className='SwitchRoot'>
            <Switch.Thumb className='SwitchThumb' />
        </Switch.Root>
    );
}

export default MySwitch;

이런 식으로 별도의 CSS코드나 스타일링 라이브러리를 사용해서 컴포넌트에 스타일을 입혀서 사용하면 됩니다.

웹 접근성 (WAI-ARIA)

그렇다면 스타일이 없는 UI 컴포넌트 라이브러리를 사용하는 이유가 뭘까요?
내가 직접 컴포넌트의 뼈대를 만들고 스타일도 입혀서 사용해도 되는데 말이죠.

스타일이 없는 UI 컴포넌트 라이브러리를 사용하는 대표적인 이유는 바로 웹 접근성 표준을 지키기 위함입니다.
여기서 웹 접근성은 모든 사람들이 웹사이트나 앱을 사용할 수 있도록 보장하는 원칙과 가이드라인이라고 할 수 있습니다.

웹 접근성을 잘 지키는 것이 중요한 이유는 여러가지가 있지만, 대표적으로 장애가 있는 사람들이나 IT기술에 친숙하지 않은 사람들도 웹사이트를 평등하게 이용할 수 있는 기회를 제공하기 위함이라고 할 수 있습니다.
그리고 웹 접근성을 법적으로 요구하는 국가들도 많으며, 검색 엔진 최적화(Search Engine Optimization, SEO) 측면에서도 중요한 부분이라고 할 수 있습니다.

평소에 웹사이트를 개발하다보면 한 번씩 WAI-ARIA라는 것을 들어보셨을 겁니다.
여기서 WAIWeb Accessibility Initiative의 약자로 웹 접근성에 대한 표준을 만드는 기관이라고 보면 됩니다.
그리고 ARIAAccessible Rich Internet Applications의 약자로, 장애를 가진 사용자가 웹 콘텐츠에 더 쉽게 접근할 수 있는 방법을 정의하는 여러가지 특성을 말합니다.
웹사이트를 개발하다 보면 aria-로 시작하는 속성을 본적이 있을텐데, 그게 바로 웹 접근성을 위한 속성이라고 보면 됩니다.

이러한 웹접근성을 개발자가 하나하나 다 지키면서 개발하기란 쉽지 않습니다.
그래서 앞에서 소개한 Headless UI나 Radix UI 같은 라이브러리를 사용해서, 웹 접근성을 준수하는 컴포넌트를 만들어서 사용하는 것입니다.
우리는 여기에 원하는대로 스타일만 입혀서 사용하면 되는 것이죠.

지금까지 스타일이 없는 UI 컴포넌트 라이브러리들과 웹 접근성에 대해 알아보았습니다.
독자분들도 다음 프로젝트에서는 이러한 UI 라이브러리를 한 번 사용해보기 바랍니다.
저는 다음에 또 유익한 글로 찾아뵙겠습니다!
지금까지 소플이었습니다. 감사합니다😀

지금 가입하고 새로운 매거진을 이메일로 받아보세요!

Copyright ⓒ Soaple. All rights reserved.