<video>
<source src="video/sample.mp4" type="video/mp4">
<source src="video/sample.webm" type="video/webm">
<source src="video/sample.ogg" type="video/ogg">
브라우저가 비디오를 지원하지 않습니다.
</video>
멀티 포맷 지원: 여러 형식을 제공하면 브라우저가 최적화된 포맷을 자동 선택
<video
autoplay
muted
loop
controls
poster="thumbnail.jpg"
preload="metadata"
width="800"
height="450"
>
<source src="video.mp4" type="video/mp4">
</video>
| 속성 | 설명 | 참고사항 |
|---|---|---|
autoplay | 자동 재생 | muted와 함께 사용해야 작동 |
muted | 음소거 상태 | 자동재생 정책상 필수 |
loop | 반복 재생 | 배경 비디오에 유용 |
controls | 재생 컨트롤 표시 | 사용자 제어 가능 |
poster | 썸네일 이미지 | 비디오 로드 전 표시 |
preload | 사전 로딩 설정 | auto, metadata, none |
<!-- 전체 비디오 미리 다운로드 -->
<video preload="auto">
<source src="video.mp4">
</video>
<!-- 메타데이터만 미리 로드 (권장) -->
<video preload="metadata">
<source src="video.mp4">
</video>
<!-- 사용자가 재생할 때까지 로드하지 않음 -->
<video preload="none">
<source src="video.mp4">
</video>
<div class="video-box">
<video class="video-container" autoplay muted loop>
<source src="video/background.mp4" type="video/mp4">
<source src="video/background.webm" type="video/webm">
</video>
<div class="video-content">
<h1>Welcome to Our Site</h1>
<p>Amazing content over video background</p>
<button class="cta-button">Get Started</button>
</div>
</div>
.video-box {
position: relative;
height: 100vh;
width: 100%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.video-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -1;
background-size: cover;
}
.video-content {
position: relative;
z-index: 1;
text-align: center;
color: white;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.video-content h1 {
font-size: 3rem;
margin-bottom: 1rem;
}
.video-content p {
font-size: 1.2rem;
margin-bottom: 2rem;
}
.cta-button {
padding: 15px 30px;
font-size: 1.1rem;
background: rgba(255, 255, 255, 0.2);
color: white;
border: 2px solid white;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s ease;
}
.cta-button:hover {
background: white;
color: #333;
}
@media (max-width: 768px) {
.video-container {
/* 모바일에서는 이미지로 대체 */
display: none;
}
.video-box {
background-image: url('video-poster.jpg');
background-size: cover;
background-position: center;
}
.video-content h1 {
font-size: 2rem;
}
}
.transform-demo {
/* 회전 */
transform: rotate(45deg);
/* 이동 */
transform: translate(50px, 100px);
transform: translateX(50px);
transform: translateY(100px);
/* 크기 조절 */
transform: scale(1.5);
transform: scaleX(2);
transform: scaleY(0.5);
/* 비틀기 */
transform: skew(15deg, 5deg);
transform: skewX(15deg);
transform: skewY(5deg);
/* 여러 속성 조합 */
transform: rotate(45deg) scale(1.2) translateX(20px);
}
/* 나쁜 예: 레이아웃 재계산 발생 */
.bad-animation {
transition: margin-left 0.3s;
}
.bad-animation:hover {
margin-left: 100px; /* 레이아웃 재계산 */
}
/* 좋은 예: GPU 가속 사용 */
.good-animation {
transition: transform 0.3s;
}
.good-animation:hover {
transform: translateX(100px); /* 효율적 */
}
/* 1. 키프레임 정의 */
@keyframes slideIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
transform: translateX(20px);
opacity: 0.8;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
/* 2. 애니메이션 적용 */
.slide-element {
animation: slideIn 0.8s ease-out;
}
.complex-animation {
animation-name: myAnimation; /* 키프레임 이름 */
animation-duration: 2s; /* 지속 시간 */
animation-timing-function: ease-in-out; /* 타이밍 함수 */
animation-delay: 0.5s; /* 시작 지연 */
animation-iteration-count: 3; /* 반복 횟수 */
animation-direction: alternate; /* 방향 */
animation-fill-mode: forwards; /* 종료 후 상태 */
animation-play-state: running; /* 재생/일시정지 */
/* 축약형 */
animation: myAnimation 2s ease-in-out 0.5s 3 alternate forwards;
}
/* 애니메이션 종료 후 원래 상태로 복귀 (기본값) */
.animation-none {
animation-fill-mode: none;
}
/* 애니메이션 종료 후 마지막 상태 유지 */
.animation-forwards {
animation-fill-mode: forwards;
}
/* 애니메이션 시작 전 첫 번째 상태 적용 */
.animation-backwards {
animation-fill-mode: backwards;
}
/* 시작 전과 종료 후 모두 적용 */
.animation-both {
animation-fill-mode: both;
}
.shake-button {
padding: 15px 30px;
font-size: 18px;
background: #007bff;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: transform 0.3s ease;
}
.shake-button:hover {
animation: shake 0.6s ease-in-out;
}
@keyframes shake {
0%, 100% {
transform: rotate(0deg);
}
25% {
transform: rotate(-5deg);
}
50% {
transform: rotate(5deg);
}
75% {
transform: rotate(-5deg);
}
}
.plus-button {
font-size: 48px;
color: #333;
cursor: pointer;
display: inline-block;
transition: transform 0.3s ease;
}
.plus-button:hover {
animation: rotatePlus 0.8s ease-out forwards;
}
@keyframes rotatePlus {
0% {
transform: rotate(0deg) scale(1);
}
25% {
transform: rotate(-15deg) scale(1.1);
}
100% {
transform: rotate(45deg) scale(1.3);
}
}
<nav class="sliding-menu">
<h4>Menu</h4>
<p class="menu-item">Home</p>
<p class="menu-item">About</p>
<p class="menu-item">Contact</p>
</nav>
.sliding-menu {
position: fixed;
left: 0;
top: 0;
width: 250px;
height: 100vh;
background: #333;
color: white;
padding: 30px 20px;
transform: translateX(-200px);
transition: all 0.5s ease;
z-index: 1000;
}
.sliding-menu:hover {
transform: translateX(0);
}
.sliding-menu h4 {
text-align: right;
transition: text-align 0.5s ease;
}
.sliding-menu:hover h4 {
text-align: center;
}
.menu-item {
cursor: pointer;
padding: 10px 0;
transition: all 0.3s ease;
}
.sliding-menu:hover .menu-item {
animation: slideText 0.8s ease-out;
}
@keyframes slideText {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
transform: translateX(30px) skewX(-20deg);
opacity: 0.7;
}
100% {
transform: translateX(0) skewX(0deg);
opacity: 1;
}
}
.card {
background: white;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
padding: 20px;
margin: 20px;
opacity: 0;
transform: translateY(50px);
animation: fadeInUp 0.6s ease-out forwards;
}
.card:nth-child(2) { animation-delay: 0.2s; }
.card:nth-child(3) { animation-delay: 0.4s; }
.card:nth-child(4) { animation-delay: 0.6s; }
@keyframes fadeInUp {
to {
opacity: 1;
transform: translateY(0);
}
}
.loader {
width: 50px;
height: 50px;
border: 4px solid #f3f3f3;
border-top: 4px solid #007bff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.pulse-button {
position: relative;
padding: 15px 30px;
background: #ff6b6b;
color: white;
border: none;
border-radius: 50px;
cursor: pointer;
}
.pulse-button::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 50px;
background: #ff6b6b;
animation: pulse 2s infinite;
z-index: -1;
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(1.3);
opacity: 0;
}
}
/* 애니메이션 성능 향상 */
.animated-element {
will-change: transform;
}
/* 애니메이션 완료 후 제거 */
.animated-element.animation-complete {
will-change: auto;
}
.gpu-accelerated {
/* 3D 변환으로 GPU 가속 활성화 */
transform: translate3d(0, 0, 0);
/* 또는 */
transform: translateZ(0);
/* 더 명시적인 방법 */
will-change: transform;
transform: translate3d(0, 0, 0);
}
/* 권장: 레이아웃에 영향 없는 속성들 */
.efficient-animation {
transition: transform 0.3s, opacity 0.3s;
}
/* 비권장: 레이아웃 재계산 발생 */
.inefficient-animation {
transition: width 0.3s, height 0.3s, margin 0.3s;
}
/* 데스크톱 애니메이션 */
@media (min-width: 768px) {
.desktop-animation {
animation: complexAnimation 2s ease-in-out;
}
}
/* 모바일에서는 단순한 애니메이션 */
@media (max-width: 767px) {
.desktop-animation {
animation: simpleAnimation 1s ease-out;
}
}
/* 사용자가 애니메이션을 원하지 않는 경우 */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* 개발 중 애니메이션 슬로우 모션 */
* {
animation-duration: 10s !important;
}
/* 특정 요소만 슬로우 모션 */
.debug-animation {
animation-duration: 5s !important;
}
/* 유틸리티 애니메이션 클래스 */
.fade-in {
animation: fadeIn 0.5s ease-out forwards;
}
.slide-up {
animation: slideUp 0.6s ease-out forwards;
}
.bounce-in {
animation: bounceIn 0.8s ease-out forwards;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from {
transform: translateY(30px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes bounceIn {
0% {
transform: scale(0.3);
opacity: 0;
}
50% {
transform: scale(1.05);
opacity: 0.8;
}
70% {
transform: scale(0.9);
opacity: 0.9;
}
100% {
transform: scale(1);
opacity: 1;
}
}
HTML 비디오 삽입부터 고급 CSS 애니메이션까지 정리해보았습니다.