1. HTML 구조 (직관적 클래스명 적용)
<div class="slide-container(slide-wrap) container"> <!-- 전체 컨테이너 (position: relative) -->
<img src="상대주소" class="bg">
<div class="slide-window"> <!-- 👁️ 보이는 창 (overflow: hidden) -->
<button class="left">왼쪽</button>
<button class="right"오른쪽</button>
<div class="slidebox"> <!-- 📏 늘어난 박스 (300%) -->
<div class="slide">슬라이드 1</div>
<div class="slide">슬라이드 2</div>
<div class="slide">슬라이드 3</div>
</div>
</div>
</div>
2. CSS 핵심 속성
/* 1. 전체 컨테이너 (위치 기준점) */
.slide-container {
position: relative; /* 내부 요소들의 기준점 */
width: 100%; /* 필요한 너비 */
}
/* 배경 이미지 */
.background-image {
width: 100%; /* 컨테이너 너비에 맞춤 */
}
/* 2. 보이는 창 */
.slide-window {
position: absolute; /* 컨테이너 위에 겹치도록 */
width: 100%;
height: 100%; /* 높이도 설정 */
top: 0; /* 컨테이너 상단에 맞춤 */
left: 0; /* 컨테이너 좌측에 맞춤 */
overflow: hidden; /* 중요! 넘치는 부분 숨김 */
}
/* 3. 늘어난 박스 */
.slidebox {
display: flex; /* 가로 배치 */
width: 300%; /* 슬라이드 3개면 300% */
}
/* 4. 개별 슬라이드 */
.slide {
width: 100%; /* 창 크기와 동일 */
}
/* 버튼 위치 (양쪽 배치) */
.left, .right {
position: absolute; /* 윈도우 기준으로 위치 */
top: 50%; /* 세로 중앙 */
transform: translateY(-50%);
z-index: 10; /* 슬라이드보다 위에 */
}
.left { left: 20px; } /* 왼쪽 여백 */
.right { right: 20px; } /* 오른쪽 여백 */
3. JavaScript 코드
// 1. 기본 변수 선언
let index = 0; // 현재 슬라이드 위치
let left = document.querySelector(".left"); // 왼쪽 버튼
let right = document.querySelector(".right"); // 오른쪽 버튼
let slide = document.querySelectorAll(".slide"); // 모든 슬라이드들
// 2. 왼쪽 이동 함수
function moveleft() {
index--; // 1. 인덱스 감소
if (index < 0) index = slide.length - 1;// 2. 범위 체크
slide.forEach((s) => { // 3. 모든 슬라이드에 적용
s.style.transform = `translateX(${index * -100}%)`; // 4. 이동 처리
});
}
// 3. 오른쪽 이동 함수
function moveright() {
index++; // 1. 인덱스 증가
if (index >= slide.length) index = 0; // 2. 범위 체크
slide.forEach((s) => { // 3. 모든 슬라이드에 적용
s.style.transform = `translateX(${index * -100}%)`; // 4. 이동 처리
});
}
// 4. 이벤트 연결
left.addEventListener("click", moveleft); // 왼쪽 버튼 클릭시 왼쪽 함수
right.addEventListener("click", moveright); // 오른쪽 버튼 클릭시 오른쪽 함수
자연어로 이해하기
- HTML 구조: 슬라이드 컨테이너(position: relative) → 윈도우(overflow: hidden) → 박스(300%) → 슬라이드(100%)
- 조건문 외우기 (자연어 문장으로 기억):
- 왼쪽 버튼:
if(index < 0) index = slide.length-1;- "인덱스가 0보다 작아졌어? 그럼 맨 뒤로 가자"
- 오른쪽 버튼:
if(index >= slide.length) index = 0;- "인덱스가 슬라이드 개수만큼 됐어? 그럼 맨 앞으로 가자"
- 왼쪽 버튼:
- transform 외우기:
s.style.transform = translateX(${index * -100}%);- 뜻: "스타일의 트랜스폼을 써서 가로로(X축) 이동시키는데, 인덱스에 -100%를 곱한 만큼 움직인다"
- 덩어리로 나누어 외우기:
s.style.transform = // 스타일 트랜스폼에 translateX(${ // 트랜슬레이트엑스 괄호 백틱 index * -100 // 인덱스 곱하기 -100 }%) // 퍼센트 닫기
- 버튼 위치 (시험에서 중요):
- position: absolute 필수
- top: 50%와 transform: translateY(-50%)로 세로 중앙 정렬
- left/right 속성으로 좌우 위치 조정
- 실제 이동 예시:
index = 0일 때: translateX(0%) // 제자리 index = 1일 때: translateX(-100%) // 왼쪽으로 100% 이동 index = 2일 때: translateX(-200%) // 왼쪽으로 200% 이동
__
슬라이드 구조 정리
1. 메인(main) 설정
- main에
width: 100%,height: 40vw고정 - position: relative 줌
→ 이걸로 슬라이드랑 버튼이 메인 기준으로 겹치게 띄움 - main img (배경 이미지)
width: 100%,height: 40vwposition: relative- → 메인과 배경 이미지를 같은 크기로 맞췄다.
2. slide-wrap 설정
- slide-wrap에
width: 100%height: 100%position: absolutetop: 0left: 50%transform: translateX(-50%)
- → 메인 기준으로 slide-wrap을 배경 위에 가운데 정렬하고 띄웠다.
3. slide-window, slide-box 설정
- slide-window
position: absolutewidth: 100%height: 100%overflow: hidden
- slide-box
position: absolutewidth: 300%(슬라이드 3장)height: 100%display: flex
- → 슬라이드를 가로로 이어붙이고, slide-window로 "보이는 영역"만 잘라냈다.
4. slide, s-img, s-text 구조
- slide
width: 100%height: 100%
- s-img (강아지 이미지 박스)
width: 50%height: 100%display: flexalign-items: centerjustify-content: center
- s-img img (강아지 이미지)
width: 60%height: auto
- → 강아지 이미지 자체 크기를 60%로 줄이고,
부모 박스 가운데에 비율 유지하면서 자연스럽게 작게 배치했다.
5. 버튼(left, right) 설정
- left 버튼
position: absolutetop: 50%left: 0transform: translateY(-50%)z-index: 7
- right 버튼
position: absolutetop: 50%right: 0transform: translateY(-50%)z-index: 7
- → 슬라이드 안에서 가운데 수직 정렬 + 좌우 끝에 딱 붙게 배치했다.
🔥 최종 흐름
| 항목 | 설정 요약 |
|---|---|
| 메인 | height: 40vw, relative 기준으로 겹침 |
| 메인 이미지 | width: 100%, height: 40vw, 배경 크기 통일 |
| slide-wrap | absolute로 띄우고 중앙 정렬 |
| 슬라이드 창 | window로 잘라내고 box로 가로 슬라이드 |
| 강아지 이미지 | s-img 박스 flex 정렬 + img 60% 축소 |
| 버튼 | slide-wrap 기준으로 수직 가운데, 좌우 끝 |
✅ transform: translateY(-50%) 쓸 때 헷갈리는 "top, left, right" 정리
1. 기본 흐름
top: 50%→ 부모 높이의 50% 지점까지 내려간다.transform: translateY(-50%)→ 자기 자신의 높이의 절반만큼 다시 끌어올린다.
→ 이 조합으로 "완전 수직 가운데" 맞춘다.
2. 그런데 왜 left, right를 따로 줘야 하냐?
top: 50%는 수직(위아래) 위치를 잡는 거다.- 가로(좌우) 위치는 별도로
left: 0또는right: 0줘야 한다.
→ 가로 정렬은 top, translateY랑 아무 관계 없다.
✅ 요약
| 항목 | 해야 하는 일 |
|---|---|
| 세로 중앙 잡기 | top: 50% + transform: translateY(-50%) |
| 왼쪽 끝으로 붙이기 | left: 0 추가 |
| 오른쪽 끝으로 붙이기 | right: 0 추가 |
✅
세로는 top 50% + translateY -50%로 맞추고,
가로는 left 0이나 right 0으로 박는다.
✅
왼쪽 버튼:
.left {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
}
오른쪽 버튼:
.right {
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
}
🔥요약
수직은 top+transform으로, 좌우는 left나 right 따로 박아야 한다.
텍스트 박스(s-text)
- position: absolute
- top: 0, right: 0
- width: 50%, height: 100%
- z-index: 7
- display: flex
- flex-direction: column
- justify-content: center
- padding: 20px
- 텍스트를 슬라이드 오른쪽에 세로 가운데 정렬
https://themewagon.github.io/waggy/#

'JS' 카테고리의 다른 글
| [시험대비JS] 탭 1(통과) (0) | 2025.04.25 |
|---|---|
| [시험대비JS] 탭 (폐기 AI이나쁜놈이) (0) | 2025.04.25 |
| [시험대비JS] 드롭다운 (통과) (0) | 2025.04.17 |
| [JS] 슬라이더 작동부 막힌 부분 코드 풀이 (0) | 2025.04.16 |
| Javascript DOM 이벤트 정리 (0) | 2025.04.14 |