강의 내용
1. 미디어 쿼리 (@media)
다양한 디바이스와 화면 크기에 맞춰 스타일을 조정하는 방법을 학습합니다.
기본 미디어 쿼리
/* 모바일 우선 (Mobile First) */
.container {
width: 100%;
padding: 10px;
}
/* 태블릿 이상 */
@media (min-width: 768px) {
.container {
max-width: 750px;
margin: 0 auto;
padding: 20px;
}
}
/* 데스크톱 이상 */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
}
}
/* 인쇄용 */
@media print {
.no-print {
display: none;
}
body {
font-size: 12pt;
color: black;
}
}
반응형 네비게이션
/* 데스크톱 네비게이션 */
.nav-menu {
display: flex;
list-style: none;
gap: 2rem;
}
.nav-toggle {
display: none;
}
/* 모바일 네비게이션 */
@media (max-width: 768px) {
.nav-menu {
position: fixed;
top: 70px;
left: -100%;
flex-direction: column;
background: white;
width: 100%;
transition: left 0.3s ease;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.nav-menu.active {
left: 0;
}
.nav-toggle {
display: block;
}
}
2. CSS 애니메이션
@keyframes를 사용하여 복잡한 애니메이션을 만들어봅시다.
기본 애니메이션
/* 키프레임 정의 */
@keyframes slideIn {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
/* 애니메이션 적용 */
.slide-in {
animation: slideIn 0.5s ease-out;
}
/* 복잡한 애니메이션 */
@keyframes bounce {
0% { transform: translateY(0); }
25% { transform: translateY(-20px); }
50% { transform: translateY(0); }
75% { transform: translateY(-10px); }
100% { transform: translateY(0); }
}
.bounce-animation {
animation: bounce 1s infinite;
}
실용적인 로딩 애니메이션
/* 스피너 로딩 */
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}
/* 펄스 효과 */
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.1); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}
.pulse {
animation: pulse 2s infinite;
}
3. 전환 효과 (Transitions)
사용자 상호작용에 반응하는 부드러운 전환 효과를 만들어봅시다.
기본 전환 효과
.button {
background-color: #3498db;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
/* 전환 효과 설정 */
transition: all 0.3s ease;
}
.button:hover {
background-color: #2980b9;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
/* 카드 호버 효과 */
.card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: scale(1.05);
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}
Transform 속성
/* 이동 */
.translate { transform: translate(50px, 100px); }
.translateX { transform: translateX(50px); }
.translateY { transform: translateY(100px); }
/* 회전 */
.rotate { transform: rotate(45deg); }
/* 크기 조절 */
.scale { transform: scale(1.5); }
.scaleX { transform: scaleX(2); }
.scaleY { transform: scaleY(0.5); }
/* 기울이기 */
.skew { transform: skew(20deg, 10deg); }
/* 조합 */
.combined {
transform: translate(50px, 100px) rotate(45deg) scale(1.2);
}
4. 고급 선택자
더 정확하고 효율적인 스타일링을 위한 고급 선택자들을 알아봅시다.
의사 클래스 (Pseudo-classes)
/* 상태 기반 선택자 */
a:hover { color: #3498db; }
a:active { color: #2980b9; }
a:visited { color: #9b59b6; }
input:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
}
/* 구조 기반 선택자 */
li:first-child { font-weight: bold; }
li:last-child { margin-bottom: 0; }
li:nth-child(odd) { background-color: #f8f9fa; }
li:nth-child(even) { background-color: white; }
/* nth-child 고급 사용법 */
li:nth-child(3n+1) { color: red; } /* 1, 4, 7, 10... */
li:nth-child(-n+3) { font-size: 18px; } /* 처음 3개 */
의사 요소 (Pseudo-elements)
/* 장식 요소 추가 */
.quote::before {
content: """;
font-size: 2em;
color: #3498db;
}
.quote::after {
content: """;
font-size: 2em;
color: #3498db;
}
/* 툴팁 만들기 */
.tooltip {
position: relative;
cursor: help;
}
.tooltip::after {
content: attr(data-tooltip);
position: absolute;
bottom: 125%;
left: 50%;
transform: translateX(-50%);
background: #333;
color: white;
padding: 8px 12px;
border-radius: 4px;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s;
}
.tooltip:hover::after {
opacity: 1;
visibility: visible;
}