주의사항
Atomic CSS를 사용할 때 알아두어야 할 주의사항들입니다. 이 내용을 미리 파악하면 예상치 못한 문제를 방지할 수 있습니다.
동적 클래스 바인딩
가장 흔한 실수
Atomic CSS는 소스 코드를 정적으로 스캔하여 클래스를 감지합니다. JavaScript 변수에 담긴 클래스명은 감지하지 못합니다.
원인
Atomic CSS 익스텐션은 파일 저장 시점에 소스 코드의 텍스트를 분석하여 사용된 클래스명을 찾고, 해당 CSS만 생성합니다. JavaScript를 실행하지 않으므로, 변수 안에 있는 문자열을 추적할 수 없습니다.
감지 안됨
변수를 통한 동적 바인딩은 클래스를 감지하지 못합니다.
<!-- ❌ 변수에 담긴 클래스 — CSS 미생성 -->
<script setup>
const boxStyle = "w100px h100px bg6366F1 br8px"
</script>
<div :class="boxStyle"></div>감지됨
클래스명이 소스 코드에 리터럴로 존재하면 정상 감지됩니다.
<!-- ✅ 리터럴 클래스 — CSS 정상 생성 -->
<div class="w100px h100px bg6366F1 br8px"></div>프레임워크에서의 동적 바인딩
Vue, React, Svelte 등에서 동적으로 클래스를 바인딩할 때도 동일한 문제가 발생합니다.
감지 안됨
<!-- ❌ v-for + 동적 바인딩 -->
<script setup>
const items = [
{ cls: "bg6366F1 br8px" },
{ cls: "bg34D399 br12px" },
]
</script>
<div v-for="item in items"
:class="item.cls">
</div>감지됨
<!-- ✅ 조건부도 전체 문자열로 -->
<div :class="active
? 'bg6366F1 cFFFFFF'
: 'bg27272A c71717A'">
</div>
<!-- ✅ 이렇게 하면 두 클래스 세트 모두
소스에 리터럴로 존재하여 감지됨 -->문자열 조합도 불가
템플릿 리터럴이나 문자열 연결로 클래스명을 만드는 것도 감지하지 못합니다.
감지 안됨
// ❌ 문자열 조합으로 클래스 생성
const size = 16
const cls = `fs${size}px` // "fs16px"
// → 소스에 "fs16px" 리터럴이 없음
// ❌ 함수로 클래스 생성
function getBg(color) {
return `bg${color}`
}
getBg("FF0000") // "bgFF0000"
// → 소스에 "bgFF0000" 리터럴이 없음감지됨
// ✅ 전체 클래스명을 리터럴로 사용
const cls = isLarge ? 'fs2rem' : 'fs1-4rem'
// → 'fs2rem'과 'fs1-4rem' 모두 감지됨
// ✅ 맵 객체에 리터럴로 나열
const sizeMap = {
sm: 'fs1-2rem p8px',
md: 'fs1-4rem p12px',
lg: 'fs1-6rem p16px',
}
// → 모든 값이 리터럴로 존재하여 감지됨핵심 원칙
클래스명의 전체 문자열이 소스 코드 어딘가에 그대로 존재해야 합니다. 조합, 분리, 변수 참조 모두 감지 대상이 아닙니다.
클래스명 충돌
Atomic CSS는 CSS 속성의 앞글자 조합으로 클래스명을 만들기 때문에, 서로 다른 속성이 같은 약어를 가질 수 있습니다. 이 경우 단위 유무로 구분합니다.
| 클래스 | CSS | 구분 기준 |
|---|---|---|
fs0 | flex-shrink: 0 | 단위 없음 → flex-shrink |
fs16px | font-size: 16px | 단위 있음 → font-size |
fs1-4rem | font-size: 1.4rem | 단위 있음 → font-size |
br8px | border-radius: 8px | 단위 있음 → border-radius |
br0 | border-radius: 0 | border-radius 리셋 |
brn | border-right: 0 | border-right 제거 |
헷갈릴 때는
자동완성을 활용하세요. 클래스명을 입력하면 어떤 CSS가 생성되는지 호버 프리뷰로 바로 확인할 수 있습니다. 확실하지 않을 때는 추측하지 말고 확인하세요.
단위 누락
수치를 사용하는 속성에는 반드시 단위를 포함해야 합니다. 단위가 없으면 다른 속성으로 해석되거나 동작하지 않습니다.
단위 없음 — 의도와 다른 결과
fs16 | 동작 안함 (단위 필요) |
w100 | 동작 안함 (단위 필요) |
gap10 | 동작 안함 (단위 필요) |
br0 | border-radius: 0 |
단위 포함 — 올바른 결과
fs16px | font-size: 16px |
w100px | width: 100px |
gap10px | gap: 10px |
br0 | border-radius: 0 |
단위 규칙 요약
px— 픽셀:w100px,gap8pxrem— 1rem=10px:w10rem(100px),gap2rem(20px)p— 퍼센트:w50p(50%),w100p(100%)vh/vw— 뷰포트:h100vh,w100vw
CSS 적용 순서 (우선순위)
Atomic CSS 클래스는 모두 동일한 선택자 우선순위(단일 클래스)를 가집니다. 같은 속성을 가진 클래스가 여러 개 있으면 CSS 파일에서 나중에 선언된 클래스가 적용됩니다. HTML의 class 속성에서의 순서가 아닙니다.
<!-- ⚠️ w100px와 w200px 중 어느 쪽이 적용될까? -->
<div class="w100px w200px bg18181B p16px">
CSS 파일 내 선언 순서에 따라 결정됨
(HTML class 속성에서의 순서가 아님)
</div>
<!-- ✅ 같은 속성은 하나만 사용 -->
<div class="w200px bg18181B p16px">
명확하게 하나만 지정
</div>주의
같은 속성의 클래스를 중복 사용하면 어느 쪽이 적용될지 예측하기 어렵습니다. 하나의 요소에는 같은 속성의 클래스를 하나만 사용하세요.
의도적으로 우선순위를 높여야 할 때는 !important를 추가하는 i 접미사를 사용합니다.
<!-- i 접미사로 !important 추가 -->
<div class="w100pxi bg6366F1 p16px">
width: 100px !important
</div>
<!-- 외부 라이브러리 스타일 덮어쓰기 -->
<div class="external-component df jcc aici">
display: flex !important로 레이아웃 강제 적용
</div>!important 남용 금지
i 접미사는 외부 라이브러리 스타일을 덮어써야 할 때 등 꼭 필요한 경우에만 사용하세요. 일반적인 스타일링에서는 사용하지 않는 것이 좋습니다.
rem 기준값
Atomic CSS의 rem 단위는 html { font-size: 10px }을 기준으로 설계되었습니다. 즉 1rem = 10px입니다. 이 설정이 없으면 rem 값이 의도와 다르게 적용됩니다.
기준값 미설정 시 (1rem = 16px)
fs1-6rem | 의도: 16px, 실제: 25.6px |
gap2rem | 의도: 20px, 실제: 32px |
w24rem | 의도: 240px, 실제: 384px |
기준값 설정 시 (1rem = 10px)
fs1-6rem | 16px 정확 |
gap2rem | 20px 정확 |
w24rem | 240px 정확 |
프로젝트의 전역 CSS에 다음을 추가하세요:
html {
font-size: 10px;
}
/* 이제 rem 계산이 직관적입니다 */
/* 1.6rem = 16px */
/* 2rem = 20px */
/* 2.4rem = 24px */
/* 10rem = 100px */rem을 쓰지 않는다면?
모든 값을 px로만 사용한다면 이 설정은 필수가 아닙니다. 하지만 rem은 20px 이상 큰 값을 간결하게 표현할 수 있어 권장됩니다.
하이픈(-) 해석
하이픈은 문맥에 따라 다르게 해석됩니다. 의도와 다른 결과를 방지하려면 하이픈의 역할을 정확히 이해해야 합니다.
| 용도 | 예시 | 해석 |
|---|---|---|
| 소수점 | gap1-5rem | gap: 1.5rem (15px) |
| 소수점 | fs1-4rem | font-size: 1.4rem (14px) |
| 값 구분 | gtc1fr-2fr-1fr | grid-template-columns: 1fr 2fr 1fr |
| 값 구분 | flex1-1-auto | flex: 1 1 auto |
| 미디어 쿼리 | sm-dn | @media (max-width: 768px) { display: none } |
| 의사 클래스 | hover-bgFF0000 | :hover { background-color: #FF0000 } |
| 음수 | neg-mt10px | margin-top: -10px |
혼동 주의
gap1-5rem은 1.5rem이지 1rem과 5rem이 아닙니다. 하이픈이 소수점인지 값 구분인지는 뒤에 오는 단위로 판단됩니다.
생성된 CSS 파일 직접 수정 금지
Atomic CSS 익스텐션이 자동 생성한 CSS 파일(atomic.css 등)은 직접 수정하면 안 됩니다. 파일 저장 시 익스텐션이 다시 스캔하여 내용을 덮어쓰기 때문입니다.
하지 말 것
- atomic.css에 직접 스타일 추가
- atomic.css 내 클래스 수정/삭제
- atomic.css에 커스텀 클래스 정의
올바른 방법
- 전역 리셋/폰트는 별도 CSS 파일에 작성
- HTML에 Atomic 클래스를 추가하면 CSS가 자동 생성
- 불필요한 클래스는 HTML에서 제거하면 CSS에서도 사라짐
체크리스트
Atomic CSS 사용 시 다음 사항을 점검하세요.
클래스명이 소스 코드에 리터럴 문자열로 존재하는가?
수치 클래스에 단위(px, rem, p, vh)가 포함되어 있는가?
html { font-size: 10px }이 설정되어 있는가? (rem 사용 시)
같은 속성의 클래스를 중복 사용하고 있지 않은가?
자동 생성된 CSS 파일을 직접 수정하지 않았는가?
헷갈리는 클래스는 자동완성 프리뷰로 확인했는가?