CSS 독학 가이드 9 - CSS 변수와 최신 기능
CSS가 프로그래밍 언어가 되어가고 있다
예전 CSS는 단순히 스타일만 지정했어요. 하지만 지금은 변수, 계산, 조건 처리까지 가능합니다. 거의 프로그래밍 언어 수준!
이런 기능들을 알면 코드 재사용성이 엄청 높아지고, 유지보수가 쉬워져요. 한 곳만 수정하면 전체가 바뀌거든요.
CSS 변수 (Custom Properties)
값을 변수에 저장하고 재사용할 수 있어요!
기본 문법
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--spacing: 1rem;
}
.button {
background: var(--primary-color);
padding: var(--spacing);
}
.link {
color: var(--primary-color);
}
실행 결과:
버튼과 링크가 같은 primary-color(#3498db)를 사용합니다
:root는 최상위 요소 (html과 동일)예요. 여기에 선언하면 전역 변수가 됩니다!
왜 좋은가?
이전 방식:
.button { background: #3498db; }
.link { color: #3498db; }
.badge { border: 1px solid #3498db; }
/* 색상 바꾸려면 모두 수정해야 함 */
CSS 변수 사용:
:root { --primary: #3498db; }
.button { background: var(--primary); }
.link { color: var(--primary); }
.badge { border: 1px solid var(--primary); }
/* :root만 수정하면 모두 변경! */
기본값 설정
.box {
color: var(--text-color, #333);
/* --text-color가 없으면 #333 사용 */
}
범위(Scope)
:root {
--spacing: 20px; /* 전역 */
}
.card {
--spacing: 10px; /* .card 안에서만 */
padding: var(--spacing); /* 10px */
}
.button {
padding: var(--spacing); /* 20px (전역 값) */
}
자식 요소는 부모의 변수를 상속받아요!
실전 예제: 테마 시스템
:root {
/* 색상 */
--color-primary: #3498db;
--color-secondary: #2ecc71;
--color-danger: #e74c3c;
--color-text: #333;
--color-bg: #ffffff;
/* 간격 */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 2rem;
--spacing-xl: 4rem;
/* 폰트 */
--font-size-sm: 0.875rem;
--font-size-md: 1rem;
--font-size-lg: 1.25rem;
--font-size-xl: 1.5rem;
/* 기타 */
--border-radius: 8px;
--box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* 다크 모드 */
:root.dark {
--color-text: #ffffff;
--color-bg: #1a1a1a;
}
// 테마 전환
document.documentElement.classList.toggle('dark');
calc() 함수
계산식을 사용할 수 있어요!
기본 사용법
.box {
width: calc(100% - 50px);
height: calc(100vh - 60px);
padding: calc(1rem + 10px);
}
실행 결과:
이 박스의 너비는 calc(100% - 50px)입니다
패딩은 calc(1rem + 10px)입니다
단위 섞어 쓰기 가능!
.container {
width: calc(100% - 2rem);
margin: calc(50px + 5%);
}
실전 예제
전체 화면 - 헤더/푸터 높이
:root {
--header-height: 60px;
--footer-height: 40px;
}
.content {
min-height: calc(100vh - var(--header-height) - var(--footer-height));
}
Grid 열 너비 계산
.grid {
display: grid;
grid-template-columns: calc(100% / 3) calc(100% / 3) calc(100% / 3);
gap: 20px;
}
반응형 폰트 크기
h1 {
font-size: calc(1.5rem + 1vw);
/* 기본 1.5rem + 화면 너비 1% */
}
clamp() 함수 ⭐ 반응형의 핵심
최소값, 이상적 값, 최대값을 지정해요.
.box {
font-size: clamp(16px, 5vw, 32px);
/* 최소 16px, 이상적 5vw, 최대 32px */
}
미디어 쿼리 없는 반응형!
/* 이전 방식 */
.title {
font-size: 1.5rem;
}
@media (min-width: 768px) {
.title {
font-size: 2rem;
}
}
@media (min-width: 1024px) {
.title {
font-size: 2.5rem;
}
}
/* clamp 사용 */
.title {
font-size: clamp(1.5rem, 4vw, 2.5rem);
}
훨씬 간단하죠!
실전 예제: 반응형 컨테이너
.container {
width: clamp(300px, 90%, 1200px);
padding: clamp(1rem, 5vw, 3rem);
}
모바일(300px)부터 데스크톱(1200px)까지 자동 대응!
min() / max() 함수
둘 중 작은/큰 값을 선택해요.
/* 둘 중 작은 값 */
.box {
width: min(90%, 1200px);
/* 90% 또는 1200px 중 작은 값 */
}
/* 둘 중 큰 값 */
.box {
height: max(200px, 50vh);
/* 200px 또는 50vh 중 큰 값 */
}
aspect-ratio (최신 기능)
가로세로 비율을 쉽게 유지해요!
.video {
width: 100%;
aspect-ratio: 16 / 9;
/* 가로세로 16:9 비율 유지 */
}
.square {
aspect-ratio: 1 / 1;
/* 정사각형 */
}
.portrait {
aspect-ratio: 3 / 4;
/* 세로가 더 긴 비율 */
}
이전에는 padding 트릭을 썼어요:
/* 예전 방식 (복잡) */
.video {
position: relative;
padding-bottom: 56.25%; /* 16:9 = 9/16 = 56.25% */
}
/* 지금 (간단) */
.video {
aspect-ratio: 16 / 9;
}
object-fit (이미지 맞춤)
이미지를 박스에 어떻게 맞출지 지정해요.
.thumbnail {
width: 300px;
height: 200px;
object-fit: cover; /* 비율 유지, 잘라서 채움 */
}
옵션:
cover: 잘라서라도 채움 (가장 많이 씀)contain: 전체가 보이게 축소fill: 늘려서 채움 (비율 깨짐)none: 원본 크기 유지scale-down: contain과 none 중 작은 것
/* 프로필 사진 */
.avatar {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
}
/* 제품 이미지 */
.product-img {
width: 100%;
aspect-ratio: 1 / 1;
object-fit: cover;
}
filter (이미지 효과)
CSS만으로 포토샵 효과!
img {
filter: grayscale(100%); /* 흑백 */
filter: blur(5px); /* 흐림 */
filter: brightness(1.5); /* 밝기 */
filter: contrast(1.2); /* 대비 */
filter: saturate(0.5); /* 채도 */
filter: hue-rotate(90deg); /* 색조 */
filter: sepia(100%); /* 세피아 */
filter: invert(100%); /* 반전 */
}
/* 여러 효과 조합 */
img {
filter: grayscale(50%) brightness(1.2) contrast(1.1);
}
실전 예제: 호버 효과
.image {
filter: grayscale(100%);
transition: filter 0.3s;
}
.image:hover {
filter: grayscale(0%);
}
backdrop-filter (배경 흐림)
뒤의 배경을 흐리게!
.modal {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
}
.glass-card {
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(20px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.3);
}
“유리 효과(Glassmorphism)” 트렌드!
scroll-snap (스크롤 스냅)
스크롤이 특정 위치에 딱 맞춰져요.
.container {
scroll-snap-type: y mandatory;
/* 세로 방향, 강제 스냅 */
overflow-y: scroll;
height: 100vh;
}
.section {
scroll-snap-align: start;
/* 각 섹션의 시작 지점에 스냅 */
height: 100vh;
}
가로 스크롤 갤러리:
.gallery {
display: flex;
overflow-x: scroll;
scroll-snap-type: x mandatory;
gap: 20px;
}
.gallery img {
scroll-snap-align: center;
width: 300px;
flex-shrink: 0;
}
CSS 논리 속성 (Logical Properties)
다국어 지원에 유용해요. (왼쪽→오른쪽 vs 오른쪽→왼쪽)
/* 물리적 속성 (이전) */
.box {
margin-left: 20px;
padding-right: 10px;
}
/* 논리적 속성 (최신) */
.box {
margin-inline-start: 20px; /* 시작 방향 */
padding-inline-end: 10px; /* 끝 방향 */
}
영어는 왼쪽이 시작, 아랍어는 오른쪽이 시작! 논리 속성을 쓰면 자동 대응.
주요 매핑:
margin-left→margin-inline-startmargin-right→margin-inline-endmargin-top→margin-block-startmargin-bottom→margin-block-end
실전 종합 예제
:root {
/* 색상 변수 */
--color-primary: hsl(220, 90%, 56%);
--color-bg: hsl(0, 0%, 100%);
--color-text: hsl(0, 0%, 20%);
/* 간격 */
--spacing-unit: clamp(0.5rem, 2vw, 1rem);
/* 반응형 폰트 */
--font-size-base: clamp(1rem, 2.5vw, 1.25rem);
--font-size-heading: clamp(1.5rem, 5vw, 3rem);
}
.container {
max-width: min(90%, 1200px);
margin: 0 auto;
padding: calc(var(--spacing-unit) * 2);
}
h1 {
font-size: var(--font-size-heading);
color: var(--color-primary);
}
.card {
aspect-ratio: 16 / 9;
background: var(--color-bg);
border-radius: calc(var(--spacing-unit) / 2);
padding: var(--spacing-unit);
filter: drop-shadow(0 2px 8px rgba(0,0,0,0.1));
}
.card img {
width: 100%;
height: 100%;
object-fit: cover;
}
@media (prefers-color-scheme: dark) {
:root {
--color-bg: hsl(0, 0%, 10%);
--color-text: hsl(0, 0%, 90%);
}
}
다음 단계
CSS 변수와 최신 기능을 마스터했으니 이제 실전 프로젝트를 만들 차례예요! 지금까지 배운 모든 것을 종합해서 완성도 높은 웹페이지를 만들어봅시다.
마지막 글에서는 포트폴리오 사이트, 랜딩 페이지, 대시보드 등 실전 프로젝트를 처음부터 끝까지 만들 거예요!
실습 과제:
- CSS 변수로 테마 시스템 만들기 (라이트/다크 모드)
- clamp()로 미디어 쿼리 없는 반응형 타이포그래피 만들기
- aspect-ratio로 YouTube 비디오 embed 만들기
- backdrop-filter로 유리 효과 카드 만들기
CSS는 이제 단순한 스타일 언어를 넘어 강력한 도구가 되었어요!
시리즈 네비게이션
- 이전글: CSS 독학 가이드 - 고급 선택자와 가상 요소
- 현재글: CSS 독학 가이드 - CSS 변수와 최신 기능
- 다음글: CSS 독학 가이드 - 실전 프로젝트