2026. 7. 3. 14:58ㆍAI 기반 프론트엔드 웹개발자 양성과정

[CSS 3일차] 반응형 @media · CSS 변수 · 가상요소
+ CSS 리셋 · 미니 프로젝트 종합
2026.07.03 · 학습 범위: CSS 14번 ~ 20번
📋 오늘 다룬 것들
오늘은 CSS 로드맵의 마무리 구간이었다. 화면 폭에 반응하는 @media, 값을 한 곳에서 관리하는 CSS 변수, hover 시 떠오르는 그림자·전환 효과, HTML을 안 건드리고 장식을 붙이는 가상 요소, 작업 시작 전 필수인 CSS 리셋까지 훑고, 마지막엔 지금까지 배운 기법을 한 페이지에 모은 미니 프로젝트(프로필 카드)로 정리했다. 참고 사이트의 예제·설명도 함께 보며 개념을 다졌다.
🗂️ 항목별 메모
14 — 화면 크기별 스타일 (@media)
화면 폭에 따라 다른 CSS를 적용하는 게 @media다. 한 CSS 파일로 PC와 모바일을 동시에 대응하는 반응형의 핵심. 기본은 넓은 화면 기준으로 짜두고, @media (max-width: 600px) 안에 좁을 때만 덮어쓸 규칙을 넣는다. 오늘 예제는 카드 3개를 넓을 땐 가로(flex-direction: row), 좁을 땐 세로(column)로 전환했다.
/* 기본(넓은 화면): 카드를 가로로 나란히 */ .box { display: flex; flex-direction: row; /* 가로 배치 (왼→오) */ gap: 10px; } /* 폭 600px 이하일 때만 적용 (모바일) */ @media (max-width: 600px) { .box { flex-direction: column; } /* 세로로 쌓기 */ }
480px — 작은 모바일 / 768px — 태블릿 시작점(아이패드 세로) / 1024px — 데스크톱 시작점(아이패드 가로) / 1280px · 1440px — 큰 화면 대응. 브라우저 창을 줄였다 늘이며 가로↔세로 전환을 직접 확인하면 감이 잡힌다.
15 — CSS 변수 (custom properties · :root · var())
CSS 변수는 값에 이름표를 붙이는 것이다. 색·간격처럼 반복되는 값을 :root 안에 한 번 정의해두고, 여러 곳에서 var()로 꺼내 쓴다. 버튼 2개가 같은 --main-color를 쓰면, :root 한 줄만 고쳐도 둘 다 동시에 바뀐다 — 유지보수의 핵심.
/* :root = 문서 전체의 뿌리 → 어디서든 꺼내 쓸 수 있음 */ :root { --main-color: #ec4899; /* 이 한 줄만 고치면 전체 반영 */ --gap: 12px; } .btn { background: var(--main-color); } /* 버튼1·버튼2 같은 색 */ .row { gap: var(--gap); } /* 간격도 변수로 */
--main-color, --gap, --body-color는 전부 커스텀 프로퍼티(custom property), 즉 개발자가 이름을 직접 만든 변수다. CSS에 미리 정해진 속성이 아니다. 핵심 규칙은 딱 하나 — --(대시 두 개)로 시작하기만 하면 이름은 뭐든 원하는 대로 지을 수 있다. 실무에선 의미가 통하는 이름을 짓는 게 흔한데, 변수 이름만 봐도 "아, 이건 gap 속성에 쓸 값이구나" 하고 바로 이해되게 하기 위해서다.
--main-color 값 한 줄만 수정 → 사용처 전부 반영. (예: #2563eb로 바꿔보기)16 — 그림자·둥근모서리·전환 (box-shadow · border-radius · opacity · transition)
카드 하나에 효과 4종을 몰아넣고, transition으로 hover 시 부드럽게 반응하게 만들었다. 핵심은 transition 덕에 변화가 뚝딱이 아니라 스르륵 일어난다는 것. 숫자(0.3s · -8px · 16px)만 바꾸면 속도·높이·그림자 세기를 조절할 수 있다.
.card { border-radius: 16px; /* ① 모서리 둥글게 */ opacity: 0.85; /* ② 살짝 비치게 (1=불투명) */ box-shadow: 0 6px 18px rgba(0,0,0,.25); /* ③ x·y·번짐·색 */ transition: all 0.3s ease; /* ④ 바뀔 때 0.3초 스르륵 */ } /* 마우스 올리면 → 떠오르고 또렷해지고 그림자 커짐 */ .card:hover { opacity: 1; transform: translateY(-8px); /* 위로 8px 떠오름 */ box-shadow: 0 16px 32px rgba(255,105,180,.5); }
| 속성 | 역할 |
|---|---|
box-shadow | 그림자 — x축 y축 번짐 색 순서 |
border-radius | 모서리 둥글게 |
opacity | 투명도 (1=불투명, 0=완전 투명) |
transition | 값이 바뀔 때 부드럽게 전환 |
17 — 가짜 요소로 장식 추가 (::before · ::after)
HTML을 건드리지 않고 콘텐츠 앞(::before)과 뒤(::after)에 장식을 끼워 넣는 게 가상 요소다. 실제 DOM에는 없는 "가짜" 요소라, content 속성이 반드시 있어야 화면에 나타난다. 제목 앞 별(★), 인용문 양옆 따옴표, 글자 아래 밑줄 같은 순수 장식을 CSS만으로 붙일 수 있다.
/* 핵심: content 속성이 없으면 화면에 절대 안 나타남! */ .star-title::before { content: "★ "; color: gold; } /* 앞에 별 */ .quote::before { content: "“ "; } /* 인용 앞 따옴표 */ .quote::after { content: " ”"; } /* 인용 뒤 따옴표 */ /* 빈 content + 네모 박스 = 밑줄 장식 */ .underline-deco::after { content: ""; /* 빈 따옴표라도 꼭 있어야 보임 */ display: block; height: 4px; background: royalblue; }
<span>을 HTML에 넣지 않고 CSS 한 곳에서 처리HTML이 깔끔하게 유지되고(장식 태그가 안 늘어남), 한 줄만 고치면 같은 클래스 전체에 반영된다(유지보수 ↑). 별·따옴표는 "내용이 아니라서" 스크린리더가 읽지 않아 접근성에도 좋다. 예를 들어 필수 입력
* 표시는 라벨마다 <span>*</span>를 20번 반복하는 대신, class="required"만 붙이고 .required::after { content:" *"; } 한 줄로 끝낼 수 있다. 필수↔선택 전환도 class 추가·제거만으로 해결.
content로 넣지 말 것. 순수 장식(별·따옴표·밑줄·툴팁 꼬리)에만 사용한다.18 — CSS 리셋 (브라우저 기본 여백 없애기)
브라우저는 body·h1·p 등에 기본 여백을 미리 넣어둔다. 그래서 화면 가장자리에 흰 틈이 생기고, 브라우저마다 값도 조금씩 다르다. 작업 시작 전에 이 기본값을 0으로 초기화하는 걸 CSS 리셋이라 하고, 실무에선 거의 필수다.
/* styles/main.css 맨 위에 먼저 */ * { /* 모든 요소 (와일드카드) */ margin: 0; /* 기본 바깥 여백 제거 */ padding: 0; /* 기본 안쪽 여백 제거 */ box-sizing: border-box; /* 크기 계산 방식 변경 */ }
width: 100px; padding: 20px를 줬을 때:·
content-box(기본) → padding이 width에 더해짐. 실제 폭 = 100 + 20 + 20 = 140px (삐져나감)·
border-box → padding을 width 안에 포함. 실제 폭 = 100px 그대로 (계산 편함)border-box면 내가 정한
width가 최종 크기라 padding·border를 줘도 박스가 안 커져 레이아웃이 안 틀어진다. 그래서 리셋에 거의 항상 포함한다.
19 — 미니 프로젝트 (HTML + CSS 종합)
지금까지 배운 기법(선택자 · 박스모델 · flex · :hover · position · grid · @media · CSS 변수 · 효과 · 가상요소 · transform/transition · gradient)을 한 페이지에 모은 최종본. 상단 고정 바, NEW 배지가 붙은 소개, 3칸 카드 갤러리(좁히면 1칸), hover 시 떠오르는 카드로 구성한 프로필 페이지를 만들었다.
/* 변수 하나(--main)만 바꿔도 테마 전체가 바뀜 */ :root { --main: #ec4899; --gap: 12px; } .bar { position: sticky; top: 0; } /* 상단 고정 헤더 */ .grid { display: grid; grid-template-columns: repeat(3, 1fr); } .card:hover { transform: translateY(-6px) scale(1.04); } @media (max-width: 600px) { .grid { grid-template-columns: 1fr; } }
--main 색 바꿔 테마 전체 변경(예 #2563eb) ② 카드 <div> 더 추가 → grid 자동 배치 ③ 폭 줄여 @media 1칸 전환 확인 ④ transition·transform 값 조절 ⑤ ::before 별을 다른 이모지로 ⑥ animation으로 배지 깜빡이기
20 — CSS 참고 사이트
직접 만들기 전에 먼저 보면 좋은 레퍼런스도 정리했다. 복붙용 UI 부품과 살아 움직이는 데모를 모아둔 곳들이다.
F12(개발자도구)로 CSS를 뜯어보면 구조가 보인다.
✍️ 마치며
오늘로 CSS 기초 로드맵을 한 바퀴 다 돌았다. 특히 미니 프로젝트에서 그동안 따로따로 배운 기법들이 한 페이지 안에서 서로 맞물리는 걸 보니, 각 속성이 언제·왜 쓰이는지가 훨씬 선명해졌다. :root 변수 하나만 바꿔도 테마 전체가 확 바뀌는 순간이 가장 인상적이었다. 가상 요소나 CSS 리셋처럼 "HTML은 깔끔하게, 반복은 CSS 한 곳으로" 라는 감각도 오늘 확실히 잡혔다. 다음엔 참고 사이트의 부품들을 실제로 내 페이지에 이식해보며 응용해볼 생각이다.
🏷️ CSS | 반응형 | CSS변수 | 가상요소 | 학습일지 | 프론트엔드
'AI 기반 프론트엔드 웹개발자 양성과정' 카테고리의 다른 글
| [260707화 07일차] JavaScript (0) | 2026.07.08 |
|---|---|
| [260706월 06일차] Mini-Project, JavaScript (0) | 2026.07.06 |
| [260702목 04일차] CSS (0) | 2026.07.02 |
| [260701수 03일차] HTML & CSS (0) | 2026.07.01 |
| [260630화 02일차] HTML (0) | 2026.06.30 |