본문 바로가기

FrontEnd

[CSS] Spacing(간격) 프레임워크 구축

반응형

TL;DR

간격은 정보 계층을 표현
유지보수성 및 일관성 향상을 위해 시스템화 된 간격을 사용하자


이 글을 요약하는 치트 시트


랜덤 간격의 문제점

무작위 간격은 타이포그래피 시스템과 어울리지 않을 수 있음

  • 어떤 간격 값을 언제 사용해야 하는지에 대한 엄격한 지침이 필요
  • 마진 / 패딩은 간격(spacing) 퍼즐의 한 조각일 뿐임.
    • 타이포그래피의 줄 높이도 UI에 상당한 공간을 추가함.

> 타이포그래피 줄 높이 시스템과 간격 시스템이 없어 두 간격 관심사 혼재; 재사용성 감소

타이포그래피 줄 높이 시스템과 간격 시스템이 없어 두 간격 관심사 혼재; 재사용성 감소

아래와 같이 타이포그래피 시스템을 고려해 간격 시스템을 개선할 수 있음

타이포그래피 시스템을 고려해 간격 시스템을 개선할 수 있음 TO-BE

 

Step 1: Determine body text line-height (& baseline grid that works)

타이포그래피의 줄 높이(line-height)는 간격 시스템 퍼즐의 첫 번째 조각입니다.
인기 있는 8포인트 베이스라인 그리드(8-point baseline grid; 즉, 8 간격의 배수 / 인수)가 효과가 있을 것이라는 가설로 시작함.
전 13/16 시스템과 (폰트 크기 / 줄 높이) 13/24 시스템 + 8px 마진을 시도해 보았으나 결과는 좋지 않았음.
(줄 높이, 마진 모두 둘 다 8의 배수)
32+16 / 48 + 16을 의미
 
줄 높이와 마진 크기를 18px(6의 배수) / 6px로 변경 후 테스트 (not good)
  • 6-포인트 베이스라인 그리드;일명 6 간격 , 6의 배수, 6의 인수를 사용함(2,3,6,12,18,24..와 같은 간격 값)을 의미

줄 높이와 마진 크기 20px / 8px를 테스트 (good)

  • 4-포인트 베이스라인 그리드;일명 4 간격; 4의 배수, 4의 인수를 사용함(2,4,8,12,16,20..와 같은 간격 값)를 의미
13/20/8이 딱 좋아보임

결과 : 13/20, 8px 그리드


Step 2: Hick’s law & geometric progression to determine spacing values

“선택의 수가 늘어날수록 결정을 내리는 것이 기하급수적으로 어려워집니다.” — 힉스의 법칙

의사 결정을 단순화하고, 예측 가능한 시스템을 만들려면, 값의 수를 가능한 한 최소값으로 유지해야 함.

  • 간격(Spacing) 값은 baseline-grid 수(4, 1단계에서 결정됨)의 인수 또는 배수
    • 따라서 간격 값은 해당 세트(2,4,8,12,16,20,24,28,..)에서 가져옴
  • 일반적으로 최대 4-5개의 값이면 충분함.
    • 복잡한 엔터프라이즈 제품에도 충분하지만, 정말 필요하다면 간격 갯수를 늘릴 수 있음.
  • 시각적으로 더 나은 간격을 제공하므로, 기하수열을 사용하여 파생한 처음 4개 값을 선택하기로 결정
    • 계층 구조 표시에 탁월
    • 따라서 간격 값은 (2,4,8,16)이 될 것
조화 수열 파생 간격 값
값 선택에 대한 분석은 Nathan Curtis’s Spacing in Design systems 게시물을 참조하세요

예측 가능한 방식으로 이러한 간격 값을 적용하려면 어떻게 해야 할 지 알아보자

결과 : 16, 8, 4, 2의 간격 값(px)


3C(컨테이너, 콘텐츠 및 컴포넌트) 법칙

모든 간격 규칙을 3C: 컨테이너, 콘텐츠 및 컴포넌트로 분류함.
  • 컨테이너 규칙은 Square Inset의 개념을 사용 (16px 사용).
    • 페이지, 카드, 모달, 창(pane)
  • 콘텐츠에 대한 규칙은 스택 개념을 사용
    • 헤더 스택은 2px
    • 리프 노드 스택은 콘텐츠 유형에 따라 0,4,8,16px
  • 컴포넌트 규칙은 인라인 개념을 사용
    • 대부분의 경우 8px
    • 연결 관계에 4px

1st C: Rule for Containers

  • 컨테이너는 콘텐츠를 담고 있는 UI의 프레임
    • Nathan에 의해 square inset으로 정의됨
  • 일반적으로 이들은 페이지, 카드, 모달, 창
  • 컨테이너는 계층 구조에서 가장 높은 수준에 있기 때문에 모든 컨테이너가 가장 큰 간격 값(제 경우에는 16px)을 갖도록 함.
디자인 시, 간격 계산에 테두리를 포함하지 말 것 (Elliot Dahl’s 8-point grid: Borders and Layouts)
주 : 디자인 도구는 Border-Box를 제공하지 않으니, 패딩과 테두리를 각자 적용.
코드에서는 border-box를 사용

컨테이너에 16px(가장 큰 간격)

결론 : 컨테이너 패딩으로 16픽셀


2nd C: Rules for Content

콘텐츠는 컨테이너 내부에 존재함.

콘텐츠는 다음을 포함함.

  • headers (h1,h2,h3,h4,h5)
  • 데이터가 산재해 있는 paragraphs, lists, forms, tables 등
    • 헤더 계층 구조의 끝에 나타나므로 앞으로 "리프 노드"라고 칭함
이 모든 콘텐츠는 마진을 사용하여 세로로 쌓임.
타이포그래피의 line-height는 마진에 간격을 추가함.
줄 높이와 마진을 동시에 고려하여 스택을 처리할 필요가 있음

A) 헤더 스택을 먼저 처리

아래 이미지의 헤더의 line-height 옵션 중 두 가지 중 하나를 선택하기로 함
해당 값이 어떻게 나왔는지는 타이포그래피 시스템 게시물(read my typography system post)을 참조
헤더의 줄 높이 옵션 중 두 가지 중 하나를 선택

두 가지 옵션 간의 의사 결정을 단순화하기 위해 비율 1.5 이상의 줄 높이로 작업하기로 결정함.
시각적 탐색을 수행하고 디자인 팀 내에서 결과를 검토하니, 해당 값을 사용하는게 적절해 보임
두 가지 옵션 간의 의사 결정을 단순화하기 위해 비율  1.5 이상의 줄 높이로 작업하기로 결정함.

시각적 탐색의 과정

헤더 스택 상단에서 h1으로 시작하여 flush(0px), 2px, 4px, 8px로 시작하는 다양한 간격 옵션을 실험해봄
  • 줄 높이가 36px인 대부분의 간격 옵션은 빡빡하게 느껴짐
  • 줄 높이 40px + 4px 간격이 적절해 보임
줄 높이 40px + 4px 간격이 적절해 보임
다음으로 h2를 처리함.
h2는 흰색 페이지 컨테이너의 첫 번째 헤더임.
컨테이너 규칙에 따라 최상위 h2는 16px 간격이 필요함
그렇기에 모든 h2 위에 16px 간격(최대 허용 간격)을 부여하기로 결정함.
그 값이 상위 섹션 계층 구조를 명확하게 만들기 때문임.
다음으로 모든 헤더(h2,h3,h4,h5)와 리프 노드(목록, 단락, 테이블, 양식) 사이에 0px, 2px, 4px 및 8px의 간격 값을 실험
2px와 4px의 결과가 다 좋아보였지만, 내부 논의 결과 2px 마진을 사용하기로 결정함.
가능한 한 1개의 마진 값을 유지하는 것이 좋음. 디자인과 개발 프로세스가 간소화되기 때문.

 

Header & leaf node spacing experiments

Header stacks : spacing with 2px and 4px
seems right!

결론 : h1은 4px, h2는 16px (컨테이너 헤더), 나머지 4px


B) 리프 노드 스택을 다음으로

4가지 주요 타입의 리프 노드가 존재함.
  • Tables (almost 50% of the product)
  • Lists (almost 30% of the product)
  • Forms (probably 15% of the product)
  • Paragraphs (probably 5% of the product)
가장 단순한 콘텐츠 타입인 단락(Paragraphs)의 간격을 먼저 처리함

각 단락(Paragraph) 내 간격

가장 간단함.
두 줄 사이에 0px 마진이 있도록 단락의 모든 텍스트 줄을 줄바꿈 하면 됨.
목록처럼 보이지 않는 모든 것(예: 표의 행의 두 줄 사이)에도 단락 내 간격이 존재함

스케치에서 서체 단락(20px의 줄 높이는 시각적 탐색을 통해 파생되었음.


연속된 두 단락 사이의 간격

첫 번째 충동은 line-height = 20px와 같은 간격을 사용하는 것이었음.
하지만 WCAG SC 1.4.8을 발견함.
"단락 ​​간격은 줄 간격보다 (최소) 1.5배 더 큽니다.
 
즉, 1 단락의 마지막 줄 상단에서 다음 단락의 첫번째 줄 까지의 간격이 줄 높이의 250%라는 것을 의미함.
((20-13) * 1/2 *2.5)px
WCAG SC 1.4.8의 단락 간격 조항 해석
 
 
기준 글꼴 크기 13px를 기준으로 % 값을 계산한다고 가정하고
두 단락 사이의 실제 간격은 약 (ps — ls)=13px이어야 한다고 계산함.
(ls : 1.5 * 13px = 20px로 줄 높이임, ps : 2.5* 13px => 2.5-1.5  = 1)
이는 margin-bottom: 13px를 사용하여 CSS에서 정의됨.
13px는 2단계에서 결정한 간격 값 중 하나가 아님
따라서 단락의 여백-하단에 대해 가장 가까운 값인 16px을 선택함.

Sketch에서 설정

계산에 대해 확신이 서지 않을 때는 항상 시각적 탐색을 통해 교차 확인함.
단락 사이의 16px 간격은 다른 가능한 값에 비해 가장 잘 동작함.
(12px 간격이 더 효과적일 수 있음.
하지만 제품에 단락이 많지 않고 연속 단락이 거의 없으면,
이 사용 사례를 위해 space 시스템에 값을 추가할 필요는 없음.)
단락 사이의 16px 간격은 다른 가능한 값에 비해 가장 잘 동작함.
단락 사이의 16px 간격은 다른 가능한 값에 비해 가장 잘 동작함.

결론 : 단락 간 간격 16px


리스트 아이템의 리스트 간 간격

리스트는 여러개의 같은 타입의 데이터로 구성된 데이터 구조임
 
리스트은 이러한 동종 데이터 항목을 모두 그룹화하므로
일반적으로 이질적인 아이디어를 포함하는 단락(사이에 16px)와 다르게
항목들이 많이 떨어져 있지 않은 것이 중요함.
 
그렇지만 리스트 항목들은 여전히 ​​약간 떨어져 있어야 함.
그렇지 않으면 하나의 단락처럼 보일 것이기 때문임.
 
0px와 16px 사이의 간격을 실험함.
실험할 값은 3개(2,4 및 8)뿐.
리스트 항목 사이의 총 4px 간격은 계층 구조에 가장 적합해 보임.
4px이 가장 적절해 보임

 

결론 : 리스트 아이템 간 간격 4px


레이블이 있는 2개의 연속 입력 필드 사이의 간격

폼에는 연속 입력 필드가 하나씩 쌓여 있음
8픽셀이 적절해 보임.

시각적 탐색

 

8픽셀이 적절해 보임

결론 : 레이블이 있는 2개의 연속된 입력 필드 간 간격은 8px


 

레이블이 없는 2개의 연속 입력 필드 사이의 간격

레이블이 없는 것은 접근성에 좋지 않지만, 특정 상황에서는 UI에 레이블을 표시하지 않는 것이 좋음
(접근성을 보장하기 위해 구현에서 레이블을 계속 선언하고 큰 여백을 사용하여 시각적으로 숨기기)
  • 여러 입력 필드가 함께 하나의 객체를 의미하는 경우
    • (예: 아래의 주소 섹션에서 "주소" 필드 집합 범례는 번지 1, 번지 2, 시, 주, 우편번호를 그룹화함)
  • 레이블이 너무 명확하거나 철자가 반복되는 경우 (예: 검색 창 또는 쿼리 빌더)

이러한 상황에서는 필드 세트 범례를 사용하는지 여부에 따라 다른 간격이 동작함
필드 세트 범례는 필드를 그룹화하여 1개의 객체를 나타내므로 더 적은 간격(8px)을 사용합니다.

입력 필드를 하나의 개체로 논리적으로 그룹화하지 않으려면
연속 단락 간격과 마찬가지로 더 많은 간격(16px)이 좋음

결론 : 범례 내 그룹화 시 8px, 아닐 경우 16px 간격


테이블 내부 간격

테이블은 목록과 마찬가지로 유사한 타입의 데이터를 그룹화하는 데 매우 유용함.
  • 테이블은 데이터가 훨씬 더 밀도가 높고 속성이 많을 때 사용됨.
  • 테이블의 간격은 목록보다 좀 더 크면 좋음
    • 데이터 간격이 너무 좁으면 인접한 행 데이터로 인해 주의가 분산되지 않고 전체 테이블 행을 읽기 어려울 수 있기 떄문
아이템과 같은 4px 간격은 너무 작게 느껴짐
테이블 텍스트와 테이블 행 테두리 사이에 8px가 있으면 2행에 걸쳐 텍스트 사이에 총 16px 간격이 생김.
이것은 16px의 연속 단락 간격과 매우 유사함.

테이블 텍스트와 테이블 행 테두리 사이에 8px가 있으면 2행에 걸쳐 텍스트 사이에 총 16px 간격이 생김.

결론 : 상하단 8px 패딩을 이용한 16px 간격 활용


3rd C: Rule for Components

컴포넌트는 버튼, input 필드, 아이콘 등을 의미함.
이러한 컴포넌트는 종종 수평으로(인라인) 서로 옆에 배치됨.
또한 모든 컴포넌트의 크기는 4의 배수(8의 배수)로 지정됨.
따라서 버튼과 input 필드는 높이가 24px인 내부 공간을 갖고 있음.
(1px 상단 및 1px 하단 테두리와 함께 전체 높이는 26px).
 

두 컴포넌트 사이의 간격

  • 대부분의 경우 두 개의 인접한 컴포넌트 사이의 간격에 8px를 적용하는 간단한 규칙을 사용함.
  • 몇 가지 경우에 4px를 사용하여 2개의 컴포넌트(게슈탈트의 근접 법칙) 간의 더 긴밀한 관계를 표시하기로 결정.
근접 법칙(Law of Proximity)은
서로 가까이 있는 요소가 하나의 그룹으로 인식되는 경향이 있다는 게슈탈트 그룹화 법칙입니다.
8px(분홍색) 및 4px(주황색)의 인라인 간격

아이콘이 없는 컴포넌트 내부의 간격

  • 컴포넌트 내부의 모든 왼쪽/오른쪽 패딩에 일관되게 8px를 사용

아이콘이 있는 컴포넌트 내부의 간격

  • 게슈탈트의 근접 법칙을 적용하여 일반적인 8px 대신 4px 간격으로 컴포넌트 내부 아이콘을 그룹화함.

외부 아이콘과 컴포넌트 간격 두기

  • 아이콘이 개별 컴포넌트와 의미적으로 연관이 있으면 4px 간격(게슈탈트의 근접성 원리).
  • 아이콘이 컴포넌트 집합과 연결된 경우 8px 간격
    • 전체 집합과 연결되어 있음을 명확히 하기 위함

결론

  • 쉽고 논리적으로 제한된 값 규칙(게슈탈트의 근접 원칙,힉스의 법칙)을 가진 간격 시스템을 활용할 것
    • 힉스의 법칙(Hick's Law)은, 사람이 무언가를 선택하는데 걸리는 시간은 옵션 수에 따라 결정된다는 법칙
    • 게슈탈트 근접 원칙 : 서로 가까이 있는 요소가 하나의 그룹으로 인식되는 경향이 있다는 원칙
  • 정보 계층을 존중하고 접근성 지침 WCAG 1.4.8을 준수하는 간격 시스템
    • 이를 통해 다양한 사람들이 정보를 보다 쉽게 ​​추적하고 이해할 수 있음
  • 간격 시스템 기반의 의사소통으로 디자인-개발 의사소통 최적화

참고 할 만한 자료

반응형