Media Query ํบ์๋ณด๊ธฐ! ๐
CSS Media Query๋ ๋ฐ์ํ ์น ๋์์ธ(Responsive Web Design)์ ํต์ฌ ๋๊ตฌ์ ๋๋ค. ๋ค์ํ ๋๋ฐ์ด์ค์ ํ๋ฉด ํฌ๊ธฐ์์ ์ต์ ์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ค๋ฉด Media Query๋ฅผ ๊ผญ ์์์ผ ํด์! ๐ฏ
Media Query๋? ๐
Media Query๋ CSS3์์ ๋์ ๋ ๊ธฐ๋ฅ์ผ๋ก,ํน์ ์กฐ๊ฑด(ํ๋ฉด ํฌ๊ธฐ, ํด์๋, ์์ ๊น์ด, ๋๋ฐ์ด์ค ํ์ , ๋๋ฐ์ด์ค ๋ฐฉํฅ ๋ฑ)์ ๋ฐ๋ผ CSS ์คํ์ผ์ ์กฐ๊ฑด๋ถ๋ก ์ ์ฉํ๋ ๊ท์น์ด์์. ํ๋ฉด์ด ์ข์์ง์๋ก ๋์์ธ์ด ๊นจ์ง์ง ์๊ณ ์์ฐ์ค๋ฝ๊ฒ ๋ณ๊ฒฝ๋๋๋ก ๋์์ค๋๋ค.
/* ๊ธฐ๋ณธ ์คํ์ผ */
body {
background-color: lightblue;
}
/* ํ๋ฉด ๋๋น๊ฐ 768px ์ดํ์ผ ๋ ์ ์ฉ */
@media (max-width: 768px) {
body {
background-color: lightcoral;
}
}
๐ ํ๋ฉด ํฌ๊ธฐ๊ฐ 768px ์ดํ๋ก ์ค์ด๋ค๋ฉด ๋ฐฐ๊ฒฝ์์ด ํ๋์์์ ๋นจ๊ฐ์์ผ๋ก ๋ฐ๋๋๋ค!
Media Query ๊ธฐ๋ณธ ๋ฌธ๋ฒ ๐ป
Media Query๋ @media ํค์๋๋ฅผ ์ฌ์ฉํด ์์ฑํฉ๋๋ค.
@media (์กฐ๊ฑด) {
/* ์กฐ๊ฑด์ด ์ฐธ์ผ ๋ ์ ์ฉํ ์คํ์ผ */
}
์กฐ๊ฑด ์ ํ
- max-width / min-width: ํ๋ฉด ๋๋น๋ฅผ ๊ธฐ์ค์ผ๋ก ์กฐ๊ฑด ์ค์
- max-height / min-height: ํ๋ฉด ๋์ด๋ฅผ ๊ธฐ์ค์ผ๋ก ์กฐ๊ฑด ์ค์
- aspect-ratio: ํ๋ฉด์ ๊ฐ๋ก์ธ๋ก ๋น์จ
- resolution: ํ๋ฉด์ ํด์๋
- orientation: ํ๋ฉด ๋ฐฉํฅ (์ธ๋ก/๊ฐ๋ก)
์์ : ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
1. ํ๋ฉด ๋๋น์ ๋ฐ๋ฅธ ์คํ์ผ: width / height
- max-width: ํ๋ฉด์ ์ต๋ ๋๋น
- min-width: ํ๋ฉด์ ์ต์ ๋๋น.
/* ๊ธฐ๋ณธ ์คํ์ผ */
h1 {
font-size: 24px;
}
/* ํ๋ฉด ๋๋น๊ฐ 600px ์ดํ์ผ ๋ */
@media (max-width: 600px) {
h1 {
font-size: 18px;
}
}
๐ ํ๋ฉด์ด ์ข์์ง๋ฉด ๊ธ์ ํฌ๊ธฐ๋ฅผ ์ค์ ๋๋ค.
2. ์ธ๋ก/๊ฐ๋ก ๋ฐฉํฅ์ ๋ฐ๋ผ ์คํ์ผ ๋ณ๊ฒฝ: orientation (๋๋ฐ์ด์ค ๋ฐฉํฅ)
- portrait: ์ธ๋ก ๋ชจ๋
- landscape: ๊ฐ๋ก ๋ชจ๋
@media (orientation: portrait) {
body {
background-color: lightgreen;
}
}
@media (orientation: landscape) {
body {
background-color: lightblue;
}
}
๐ ํ๋ฉด ๊ฐ๋ก ์ธ๋ก ๋ชจ๋์ ๋ฐ๋ผ ๋ฐฐ๊ฒฝ ์๊น์ด ๋ฌ๋ผ์ง
3. ๊ณ ํด์๋ ๋๋ฐ์ด์ค ์คํ์ผ๋ง: resolution (ํด์๋)
- min-resolution: ์ต์ ํด์๋
- max-resolution: ์ต๋ ํด์๋
@media (min-resolution: 2dppx) {
img {
content: url('high-resolution.png');
}
}
๐ Retina ๋์คํ๋ ์ด๋ ๊ณ ํด์๋ ํ๋ฉด์์ ์ ๋ช ํ ์ด๋ฏธ์ง๋ฅผ ์ ๊ณตํ๋ ค๋ฉด resolution ์กฐ๊ฑด์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
4. ๊ฐ๋ก ์ธ๋ก ๋น์จ: aspect-ratio
@media (aspect-ratio: 16/9) {
.video-container {
width: 100%;
}
}
๐ ๋๋ฐ์ด์ค ํ๋ฉด์ ๊ฐ๋ก ์ธ๋ก ๋น์จ์ ๊ธฐ์ค์ผ๋ก ์คํ์ผ์ ์ ์ฉ
Media Query์์ ์ฌ์ฉ๋๋ ๋ ผ๋ฆฌ ์ฐ์ฐ์ ๐
1. and (์กฐ๊ฑด์ด ๋ชจ๋ ์ฐธ์ผ ๋)
@media (min-width: 600px) and (max-width: 1200px) {
body {
font-size: 16px;
}
}
2. or (์กฐ๊ฑด ์ค ํ๋๋ผ๋ ์ฐธ์ผ ๋, ํค์๋ ,๋ก ํํ)
@media (max-width: 600px), (orientation: portrait) {
body {
background-color: lightcoral;
}
}
3. not (์กฐ๊ฑด์ ๋ถ์ )
@media not (max-width: 600px) {
body {
font-size: 18px;
}
}
4. only (ํด๋น ์กฐ๊ฑด์๋ง ์ ์ฉ)
@media only screen and (max-width: 600px) {
body {
background-color: lavender;
}
}
Media Query ์ค์ ์์ ๐ผ๏ธ
1. Mobile First ๋์์ธ ์ ๋ต
๋ชจ๋ฐ์ผ ์ฐ์ ์ ๋ต์ ๊ธฐ๋ณธ ์คํ์ผ์ ๋ชจ๋ฐ์ผ ์ค์ฌ์ผ๋ก ์์ฑํ๊ณ , ๋ ํฐ ํ๋ฉด์ ์ํ ์คํ์ผ์ Media Query๋ก ์ถ๊ฐํ๋ ๋ฐฉ์์ ๋๋ค.
/* ๊ธฐ๋ณธ ์คํ์ผ (๋ชจ๋ฐ์ผ ์ฐ์ ) */
body {
font-size: 14px;
}
/* ํ๋ธ๋ฆฟ */
@media (min-width: 768px) {
body {
font-size: 16px;
}
}
/* ๋ฐ์คํฌํฑ */
@media (min-width: 1024px) {
body {
font-size: 18px;
}
}
2. Grid ๋ ์ด์์์ Media Query ์ ์ฉ
.container {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
@media (min-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.container {
grid-template-columns: repeat(4, 1fr);
}
}
3. ์ด๋ฏธ์ง ๋ฐ์ํ ์ฒ๋ฆฌ
img {
width: 100%;
height: auto;
}
@media (min-width: 768px) {
img {
width: 50%;
}
}
4. ๋คํฌ ๋ชจ๋ ๊ตฌํํ๊ธฐ
๋คํฌ ๋ชจ๋๋ ํ๋ ์น์ฌ์ดํธ์์ ํ์์ฃ . Media Query๋ก ๊ฐ๋จํ ๊ตฌํํ ์ ์์ด์.
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
color: #ffffff;
}
}
@media (prefers-color-scheme: light) {
body {
background-color: #ffffff;
color: #000000;
}
}
5. ๋ฐ์ํ ๋ค๋น๊ฒ์ด์ ๊ตฌํํ๊ธฐ
ํ๋ฉด ํฌ๊ธฐ์ ๋ฐ๋ผ ๋ค๋น๊ฒ์ด์ ์ ๋ณ๊ฒฝํ๋ ์์ ์ ๋๋ค.
/* ๊ธฐ๋ณธ ์คํ์ผ */
nav {
display: flex;
}
/* ํ๋ฉด์ด ์ข์์ง๋ฉด ๋ค๋น๊ฒ์ด์
์จ๊ธฐ๊ธฐ */
@media (max-width: 768px) {
nav {
display: none;
}
}
CSS-in-JS์์ Media Query ์ฌ์ฉ ๐
React ์คํ์ผ๋ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์๋ Media Query๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค.
Styled-Components
import styled from "styled-components";
const Container = styled.div`
font-size: 14px;
@media (min-width: 768px) {
font-size: 16px;
}
@media (min-width: 1024px) {
font-size: 18px;
}
`;
export default function App() {
return <Container>Hello, Media Query!</Container>;
}
Emotion
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
const containerStyle = css`
font-size: 14px;
@media (min-width: 768px) {
font-size: 16px;
}
@media (min-width: 1024px) {
font-size: 18px;
}
`;
export default function App() {
return <div css={containerStyle}>Hello, Media Query!</div>;
}
Media Query ์ฌ์ฉ ์ ์ฃผ์์ฌํญ ๐๏ธ
- ํ ์คํธ ํ์: ๋ค์ํ ๋๋ฐ์ด์ค์ ํ๋ฉด ํฌ๊ธฐ์์ ํ ์คํธํ์ธ์.
- ์กฐ๊ฑด ์ค๋ณต ์ฃผ์: min-width์ max-width ์กฐ๊ฑด์ด ๊ฒน์น์ง ์๋๋ก ์ค์
- ์ฑ๋ฅ ์ต์ ํ: ๋๋ฌด ๋ง์ Media Query๋ฅผ ์ฌ์ฉํ๋ฉด CSS ํ์ผ์ด ๋ณต์กํด์ง ์ ์์ด์.
๊ฒฐ๋ก : ๋ฐ์ํ ๋์์ธ์ Media Query๋ก! ๐
Media Query๋ ํ๋ ์น์์ ๋ค์ํ ๋๋ฐ์ด์ค๋ฅผ ์ง์ํ๋ ๋ฐ ํ์์ ์ธ ๋๊ตฌ์ ๋๋ค. ์ ๋๋ก ์ดํดํ๊ณ ํ์ฉํ๋ฉด ์๋ฆ๋ต๊ณ ์ ์ฐํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ด์. ์ง๊ธ ๋น์ฅ ์ฌ๋ฌ๋ถ์ ํ๋ก์ ํธ์ Media Query๋ฅผ ์ ์ฉํด๋ณด์ธ์!
๐ท์ ์ค์ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ด ์๋น! ๐ท