0) CSS란
Cascading Style Sheets.
HTML 같은 문서의 보이는 모습(색, 글꼴, 배치, 애니메이션)을 정의한다. “Cascading(캐스케이드)”는 충돌 시 누가 이기나를 정하는 규칙 (!important → 레이어 → 특정성 → 소스 순서).
기본 문법(한 줄 요약)
/* 선택자 */ /* 선언블록 */
button.primary { /* ← 규칙(rule) */
color: white; /* 속성: 값; */
background: #4f46e5;
}
/* 주석은 이렇게 */
선택자(무엇에 적용할지)
- 태그: h1, p
- 클래스: .card, .btn.primary
- 아이디: #app
- 속성: [type="email"]
- 조합자: .nav > li(자식), .item + .item(인접 형제), .a .b(후손)
- 가상 클래스: :hover, :focus, :disabled, :nth-child(2n)
- 가상 요소: ::before, ::after
1) CSS의 토대: 박스·상속·캐스케이드
모든 요소는 박스(Box Model): content + padding + border + margin.
레이아웃 멘탈모델은 항상 “박스가 쌓인다”.
* { box-sizing: border-box; } /* 패딩/보더 포함한 크기 계산: 실무 표준 */
상속(Inheritance): 글꼴·색상 등은 보통 상속, 레이아웃 속성은 상속 안 됨.
헷갈리면 DevTools의 “Computed” 탭에서 확인.
캐스케이드(Cascade): “어디서, 어떤 선택자로, 어떤 순서에 적었나”가 최종 스타일을 결정.
우선순위: 인라인 스타일 > #id > .class/속성/가상클래스 > 태그 > *
나중에 나온 규칙이 이긴다(같은 특정성일 때).
정말 급할 때만 !important 사용하기
2) 레이아웃 기본기: 흐름·포지셔닝·Flex·Grid
노멀 플로우
- block은 세로로, inline은 가로로 흐른다. 가능한 한 기본 흐름을 존중하면 버그가 준다.
포지셔닝
- position: relative(기준점), absolute(문서 흐름 이탈), fixed(뷰포트 고정), sticky(스크롤 고정).
- z-index는 스태킹 컨텍스트를 만든 속성들(position + z-index, opacity<1, transform, filter, will-change 등)에 종속됨.
Flexbox (1차원 레이아웃): 가로 또는 세로 한 축 정렬/분배에 최적.
.row {
display: flex; gap: 12px;
justify-content: space-between; /* 가로 정렬 */
align-items: center; /* 세로 정렬 */
}
Grid (2차원 레이아웃): 행·열을 동시에 설계.
.grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 16px;
}
float(요소를 띄워서 특정 위치에 위치시킬 때 사용하는 속성)은 레거시. 이미지 주변 텍스트 흐름 등 특수한 경우에만.
3) 단위와 크기: 유연하게, 안전하게
px(고정), %(부모 기준), em/rem(폰트 기준), vw/vh(뷰포트),
fr(Grid 비율), minmax(), clamp()(최소이상적최대)
html { font-size: 16px; }
h1 { font-size: clamp(1.5rem, 2vw + 1rem, 2.5rem); } /* 유동 타이포 */
.col { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
모던 뷰포트 단위: svh/lvh/dvh(모바일 브라우저 UI 변화 대응).
4) 선택자·가상 클래스/요소: 정확하게 집기
기본 선택자: 태그, 클래스 .btn, 아이디 #app, 속성 [type="email"].
가상 클래스: :hover, :focus, :active, :disabled, :focus-visible(접근성 최고), :nth-child().
가상 요소: ::before, ::after(장식/뱃지/아이콘 붙이기).
※ 도움 되는 최신 문법
:is() 그룹화(특정성 Specificity=가장 구체적인 것):
.card :is(h1, h2, h3) { … }
:where()(특정성 0, 안전한 래핑):
:where(.prose) h2 { margin: 0; }
:has()(부모 선택자, 최신 브라우저에서 실사용 가능):
.field:has(input:invalid) { outline: 2px solid red; }
5) 색·타이포·그래픽
- 색상: #hex, rgb(), hsl() + 투명도 hsla(). 최신엔 lab(), lch()도 등장(광색역).
- 폰트: line-height는 단위 없이(비율) 쓰면 상속·반응형에 유리.
- 아이콘: 가상요소+mask/background로도 가능.
- 효과: border-radius, box-shadow, filter, backdrop-filter.
6) 반응형·적응형: 모던 CSS 루틴
모바일 퍼스트: 기본 스타일을 모바일로 두고, 넓어질수록 확장.
.wrap { padding: 16px; }
@media (min-width: 768px) { .wrap { padding: 24px; } }
@media (min-width: 1200px){ .wrap { padding: 32px; } }
컨테이너 쿼리(요소 너비 기준 반응형):
.card { container-type: inline-size; }
@container (min-width: 40rem) { .card .meta { display: grid; } }
리듀스 모션/다크 모드
@media (prefers-reduced-motion: reduce) { * { animation: none; } }
@media (prefers-color-scheme: dark) { :root { color-scheme: dark; } }
prefers-reduced-motion: reduce 란?
“내 장치에서 과한 움직임(애니메이션)을 줄여줘!”라고 설정한 사용자에게, 웹이 덜 움직이도록 만들어주는 CSS 미디어쿼리. 멀미/현기증을 유발할 수 있는 패럴랙스, 큰 슬라이드 전환, 자동 스크롤 같은 걸 줄이거나 끄는 데 쓰임. 접근성(멀미·주의집중·발작 유발 방지) + 성능/배터리에 이득임.
7) 모던 문법: 변수·레이어·네스팅
CSS 변수(커스텀 프로퍼티): 테마·다크모드·디자인트큰 핵심.
:root { --brand: hsl(260 90% 60%); }
.btn { background: var(--brand); }
@layer(캐스케이드 레이어): “베이스→컴포넌트→유틸리티” 순서 제어.
@layer base, components, utilities;
@layer base { *{box-sizing:border-box} }
@layer components { .card{padding:1rem} }
@layer utilities { .mt-2{margin-top:.5rem} }
네이티브 네스팅(현대 브라우저 지원 확산 중):
.card {
padding: 1rem;
& > h3 { margin: 0; } /* .card > h3 */
&:hover { transform: translateY(-2px); } /* .card:hover */
}
선택자 흐름을 계층식으로 읽기 편하게 해주는 문법 설탕
8) 애니메이션·트랜지션: 과유불급
트랜지션: 상태 변화 부드럽게.
.btn { transition: transform .2s ease, box-shadow .2s; }
.btn:hover { transform: translateY(-1px); }
키프레임 애니메이션: 짧고 가벼운 것만, prefers-reduced-motion 고려.
키프레임 애니메이션이란? 시간축(타임라인)에 스타일의 ‘중간 지점(keyframes)’을 정의하고, 그 사이 값을 브라우저가 자동으로 보간해 움직임을 만드는 방식. @keyframes로 애니메이션 이름과 단계(%, from/to)를 정하고, 요소에 animation으로 적용함.
@keyframes pop {
from { transform: scale(0.9); opacity: 0; }
60% { transform: scale(1.05); }
to { transform: scale(1); opacity: 1; }
}
.card { animation: pop .6s ease-out both; }
9) 아키텍처·유지보수: 팀이 편해야 진짜 실력
- 네이밍·구조: BEM(.btn--primary), 컴포넌트 단위 스타일, 디자인 토큰(색/간격/폰트 스케일).
- 유틸리티와 컴포넌트의 균형: 유틸리티(원자 클래스)로 속도, 컴포넌트로 의미와 재사용.
- 리셋/노멀라이즈: @layer base에서 최소한의 초기화. { all: unset/revert }는 “원복 스위치”로 유용.
- 호환성 전략: @supports로 점진적 개선(폴리필보다 깔끔).
/* 1) 안전한 기본값 */
.card {
background: rgba(255,255,255,.85);
}
/* 2) 지원되면 강화 */
@supports (backdrop-filter: blur(10px)) or (-webkit-backdrop-filter: blur(10px)) {
.card {
background: rgba(255,255,255,.6);
backdrop-filter: blur(10px);
}
}
10) 성능·디버깅 습관
- 과도한 후손 선택자 지양: .a .b .c 깊어질수록 느려지고 충돌 많아짐.
- 페인트 최적화: 변환/불투명도 위주로 애니메이션(transform, opacity).
- 컨테인먼트: 큰 컴포넌트에 contain: content;로 영향 범위 차단.
- DevTools: 레이아웃/그리드 오버레이, 계산된 스타일, 스태킹 컨텍스트 보기.
11) 자주 쓰는 레시피 모음
/* 가운데 정렬 카드 */
.center {
min-height: 100svh;
display: grid;
place-items: center;
}
/* 반응형 카드 그리드 */
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
gap: 1rem;
}
/* 접근성 있는 포커스 */
:focus-visible {
outline: 2px solid hsl(220 90% 60%);
outline-offset: 2px;
}
/* 유동 타이포 스케일 */
:root { --scale: clamp(1rem, 1rem + 1vw, 1.25rem); }
body { font-size: var(--scale); }
/* 이미지 비율 유지 박스 */
.thumb { aspect-ratio: 16 / 9; object-fit: cover; }
'Front-End > CSS' 카테고리의 다른 글
CSS 아키텍쳐와 BEM (0) | 2025.04.27 |
---|