Home

Presentation

결과물만으로는 보이지 않는 작업 의도를 전달합니다. 무엇이 문제였고, 어떻게 바꿨고, 그래서 무엇이 좋아졌는지를 하나의 판단 단위로 묶어 기록합니다.

  1. 삭제처럼 되돌릴 수 없는 액션은 Button 색으로 구분해요

    색과 스타일이 서로 맞물려 있던 Button

    예전에는 어떤 색을 쓸 수 있는지가 스타일에 따라 갈렸어요. 삭제에 쓰는 붉은 색은 outline에만 있어서, 삭제가 화면에서 가장 중요한 액션으로 서야 할 때는 채워진 brand 버튼을 그대로 썼어요. 엑셀로 내려받는 버튼처럼 색이 이미 정해진 자리도 컴포넌트 밖에서 색을 넣고 있었어요.

    뜻은 색으로, 강조는 스타일로 따로 정하기

    Button은 어떤 액션인지를 색으로, 얼마나 강조할지를 스타일로 따로 정해요. danger가 스타일과 따로 정해지기 때문에, 삭제는 채워진 버튼으로 가장 앞에 서도 붉은 색을 그대로 써요. 엑셀처럼 이미 굳어진 색은 custom 아래에 들여 컴포넌트가 관리하고, 다른 외부 서비스 색이 필요해지면 여기에 더해요.

  2. 색이 아니라 뜻으로 Badge를 골라요

    색과 스타일로만 구분되던 Badge

    Badge는 정보를 표시하는 자리였지만 구분 기준은 색과 스타일뿐이었어요. 어떤 뜻에 어떤 색을 쓸지는 화면마다 다시 판단해야 했고, 같은 뜻이 화면마다 다른 색으로 보이기도 했어요. 색을 고르는 일이 매번 새로 생겨서, 뜻이 같다는 것을 화면에서 알아보기 어려웠어요.

    뜻을 이름으로 정하고, 뜻이 없는 색은 custom으로 두기

    Badge는 info, warning, success, danger처럼 뜻을 이름으로 정하고, 이름을 고르면 색이 따라오기 때문에 뜻이 있는 자리에서는 색을 고를 일이 없어요. 뜻과 관계없이 색만 필요한 경우는 custom으로 빼고, 색을 직접 고르는 것은 custom에서만 열려요. 스타일은 뜻이 아니라 놓이는 자리에 따라 고르는 축이므로 그대로 남겨 뒀어요. 색을 직접 정해야 하는 자리가 custom 하나로 드러나서, 나중에 이 자리에 뜻이 생기면 어디를 바꿔야 하는지도 바로 보여요.

  3. 붙어서 알리는 표시는 Notification Badge가 담당해요

    뜻을 고르는 자리에 담을 수 없던 알림

    Badge가 뜻으로 고르도록 정리되면서, 알림 표시는 담을 자리가 없어졌어요. 알림은 어떤 뜻인지가 아니라 무언가 생겼다는 사실을 알리고, 혼자 서지 않고 아이콘·버튼·메뉴에 붙어서 위치와 정렬이 붙는 요소에 따라 달라져요. 마침 개수 없이 있다는 것만 알리는 점 표시를 따로 추가할 예정이었는데, 그대로 두면 하는 일과 붙는 방식이 같은 컴포넌트가 둘로 나뉠 수 있었어요.

    개수와 점을 한 컴포넌트의 형태로 두기

    Notification Badge는 다른 요소에 붙어 새 소식이 있다는 것을 알리는 표시예요. 그 안에서 개수를 보여주는 형태와 점만 찍는 형태로 갈려요. 개수를 알려줘야 할 때는 개수 형태, 있다는 사실만 알려도 될 때는 점 형태를 써요. 개수가 0 이하면 아무것도 그리지 않기 때문에 화면에서 조건을 따로 걸지 않아도 돼요.

  4. Button은 Action에만 쓰도록, 상태를 나타내는 버튼은 ToggleButton으로 나눴어요

    겉모습이 같아 한 버튼으로 쓰이던 두 가지 역할

    한 번 누르면 끝나는 버튼과, 대상의 상태를 나타내는 버튼은 겉모습이 같아요. 그래서 같은 버튼을 토글로도 쓰면서 켜졌을 때의 모습을 자리마다 따로 손봤어요. 켜짐을 어떻게 보일지가 컴포넌트에 정의되어 있지 않아서 같은 켜짐이라도 화면마다 갈렸어요.

    성격에 따라 두 가지 Style로 나누기

    ToggleButton을 별도 컴포넌트로 만들고, 토글의 성격에 따라 Ghost와 Tonal 두 Style로 나눴어요. 즐겨찾기나 찜처럼 그 항목에만 상태가 남는 자리는 Ghost를 쓰고, 검색 영역을 여는 것처럼 화면이 함께 바뀌는 자리는 Tonal을 쓰도록 가이드에 적어 뒀어요. Button은 눌러서 실행하고 끝나는 Action에만 쓰면 되니까 어느 쪽을 고를지가 분명해졌어요. 크기와 여백은 두 컴포넌트가 같은 값을 쓰기 때문에 도구 모음에서 같은 줄에 놓아도 어긋나지 않아요.

  5. 따로 만들던 표시를 Chip으로 정의하고 다섯 역할로 나눴어요

    역할마다 따로 만들던 표시

    예전에는 값이나 조건을 짧게 보여 주는 표시를 역할마다 따로 만들었어요. 하나의 컴포넌트로 정의된 적이 없어서, 같은 모양이 여러 자리에 있어도 서로 다른 것으로 만들어졌어요.

    Chip으로 정의하고 다섯 역할로 나누기

    Chip을 하나의 컴포넌트로 정의하고, 쓰이는 자리를 Filter와 Selection, Suggestion, Input과 정보 표시 다섯 역할로 나눴어요. 역할마다 어떤 모양을 쓰고 눌렀을 때 무엇이 되는지, 지우기 버튼을 두는지를 정해 뒀어요. 어느 역할인지 먼저 정하면 나머지는 따라오기 때문에 자리마다 다시 판단하지 않아도 돼요.

  6. 라벨과 안내 문구를 Field가 맡아, 폼 한 칸을 한 곳에서 다뤄요

    화면마다 새로 만들던 라벨과 안내 문구

    예전에는 입력 요소만 있고, 그 위에 붙는 라벨과 아래에 붙는 도움말·오류 문구는 화면마다 새로 만들었어요. 라벨과 입력 요소를 이어서 화면 읽기 도구에 이름을 알려주는 연결도 그때마다 직접 적어야 했어요. Select처럼 이름을 속성으로 한 번 더 받는 컴포넌트에서는 같은 문구를 두 곳에 적었어요.

    폼 한 칸을 Field 하나로 묶기

    Field는 라벨과 필수 표시, 도움말과 오류 문구를 함께 가지고, 가운데에는 입력 요소가 갈아 끼워지는 자리를 둬요. Input과 Textarea, Select는 물론이고 여러 개를 고르는 묶음까지 이 자리에 그대로 들어가요. 라벨과 입력 요소를 잇는 연결은 Field가 만들기 때문에 화면에서는 따로 적지 않아요. 입력 요소는 값을 다루는 일만 맡고 자기 라벨을 갖지 않아요.

    폼을 이루는 네 층을 나눈 기준

    Field를 두면서 폼을 이루는 층에 Control, Field, Fieldset, Form이라는 이름을 붙였어요. 값을 다루는 일은 Control이, 폼 한 칸을 묶는 일은 Field가 맡아요. 여러 칸을 묶는 Fieldset과 제출·유효성 검증을 맡는 Form은 아직 만들지 않았다는 것까지 함께 적어서, 제출과 검증이 Field의 책임이 아니라는 점을 분명히 했어요.

    이름이 비슷한 CheckboxField와 RadioField, SwitchField는 Field가 아니에요. 체크박스나 라디오 옆에 라벨을 나란히 붙인 한 줄이고, 그런 줄을 여러 개 묶어 하나의 폼 항목으로 만들 때 그 바깥을 Field가 감싸요.

  7. 별도 액션 없이 비교할 수 있는 Select Box를 추가했어요

    비교할 만큼 정보를 담지 못한 선택지

    선택지마다 설명이나 가격 같은 근거가 필요한 화면에서, 예전 라디오·체크박스 형태로는 라벨 한 줄이 전부였어요. 툴팁이나 별도 영역으로 밀려나다 보니, 선택에 필요한 정보를 보려면 또 다른 액션이 필요했어요.

    컨트롤에서 박스 전체로 넓힌 선택 영역

    Select Box는 라벨 아래에 부가정보 슬롯을 두고, 박스 전체를 선택 영역으로 삼았어요. 하나만 고르는 방식과 여럿 고르는 방식을 모두 제공해서 두 가지 선택을 한 컴포넌트로 다뤄요. 정보를 담으려 박스가 커지면서 터치 영역도 자연히 넓어졌어요.

    한 화면에서 끝나는 비교와 선택

    판단 근거가 선택지 안에 있으니 정보를 확인하는 데 별도 액션이 필요 없어졌어요. 넓어진 터치 영역 덕에 모바일에서 누르기도 쉬워졌어요. 흩어져 있던 카드형 선택이 하나의 컴포넌트로 모여 패턴도 일관돼졌어요.

    이름이 비슷하지만 Select와는 다른 컴포넌트예요. Select는 평소에 접어 두었다가 눌러서 목록을 펼치고, Select Box는 선택지를 계속 펼쳐 둔 채로 비교하게 해요.

  8. 브라우저가 그리던 Select 목록을 우리가 직접 그려요

    브라우저가 정하던 목록의 생김새

    예전에는 눌러서 여는 부분만 우리가 만들고, 펼쳐지는 목록은 브라우저가 그렸어요. 같은 코드인데도 어디서 보느냐에 따라 목록이 다르게 보였고, 우리가 손댈 수 있는 부분이 아니었어요. 목록에 넣을 수 있는 것도 글자뿐이었어요.

    브라우저에서 우리 코드로 옮긴 목록

    Select의 펼쳐지는 목록을 브라우저에 맡기지 않고 직접 그려요. 항목에는 아이콘과 설명, 뱃지 같은 요소를 글자와 함께 놓을 수 있고, 선택한 값이 보이는 자리에도 같은 요소가 따라와요. 어떤 브라우저에서 열어도 같은 모양이 나오니 브라우저마다 따로 열어 확인할 일도 줄었어요.

  9. 모양만으로 선택 방식이 읽히도록, Radio를 원형으로 되돌렸어요

    Radio와 Checkbox가 같이 쓰던 아이콘

    Radio와 Checkbox는 고를 수 있는 개수가 달라요. 하나만 고르는 것인지 여럿 고르는 것인지는 누르기 전에 알아야 하고, 그 신호를 모양이 맡고 있어요. 둘 다 같은 아이콘을 쓰면 신호가 사라져요.

    사람들이 이미 학습한 형태 따르기

    Radio는 원, Checkbox는 사각형이에요. 우리가 고른 디자인이 아니라 다른 제품에서 이미 익힌 약속이에요. 이미 아는 것을 다시 배우게 만들지 않는 게 목적이라, 여기에는 우리 취향을 넣지 않았어요.

  10. 명도를 단계로 나눠 브랜드 색이 바뀌어도 대비를 지켜요

    색조에 따라 결과가 달라지던 브랜드 색

    브랜드 색은 제품마다 다른 값이 들어와요. 그 값을 글자에도 배경에도 그대로 쓰면, 색조에 따라 어떤 브랜드는 잘 읽히고 어떤 브랜드는 그렇지 않았어요. 같은 화면이라도 어떤 색이 들어오느냐에 따라 결과가 달라져서 안정적으로 쓸 수 없었어요.

    명도 단계를 만들고 역할마다 쓸 단계 정하기

    브랜드 색 하나를 받아 색상과 채도는 그대로 두고 명도만 열한 단계로 나눠요. 텍스트는 진한 단계, 옅은 배경은 밝은 단계, 진한 배경은 중간 단계처럼 역할마다 쓸 자리를 미리 정해요. 컴포넌트는 색이 아니라 역할 이름을 쓰기 때문에, 브랜드 색이 바뀌어도 대비 관계는 그대로 유지돼요.

    다크 모드 대응과 앞으로 쌓을 자산의 기초

    같은 팔레트에서 라이트 모드와 다크 모드가 쓸 단계를 각각 잡아두기 때문에 모드를 바꿔도 대비 관계가 유지돼요. 브랜드 색을 바꿔 넣으면 팔레트와 역할별 연결이 다시 만들어져서 화면 전체가 어떻게 달라지는지 바로 확인할 수 있어요. 앞으로 컴포넌트와 화면이 늘어도 색을 매번 다시 고르지 않고 이미 정해진 역할 이름을 쓰면 돼요.

  11. 하는 일이 다른 Input과 Input Button을 나눴어요

    입력창 하나가 타이핑과 화면 열기를 함께 맡던 구조

    겉모습은 같지만 하는 일이 달라요. 하나는 사용자가 값을 직접 넣고, 다른 하나는 달력·주소·시간 선택 화면을 여는 역할이에요. 한 컴포넌트로 두면 이것이 입력하는 자리인지 누르는 자리인지 브라우저에 알려주는 정보와 키보드 동작을 한쪽에만 맞출 수 있어서, 나머지 한쪽에서는 접근성을 보장할 수 없어요.

    외관은 공유하고 역할에 따라 나누기

    Input은 사용자가 값을 직접 입력하는 자리이고, Input Button은 눌러서 선택 화면을 여는 자리예요. 크기 기준과 배치, 시각 외곽은 그대로 공유하기 때문에 한 줄에 나란히 놓아도 어긋나지 않아요. 실제로 어떤 선택 화면을 열지는 이 컴포넌트를 가져다 쓰는 화면에서 정해요.