--- id: wiki-2026-0508-미디어-쿼리-media-queries title: 미디어 쿼리(Media Queries) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Media Queries, Responsive Design, MQ Level 4, MQ Level 5] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [css, responsive, web, accessibility] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: css framework: web-platform --- # 미디어 쿼리(Media Queries) ## 매 한 줄 > **"매 viewport-level 의 conditional CSS"**. Media Queries 매 device/viewport feature (width, color-scheme, motion preference) 의 의해 stylesheet 의 적용 의 toggle. 매 2026 의 Container Queries 의 등장 의 component-level 의 위임 — MQ 매 page-level (theme, layout shift, accessibility) 의 책임 만 유지. ## 매 핵심 ### 매 query type - **width/height**: viewport 의 dimension (`min-width`, `max-width`). - **orientation**: `portrait` / `landscape`. - **resolution**: `min-resolution: 2dppx` (retina). - **user preference**: `prefers-color-scheme`, `prefers-reduced-motion`, `prefers-contrast`. - **interaction**: `hover`, `pointer: fine|coarse`. ### 매 modern syntax (Level 4+) - Range syntax: `(width >= 768px)` (vs legacy `min-width: 768px`). - Logical: `and`, `or`, `not`. - Nested 의 native CSS nesting 의 결합. ### 매 응용 1. Theme toggle — `prefers-color-scheme: dark`. 2. Accessibility — `prefers-reduced-motion: reduce`. 3. Page-level breakpoint — header, sidebar 의 layout shift. ## 💻 패턴 ### Mobile-first breakpoints (range syntax) ```css /* base = mobile */ .container { padding: 1rem; } @media (width >= 640px) { .container { padding: 1.5rem; max-width: 640px; margin-inline: auto; } } @media (width >= 1024px) { .container { max-width: 1024px; padding: 2rem; } } @media (width >= 1440px) { .container { max-width: 1280px; } } ``` ### Dark mode (system preference) ```css :root { --bg: white; --fg: #111; } @media (prefers-color-scheme: dark) { :root { --bg: #0a0a0a; --fg: #f5f5f5; } } body { background: var(--bg); color: var(--fg); } ``` ### Reduced motion (a11y mandatory) ```css .fade { transition: opacity 300ms ease; } .spin { animation: rotate 2s linear infinite; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } ``` ### Hover-capable device 만 hover effect ```css .card { transform: scale(1); transition: transform 200ms; } @media (hover: hover) and (pointer: fine) { .card:hover { transform: scale(1.03); } } /* 매 touch device 매 hover state 의 stuck 회피 */ ``` ### High-DPI / retina assets ```css .logo { background-image: url('/logo.png'); } @media (min-resolution: 2dppx) { .logo { background-image: url('/logo@2x.png'); background-size: contain; } } /* 또는 image-set() 의 modern alternative */ .logo { background-image: image-set( url('/logo.png') 1x, url('/logo@2x.png') 2x, url('/logo.avif') type('image/avif') 2x ); } ``` ### CSS nesting + MQ (modern) ```css .header { padding: 1rem; display: flex; flex-direction: column; @media (width >= 768px) { flex-direction: row; padding: 1.5rem 2rem; & .nav { margin-inline-start: auto; } } } ``` ### Accessibility: prefers-contrast ```css :root { --border: rgba(0, 0, 0, 0.1); } @media (prefers-contrast: more) { :root { --border: #000; } button { outline: 2px solid currentColor; } } ``` ### MQ vs Container Query 의 분리 ```css /* 매 page-level — MQ */ @media (width >= 1024px) { .layout { grid-template-columns: 240px 1fr; } } /* 매 component-level — CQ (NOT MQ) */ .card { container-type: inline-size; } @container (width >= 400px) { .card .title { font-size: 1.25rem; } } ``` ### JS 의 MQ matchMedia ```javascript const mq = window.matchMedia('(prefers-color-scheme: dark)'); mq.addEventListener('change', (e) => { document.documentElement.dataset.theme = e.matches ? 'dark' : 'light'; }); // initial document.documentElement.dataset.theme = mq.matches ? 'dark' : 'light'; ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Component 의 own-size adapt | Container Query (NOT MQ) | | Page-level layout shift | Media Query (`width >= 1024px`) | | Theme toggle | `prefers-color-scheme` + manual override | | A11y motion | `prefers-reduced-motion: reduce` (의무) | | Touch vs mouse | `(hover: hover) and (pointer: fine)` | | High-DPI image | `image-set()` > `min-resolution` MQ | **기본값**: page-level layout/theme/a11y → MQ. Component reflow → Container Query. ## 🔗 Graph - 부모: [[CSS_Architecture_and_Styling|CSS Architecture]] · [[Responsive Web Design]] - 변형: [[컨테이너 쿼리 (Container Queries)|Container Queries]] - 응용: [[Mobile-First Design]] ## 🤖 LLM 활용 **언제**: page-level breakpoint, theme switching, a11y compliance, retina asset switching. **언제 X**: component-internal reflow — Container Query 의 사용. 매 MQ 의 component coupling 의 anti-pattern. ## ❌ 안티패턴 - **Component sizing 의 MQ 사용**: viewport 의 의존 — Container Query 로 마이그레이션. - **Desktop-first**: max-width cascade 의 복잡 — mobile-first 의 추천. - **prefers-reduced-motion 의 무시**: WCAG 2.1 위반. - **Hover 의 모든 device**: touch 의 stuck hover state. - **legacy `min-width`/`max-width` 의 mix**: range syntax `>=`/`<=` 의 통일. ## 🧪 검증 / 중복 - Verified (MDN Media Queries, CSS MQ Level 4/5 spec, web.dev responsive design). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — MQ Level 4 range syntax + CQ 분리 |