Navigation

CSS

에이전트 협업 팀을 위한 CSS 코딩 컨벤션입니다. 일반 CSS를 기본으로 한 전역 고유 이름, pg_, wg_, ui_ 소유 범위, 예측 가능한 TSX 클래스 조합, 평평한 선택자, 다른 소유자의 클래스는 자기 루트 아래에서만 선택자로 잡는 경계, 토큰으로 모은 값, 눈에 보이는 포커스 표시, stylelint 설정을 다룹니다. TSX의 클래스 계약을 함께 바꿀 때는 React와 TypeScript 규칙도 함께 봅니다.

함께 보는 규칙

규칙

1. 클래스 이름과 문법

일반 *.css를 사용하고 전역에서 고유한 클래스 이름을 붙입니다. 클래스 이름은 소유자와 역할을 드러내고, 요소와 수정자는 정해진 문법으로 구분합니다. 섹션 페이지

규칙요지
1.1 프로젝트 표준이 없으면 CSS Modules 대신 일반 CSS를 씁니다클래스 이름이 전역에서 고유해야 범위_식별자로 소유자를 되짚을 수 있습니다
1.2 클래스 이름은 범위_식별자__요소--수정자 형식으로 씁니다클래스 이름에서 소유자와 역할을 확인할 수 있습니다
1.3 요소와 수정자는 역할로 이름을 짓습니다구조나 치수 대신 역할을 이름에 담아 UI의 어느 부분인지 구분합니다
1.4 pg_* 식별자에 화면 이름을 드러냅니다클래스 이름에서 해당 화면을 추적할 수 있습니다

2. 소유와 경계

CSS 파일마다 소유자를 정하고, 다른 소유자의 스타일을 사용할 때 지킬 범위를 명시합니다. 외부 라이브러리 DOM은 소유한 루트 아래에서만 선택해 다른 화면에 영향을 주지 않습니다. 섹션 페이지

규칙요지
2.1 CSS 파일마다 고유한 범위_식별자를 하나씩 씁니다파일마다 네임스페이스를 구분해 전역 클래스 충돌을 막습니다
2.2 범위 접두사는 소유 레이어를 따릅니다클래스 접두사로 소유 레이어를 구분합니다
2.3 다른 소유자의 클래스는 내 최상위 블록 안에서만 씁니다다른 소유자의 스타일을 덮어써도 해당 인스턴스에만 적용되도록 제한합니다
2.4 다른 소유자의 모습은 해당 소유자의 API로 바꿉니다다른 소유자의 모습을 바꿀 때 배치 조정, 변형 노출, 레이어 이동을 순서대로 판단합니다

3. TSX 클래스 조합

TSX에서 클래스를 조합하는 방법과 UI 래퍼가 허용하는 스타일 범위를 정합니다. 클래스의 책임과 수정자로 표현할 변형을 구분하고, 시각적 표현은 인라인 style 대신 클래스로 지정합니다. 섹션 페이지

규칙요지
3.1 클래스는 clsx()로 조합합니다기본 클래스와 상태 수정자의 조합을 TSX에서 한눈에 읽을 수 있습니다
3.2 수정자는 상태와 반복되는 모양에만 씁니다일회성 배치 보정이 수정자로 늘어나지 않게 합니다
3.3 기본 스타일과 상태를 한 클래스에 섞지 않습니다기본 스타일과 상태를 분리해 상태만 켜고 끌 수 있습니다
3.4 외부 클래스는 컴포넌트 진입점에서만 받습니다클래스 주입을 한 곳으로 제한해 사용처가 내부 구조에 의존하지 않게 합니다
3.5 스타일 때문에 요소를 새로 감싸지 않습니다래퍼 요소는 부모 레이아웃 계산을 바꾸고 역할 없는 클래스를 늘립니다
3.6 인라인 style로 스타일을 주지 않습니다모든 시각 결정이 스타일시트에 남아 검색과 덮어쓰기가 예측대로 동작합니다
3.7 수정자는 조건으로 적고 클래스 이름을 조립하지 않습니다클래스 이름이 코드에 문자열로 남아 CSS와 사용처를 한 번의 검색으로 함께 고칩니다

4. 선택자와 선언 배치

선택 대상은 클래스 이름으로 명시하고, 각 클래스의 선언은 한 블록에 모읍니다. 브라우저가 제공하는 DOM 상태는 가상 클래스로, 앱이 정의한 상태는 수정자 클래스로 표현합니다. 섹션 페이지

규칙요지
4.1 선택자 중첩은 한 겹까지만 쓰고 나머지 경로는 한 줄로 잇습니다선택자 경로가 여러 중첩 블록에 흩어지지 않습니다
4.2 요소 선택자 대신 클래스를 붙입니다태그를 바꿔도 스타일이 유지되도록 마크업을 클래스로 선택합니다
4.3 공통 선언을 쓰려고 클래스를 쉼표로 묶지 않습니다공통 선언도 각 클래스에 두어 전체 스타일을 한 곳에서 읽습니다
4.4 한 클래스의 선언은 한 블록에 모읍니다한 클래스의 선언을 한 블록에서 확인하고 수정합니다
4.5 DOM이 표현하는 상태는 가상 클래스로 씁니다DOM 상태와 앱 상태를 구분해 같은 상태를 중복 표현하지 않습니다
4.6 DOM 상태 가상 클래스는 해당 요소의 기본 블록에 둡니다기본 모습과 상태 변화를 함께 읽고 수정자가 꺼져도 상호작용 표시를 유지합니다
4.7 선택자에 :not()을 쓰지 않습니다기본 모습을 기본 블록에 두어 부정 조건을 따로 해석하지 않게 합니다

5. 디자인 토큰

여러 파일이 공유하는 값은 전역 토큰으로 정의하고 사용처에서는 토큰 이름을 참조합니다. z-index 순서와 테마 값도 토큰으로 관리해 변경할 곳을 한곳에 모읍니다. 섹션 페이지

규칙요지
5.1 대체값은 공통 토큰 밖의 var()에만 둡니다공통 토큰의 수정 위치를 하나로 유지하고 대체값의 중복을 막습니다
5.2 여러 파일이 쓰는 값은 전역 토큰으로 씁니다여러 파일이 쓰는 값은 전역 토큰으로 모으고 나머지는 선언 자리에 그대로 둡니다
5.3 z-index 층은 토큰 파일 한 곳에 선언합니다층 순서를 한 파일에서 확인하고 z-index 숫자를 임의로 늘리지 않습니다
5.4 테마는 토큰 값만 바꿔서 전환합니다테마 분기가 한 파일에만 있어 색을 하나 더할 때 파일 여러 개를 열지 않습니다
5.5 토큰 이름은 값이 아니라 쓰임으로 짓습니다값이 바뀌어도 토큰 이름이 쓰임을 나타내고 일관된 형식을 유지합니다

6. 레이아웃과 반응형

클래스 이름과 선언에 배치 의도를 드러내고, 폭에 따른 변경은 한곳에 모읍니다. 브레이크포인트를 추가하기 전에 고유 크기 지정으로 해결할 수 있는지 확인합니다. 뷰포트 브레이크포인트는 파일 아래 한곳에 모으고 데스크톱 퍼스트로 정한 세 값만 씁니다. 컴포넌트가 받은 폭에 따라 구조를 바꿔야 하면 컨테이너 쿼리를 씁니다. 섹션 페이지

규칙요지
6.1 @media 브레이크포인트는 파일 맨 아래에 모읍니다각 브레이크포인트에서 달라지는 스타일을 한 블록에서 확인합니다
6.2 브레이크포인트는 데스크톱 퍼스트로 세 값만 씁니다넓은 화면부터 좁은 화면 순서로 덮어쓰고 프로젝트 전체에서 세 기준 폭을 공유합니다
6.3 레이아웃의 기준과 역할을 클래스 이름과 선언에 드러냅니다조상 DOM을 찾아보지 않고 sticky, fixed의 기준과 각 요소의 배치 역할을 파악합니다
6.4 브레이크포인트보다 고유 크기 지정을 먼저 검토합니다컴포넌트가 배치된 폭에 맞춰 크기를 조정해 위치가 바뀌어도 CSS 수정을 줄입니다

7. 접근성과 움직임

키보드 포커스를 눈으로 확인할 수 있고, 움직임에 민감한 사용자도 이용할 수 있어야 합니다. 포커스 표시는 없애지 않고 형태로 구분하며, 애니메이션은 전역 이름을 겹치지 않게 두고 사용자 설정을 따릅니다. 섹션 페이지

규칙요지
7.1 포커스 표시는 항상 눈에 보이게 남깁니다포커스 위치를 형태로 구분해 키보드 사용자가 현재 위치를 알 수 있습니다
7.2 @keyframes 이름에 소유자를 붙이고 prefers-reduced-motion을 따릅니다전역 애니메이션 이름의 충돌을 막고 움직임에 민감한 사용자의 설정을 따릅니다

8. 도구 설정

자동 검사할 항목은 stylelint로 설정하고, 도구가 판단하지 못하는 항목은 리뷰에서 확인합니다. 섹션 페이지

규칙요지
8.1 stylelint로 자동 검사할 규칙을 설정합니다자동 검사 범위를 설정으로 고정하고 의미 판단은 리뷰에 남깁니다

참고 자료