추상적 불만에서 정확한 수치 한 줄까지
4단계로 좁혀 간다.
처음부터 "padding 20px로 늘려"는 못 시킨다.
가설 → 확인 → 수치 → 요청 4단계로 대화하며 좁힌다.
"이 윗부분"이 아니라 "헤더"로.
위치마다 이름이 있다.
이름을 알면 "헤더에", "사이드바를" 같이 콕 짚어 시킬 수 있다.
| 이름 | 위치 · 역할 |
|---|---|
| header | 최상단 영역 (로고 + 메뉴) |
| nav · navbar | 메뉴바 — 헤더 안 / 사이드 / 하단 |
| hero | 큰 시각 + 핵심 메시지 |
| main | 본문 영역 |
| aside · sidebar | 본문 옆 보조 영역 |
| footer | 최하단 — 저작권·링크 |
| card · modal | 콘텐츠 박스 / 떠 있는 박스 |
모든 HTML 요소는 4겹의 박스다. 안쪽부터 content · padding · border · margin.
안쪽 여백은 padding, 바깥 여백은 margin. padding이 끝나는 지점이 곧 border가 시작되는 지점이다.
| 겹 | 비유 | 역할 |
|---|---|---|
| content | 사진 자체 | 텍스트·이미지가 들어감 |
| padding | 매트지 | 박스 안쪽 여백 |
| border | 액자 테두리 | 박스의 경계선 |
| margin | 옆 액자와의 벽 | 박스 바깥쪽 여백 |
"이 카드 답답해 보여"의 90%는 padding이 부족해서다.
요소의 테두리 안쪽과 내용물 사이의 공간. 박스를 "더 넓어 보이게" 만드는 것이 아니라, 숨 쉴 자리를 주는 것.
| 위치 | 값 |
|---|---|
| 작은 버튼 | 8px 16px |
| 큰 카드 | 20~24px |
| 섹션 컨테이너 | 40~64px |
박스의 보이는 선. 굵기 1px만 바꿔도 디자인 인상이 바뀐다.
content·padding을 감싸는 경계선. 굵기·스타일·색 세 가지로 정의한다.
다른 박스와의 거리. 가까우면 한 묶음, 멀면 별개 그룹.
요소 바깥의 빈 공간. "묶기"와 "분리"를 시각적으로 표현하는 도구.
| 거리 | 인식 |
|---|---|
| 0 ~ 4px | 한 묶음으로 보임 |
| 12 ~ 16px | 같은 그룹 안 분리 |
| 32px 이상 | 별개 그룹으로 보임 |
margin과 같은 결과, 더 깔끔한 방법.
요즘 카드 그리드는 거의 gap을 쓴다.
margin은 박스마다 일일이 줘야 한다.
gap은 감싸는 박스(flex / grid)에 한 번이면 끝.
여러 박스를 한 방향으로 줄 세운다.
메뉴 / 버튼 / 카드 한 줄에 쓴다.
박스들을 감싸고 있는 바깥 박스에 display: flex를 주면, 안에 있는 박스들이 기본적으로 한 줄로 늘어선다.
방향(가로/세로)과 정렬(시작·가운데·끝)을 정할 수 있다. (flex-wrap을 쓰면 여러 줄도 가능)
| 속성 | 역할 |
|---|---|
| flex-direction | 줄 방향 — row(가로) / column(세로) |
| justify-content | 줄 따라 정렬 — start / center / end / space-between |
| align-items | 줄에 수직 정렬 — center / stretch |
줄을 어디에 붙일 것인가.
왼쪽 / 가운데 / 오른쪽 / 양 끝.
justify-content는 줄 방향(가로면 좌우, 세로면 위아래)을 따라 박스들을 어디에 모을지 결정한다.
| 패턴 | 예시 |
|---|---|
| flex-start | 좌측 메뉴, 리스트 아이콘 |
| center | 중앙 정렬 버튼, 페이지 가운데 |
| flex-end | 우측 버튼, 닫기 X |
| space-between | 헤더 — 로고 좌, 메뉴 우 |
행과 열 모두 컨트롤.
카드 그리드 · 대시보드처럼 격자로 배치.
Flex는 한 줄, Grid는 격자(바둑판).
여러 박스를 가로·세로 모두 정해진 칸에 깔끔하게 깔 때 쓴다.
| 속성 | 역할 |
|---|---|
| display: grid | 격자 모드 켜기 |
| grid-template-columns | 열을 몇 개, 어떤 크기로 나눌지 |
| gap | 칸 사이 간격 |
가장 자주 쓰는 패턴.
repeat(N, 1fr) + gap 한 줄로 끝.
카드 여러 개를 줄·열로 깔 때 쓰는 가장 흔한 레시피.
칸 개수만 정하면 안에 들어가는 카드는 알아서 균등 분배.
| 상황 | 설정 |
|---|---|
| 카드 3개 한 줄 | repeat(3, 1fr) |
| 반응형 자동 줄바꿈 | repeat(auto-fill, minmax(240px, 1fr)) |
| 사이드바 + 본문 | 1fr 3fr |
글자의 4개 다이얼을 알면
"읽히는 글"과 "안 읽히는 글"이 갈린다.
글자에는 네 가지 다이얼이 있다 — 글꼴 / 크기 / 굵기 / 행간.
이 4개만 조정하면 글의 인상이 완전히 달라진다.
| 속성 | 역할 |
|---|---|
| font-family | 글꼴 — 본문은 sans, 제목은 serif가 흔함 |
| font-size | 크기 — px 또는 rem 단위 |
| font-weight | 굵기 — 400 보통 · 700 굵게 |
| line-height | 행간 — 줄과 줄 사이 거리 (1.5~1.7 권장) |
한 줄이 차지하는 높이.
값이 커질수록 줄 사이 여유가 늘어난다.
line-height는 한 줄이 차지하는 높이다.
숫자(1.0, 1.6 등)는 글자 크기의 배수 — 1.6이면 글자 높이의 1.6배.
| 용도 | 값 |
|---|---|
| 큰 제목 | 1.1 ~ 1.3 (타이트하게) |
| 본문 | 1.5 ~ 1.7 (가장 흔히) |
| 시·강조 문구 | 1.8 ~ 2.0 (여유 있게) |
무엇이 먼저고 무엇이 보조인지
한눈에 보이게 만드는 기술.
정보에는 중요도가 다른 층이 있다.
제목 → 부제 → 본문 → 메타. 시각적으로 이 순서가 보여야 한다.
| 도구 | 활용 |
|---|---|
| 크기 | 제목 크게, 본문 작게 (1.5배 이상 차이) |
| 굵기 | 중요한 곳만 굵게 (700), 나머지는 보통(400) |
| 색 | 강조는 검정, 보조 정보는 회색 |
| 여백 | 중요한 것 주변에 더 많은 빈 공간 |
제목 / 본문 / 메타를
크기·굵기·색으로 한눈에 갈라낸다.
잘 만든 카드는 안 봐도 위계가 들린다 — 큰 글자가 먼저, 작은 회색 글자는 마지막.
이게 안 되면 LLM에 "글 강약 좀 줘"라고 말할 수 있다.
| 요소 | 크기 / 굵기 / 색 |
|---|---|
| 제목 (h1) | 28~56px · 700 · 검정 |
| 부제 | 18~22px · 500 · 진한 회색 |
| 본문 | 14~16px · 400 · 회색 |
| 메타 (날짜·태그) | 11~12px · 400 · 옅은 회색 |
비어 있는 공간도 디자인의 일부다.
여백이 적으면 답답, 많으면 시원.
여백은 "버리는 공간"이 아니다.
정보를 묶고, 끊고, 숨 쉬게 만드는 적극적인 도구.
| 종류 | 예시 |
|---|---|
| Macro (큰 여백) | 섹션·블록 사이 — margin 64px+ |
| Micro (작은 여백) | 줄·글자 사이 — padding 16px · line-height 1.7 |
여백을 어디에 더 주느냐가
"한 묶음"과 "별개"를 가른다.
안쪽 여백은 좁게, 그룹 사이 여백은 넓게.
반대로 하면 어디까지가 한 묶음인지 알 수 없다.
| 관계 | 여백 |
|---|---|
| 한 묶음 안 (제목 ↔ 본문) | 8 ~ 12px |
| 같은 그룹 안 카드끼리 | 16 ~ 24px |
| 다른 그룹 사이 | 48 ~ 96px |
글자와 배경이 충분히 달라야 읽힌다.
"안 보여"의 절반은 대비 부족.
대비(contrast)는 두 색이 얼마나 다른지의 정도.
글자색과 배경색의 명도(밝기) 차이가 너무 작으면 글이 사라진다.
| 상황 | 최소 대비 |
|---|---|
| 본문 (작은 글) | 4.5 : 1 이상 |
| 큰 제목 (대략 24px 이상) | 3 : 1 이상 |
| 약한 대비 (회색 글자 on 흰색) | 대비 부족 — 본문에 못 씀 |
대비를 위계 도구로 쓰면
크기 안 키워도 강조가 된다.
제일 중요한 텍스트는 가장 진한 검정, 보조 정보는 옅은 회색.
크기 차이 없이도 시선의 순서를 만들 수 있다.
| 역할 | 색 |
|---|---|
| 본문·제목 (강한 정보) | #111 ~ #1a1a1a |
| 보조 텍스트 | #4a5568 |
| 메타·라벨 | #71717a |
| 비활성·플레이스홀더 | #a1a1aa |
색을 "회색", "파란색"이 아니라
역할 이름으로 부를 수 있다.
웬만한 디자인엔 색마다 역할 이름이 있다 — primary, ink, surface...
이름만 알면 "이 부분 색을 X로 바꿔달라"가 가능해진다.
| 이름 | 역할 |
|---|---|
| primary | 강조 — 주요 버튼, 링크, 활성 상태 |
| ink / ink-2 / ink-3 | 본문 검정 → 보조 회색 단계 |
| surface | 카드 배경 (보통 흰색) |
| bg | 페이지 배경 (옅은 회색) |
| border | 테두리·구분선 |
"여기 색 이상해"가 아니라
"이 부분 ink-3를 ink로 바꿔줘".
색을 바꾸고 싶을 때 디자이너처럼 "규칙"을 알 필요 없다.
현재 색의 이름과 바꿀 색의 이름만 알면 LLM이 알아서 처리.
| 증상 | 이렇게 요청 |
|---|---|
| 본문이 너무 옅어 | "본문을 ink로 진하게" |
| 강조가 약해 | "이 버튼을 primary로 강조" |
| 구분선 안 보여 | "border 색 한 단계 진하게" |
| 강조가 시끄러워 | "primary-soft로 옅게 바꿔" |
모서리 둥글기와 그림자가
"현대적"과 "올드함"을 가른다.
border-radius는 모서리 둥글기, box-shadow는 그림자.
둘 다 "강할수록 좋다"가 아니다 — 대부분의 UI에서는 옅은 쪽이 깔끔하다.
| 요소 | border-radius |
|---|---|
| 버튼 | 6 ~ 8px |
| 카드 | 8 ~ 12px |
| 태그·뱃지 | 999px (완전 둥근 pill) |
| 아바타·아이콘 | 50% (원형) |
그림자는 옅을수록 현대적.
짙으면 90년대 디자인이 된다.
box-shadow는 카드가 살짝 떠 있는 느낌을 준다.
보통 네 요소로 읽는다 — x-offset · y-offset · blur · color (색은 검정에 투명도).
| 강도 | 값 |
|---|---|
| 없음 (border만) | none |
| 옅게 (기본 카드) | 0 1px 2px rgba(0,0,0,.06) |
| 떠 있게 (호버·모달) | 0 4px 12px rgba(0,0,0,.08) |
| 금지 (올드) | 0 10px 30px rgba(0,0,0,.3) |
박스를 흐름대로 둘지
특정 자리에 고정할지 정한다.
기본적으로 박스는 위에서 아래로 흐름대로 쌓인다.
position으로 이 흐름을 깨고 특정 위치에 박을 수 있다.
| 값 | 의미 |
|---|---|
| static | 기본 — 위에서 아래로 흐름 |
| relative | 자기 자리 기준 미세 이동 |
| absolute | 가까운 position 지정 부모(보통 relative) 기준 — 뱃지·닫기 버튼 |
| fixed | 스크롤해도 화면에 고정 — 헤더·플로팅 버튼 |
| sticky | 스크롤하다 멈춤 — 섹션 헤더 |
px? rem? %?
상황에 맞는 단위를 골라야 한다.
고정값(px)과 상대값(rem · % · vw)의 차이만 알면 대부분의 크기 지시는 가능하다.
| 단위 | 언제 쓰나 |
|---|---|
| px | 고정 — border, 아이콘 |
| rem | 폰트·padding (권장) |
| % | 부모 기준 비율 |
| clamp() | 최소·기본·최대 한꺼번에 |
요소를 안 보이게 하는 3가지 방법.
각자 결과가 다르다.
"안 보이게 해줘"라고 시킬 때 결과는 셋 중 하나.
공간도 사라질지, 자리만 비울지, 클릭은 받을지를 구분해야 한다.
| 방법 | 결과 |
|---|---|
| display: none | 완전히 사라짐 — 공간도 없음, 클릭 불가 |
| visibility: hidden | 안 보이지만 공간은 차지 — 자리 유지 |
| opacity: 0 | 투명 — 안 보이지만 클릭은 가능 |
같은 박스에 여러 규칙이 충돌하면
더 구체적인 규칙이 이긴다.
LLM이 새 규칙을 추가했는데 안 먹는다면 —
기존에 더 점수가 높은 규칙이 이미 자리 잡고 있을 가능성.
| 선택자 | 점수 |
|---|---|
| inline (style="...") | 1000 — 일반 CSS보다 강함 |
| #id | 100 |
| .class · :hover | 10 |
| div · p (태그) | 1 |
| !important | 별도 규칙 — 위 점수 뒤집음 |
점수 무시하고 무조건 이기는 두 가지.
이걸 못 보면 영원히 안 바뀐다.
!important는 점수 시스템을 무시하고 무조건 이긴다.
inline style(HTML에 직접 박힌 style="...")도 마찬가지.
| 증상 | 확인할 것 |
|---|---|
| CSS 고쳐도 안 바뀜 | HTML에 inline style="..." 있는지 |
| 다른 규칙이 무조건 이김 | !important 있는지 grep |
| JS로 동적 적용 | element.style.xxx = "..." 있는지 |
<div style="...">. 일반 CSS보다 강함
코드는 분명 바꿨는데
브라우저가 옛날 파일을 보고 있다면.
CSS는 맞게 고쳤는데 화면이 그대로면 —
브라우저가 캐시를 보고 있거나, 빌드가 안 돌았을 가능성.
| 원인 | 해결 |
|---|---|
| 브라우저 캐시 | Cmd+Shift+R (하드 새로고침) |
| HMR 안 도는 상태 | dev server 재시작 |
| 빌드 산출물 안 갱신 | build 명령 실행 |
"LLM이 고쳤다는데 안 바뀜" —
이 순서대로 확인하면 90% 잡는다.
아래 순서대로 위에서 아래로 확인.
대부분 1~2번에서 해결된다.