8px 그리드를 넘어선 논리적 간격 시스템 설계 가이드
디자인 가이드를 넘겨받았는데 어떤 곳은 간격이 13px이고, 어떤 곳은 15px이라 당황했던 적 없으신가요? 디자이너가 매번 직관에 의존해 숫자를 결정하고 개발자는 그 의중을 파악하느라 시간을 허비하고 있다면, 그 팀의 디자인 시스템은 뿌리부터 흔들리고 있는 것입니다. 단순한 숫자의 나열을 넘어 누구나 납득할 수 있는 질서를 부여하는 것이 바로 그리드와 스페이싱 시스템의 핵심입니다.
이 글에서는 업계 표준인 8px 그리드의 원리를 깊이 있게 살펴보고, 한 걸음 더 나아가 실무에서 어떻게 ‘논리적 간격(Logical Spacing)’을 정의하여 디자인과 개발 사이의 불필요한 소통을 줄일 수 있는지 그 구체적인 엔지니어링 전략을 제시합니다. 이 시스템을 구축하고 나면 더 이상 “이 간격은 왜 이렇게 주었나요?”라는 질문을 주고받을 필요가 없어집니다.
8px 그리드, 왜 하필 8인가요?
우리가 8px 그리드를 사용하는 이유는 단순히 사람들이 많이 써서가 아닙니다. 공학적인 관점에서 8은 2의 거듭제곱($2^3$)으로, 대부분의 화면 해상도에서 정수 단위로 깔끔하게 나누어 떨어지는 숫자이기 때문입니다. 이는 화면 밀도(DPI)가 높은 환경에서도 픽셀이 소수점으로 쪼개져 화면이 뿌옇게 보이는 ‘안티앨리어싱(Anti-aliasing)’ 현상을 방지해 줍니다.
실무에서 모든 간격을 8의 배수로 가져가면 컴포넌트 간의 시각적 리듬이 일정해집니다. 버튼 내부의 패딩, 카드 사이의 간격, 섹션 간의 여백이 모두 8, 16, 24, 32px와 같은 규칙 안에 존재할 때 사용자는 안정감을 느낍니다. 하지만 단순히 8의 배수를 지키는 것만으로는 충분하지 않습니다. 시스템이 커질수록 우리는 숫자가 아닌 ‘의도’를 담은 이름을 고민해야 합니다.
[💡 에디터의 실무 팁: 8px 그리드가 너무 크다고 느껴지는 좁은 영역(아이콘 내부 등)에서는 4px 단위를 보조로 사용하세요. 다만, 4px는 아주 예외적인 경우에만 허용하는 것이 시스템의 엄격함을 유지하는 비결입니다.]
숫자를 넘어 의미를 부여하는 논리적 간격 토큰
개발 코드에 padding: 16px라고 적는 순간, 그 값은 죽은 데이터가 됩니다. 나중에 전체적인 여백을 20px로 넓히고 싶을 때 수천 개의 파일을 뒤져야 하기 때문이죠. 그래서 우리는 간격을 ‘논리적 토큰’으로 추상화해야 합니다. 저는 보통 spacing-sm, spacing-md, spacing-lg와 같은 스케일 기반 토큰과 spacing-layout-margin 같은 역할 기반 토큰을 혼합하여 사용합니다.
여기서 중요한 점은 간격의 위계를 정의하는 것입니다. 컴포넌트 내부 요소 간의 조밀한 간격(In-set), 컴포넌트끼리 떨어져 있는 간격(Out-set), 그리고 페이지 전체의 레이아웃을 결정하는 큰 간격(Layout)으로 구분하여 토큰을 할당하세요. 이렇게 계층을 나누어 관리하면 디자인 시스템이 단순한 스타일 가이드를 넘어 서비스의 논리 구조를 대변하게 됩니다.
트러블슈팅: 반응형 그리드에서 발생하는 간격 붕괴 해결법
실제로 한 글로벌 프로젝트를 진행할 때, 데스크톱에서 완벽했던 32px 간격이 모바일로 가니 화면의 절반을 차지해 콘텐츠가 밀려나는 문제가 발생했습니다. 고정된 픽셀 기반의 간격 토큰이 반응형 환경의 유연성을 따라가지 못한 것이 원인이었습니다.
저는 이를 해결하기 위해 ‘반응형 간격 토큰’ 전략을 도입했습니다. spacing-container라는 토큰에 모바일에서는 16px, 태블릿에서는 24px, 데스크톱에서는 32px라는 값을 모드(Mode)별로 다르게 할당한 것이죠. 개발자는 코드에서 단순히 var(--spacing-container)만 사용하면 브라우저 너비에 따라 간격이 자동으로 최적화됩니다. 이것이 바로 피그마 변수(Variables)와 CSS 변수를 결합했을 때 발휘되는 진정한 DesignOps의 위력입니다.
[💡 에디터의 실무 팁: 간격 토큰을 정의할 때 절대 ‘위, 아래, 왼쪽, 오른쪽’과 같은 방향성을 이름에 넣지 마세요. 대신 ‘inline’과 ‘block’ 같은 논리적 방향을 사용하면 RTL(오른쪽에서 왼쪽으로 읽는 언어) 대응 시 코드를 한 줄도 고치지 않아도 됩니다.]
레이아웃 그리드와 거터(Gutter)의 수학적 정렬
스페이싱 시스템은 레이아웃 그리드와 긴밀하게 연결되어야 합니다. 우리가 흔히 쓰는 12컬럼 그리드 시스템에서 컬럼 사이의 간격인 ‘거터’는 우리가 정의한 스페이싱 토큰 중 하나와 반드시 일치해야 합니다. 예를 들어 거터가 24px라면, 컴포넌트 간의 간격도 24px의 배수로 설정하여 시각적인 수직/수평 정렬 선을 맞춰야 합니다.
이 정렬이 깨지면 사용자는 본능적으로 UI가 지저분하다고 느낍니다. 디자인 엔지니어는 그리드 도구(Grid Overlay)를 항상 켜두고 컴포넌트의 경계선이 그리드 라인에 정확히 물리도록 강제해야 합니다. 이를 자동화하기 위해 CSS Grid나 Flexbox의 gap 속성에 우리 시스템의 간격 토큰을 변수로 주입하는 것을 표준 작업 절차로 삼으세요.
자주 묻는 질문(FAQ)
Q1. 8px 그리드를 쓰면 10px나 12px 간격은 절대 쓰면 안 되나요?
시스템의 일관성을 위해서는 지양하는 것이 좋습니다. 하지만 디자인의 특성상 8 단위가 너무 크거나 작을 때는 4px 단위를 제한적으로 허용할 수 있습니다. 다만 10px처럼 4의 배수가 아닌 숫자는 시스템의 규칙을 완전히 파괴하므로 절대 추천하지 않습니다.
Q2. 간격 토큰의 이름을 짓는 가장 좋은 방법은 무엇인가요?
spacing-1, spacing-2처럼 숫자를 쓰는 방식과 spacing-xs, spacing-sm처럼 티셔츠 사이즈를 쓰는 방식이 있습니다. 전자는 확장이 쉽지만 의미 전달이 부족하고, 후자는 직관적이지만 중간 단계가 필요할 때 난처해집니다. 최근에는 두 장점을 결합해 spacing-100, spacing-200처럼 100 단위의 숫자를 쓰는 방식이 가장 선호됩니다.
Q3. 개발 환경에서 간격 실수를 방지하는 린트(Lint) 설정이 있나요?
네, Stylelint나 ESLint 플러그인을 사용하여 미리 정의된 변수가 아닌 하드코딩된 픽셀 값을 사용하면 경고를 띄우도록 설정할 수 있습니다. “Constraint is freedom”이라는 말처럼, 도구를 통한 강제성이 팀 전체의 코드 퀄리티를 보장합니다.