탭 에니메이션 구현
Tab을 사용하여 콘텐츠를 표시하는 방법
안녕하세요! 여러 개의 탭(Tab)을 사용하여 콘텐츠를 표시하는 웹 페이지를 구현하는 방법에 대해 설명해드리겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>1</title>
<style>
.tab-content {
display: none;
}
</style>
</head>
<body>
<div class="tab">
<button class="tablinks" onclick="openTab(event, 'Tab1')">Tab 1</button>
<button class="tablinks" onclick="openTab(event, 'Tab2')">Tab 2</button>
<button class="tablinks" onclick="openTab(event, 'Tab3')">Tab 3</button>
</div>
<div id="Tab1" class="tab-content">
<h3>Tab 1</h3>
<p>Tab 1 내용입니다.</p>
</div>
<div id="Tab2" class="tab-content">
<h3>Tab 2</h3>
<p>Tab 2 내용입니다.</p>
</div>
<div id="Tab3" class="tab-content">
<h3>Tab 3</h3>
<p>Tab 3 내용입니다.</p>
</div>
<script>
function openTab(evt, tabName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tab-content");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
</body>
</html>
해당 코드들의 주요 기능 설명에 대해 말씀드리겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
HTML 구조
<head>: 문서의 메타데이터 및 스타일을 포함합니다.
<style>: CSS를 통해 .tab-content 클래스 요소를 모두 display: none으로 숨깁니다.
<body>: 탭 버튼과 탭 콘텐츠로 구성된 본문을 정의합니다.
탭 버튼들은 각 버튼의 onclick 속성으로 openTab 함수를 호출하여 탭 전환 기능을 구현합니다.
CSS 스타일링
.tab-content: 모든 탭 콘텐츠를 기본적으로 숨기는 역할을 합니다.
JavaScript 함수
openTab(evt, tabName):
tabcontent 배열을 사용하여 모든 탭 콘텐츠를 숨깁니다.
tablinks 배열을 사용하여 모든 탭 버튼의 active 클래스를 제거합니다.
지정된 tabName의 탭 콘텐츠를 표시하고, 클릭된 버튼에 active 클래스를 추가합니다.
요약하자면
1
2
3
HTML: 탭 버튼과 각 탭의 콘텐츠를 정의합니다.
CSS: 모든 탭 콘텐츠를 숨기고, 나중에 JavaScript를 통해 원하는 콘텐츠만 표시합니다.
JavaScript: 탭 전환 로직을 구현하여 사용자가 탭 버튼을 클릭하면 해당 탭의 콘텐츠만 표시하도록 합니다.
이번엔 수정된 코드를 한번 살펴보겠습니다.
Tab 1을 기본으로 열기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>1</title>
<style>
.tab-content {
display: none;
}
.tab button.active {
background-color: #ccc;
}
</style>
</head>
<body>
<div class="tab">
<button class="tablinks active" onclick="openTab(event, 'Tab1')">Tab 1</button>
<button class="tablinks" onclick="openTab(event, 'Tab2')">Tab 2</button>
<button class="tablinks" onclick="openTab(event, 'Tab3')">Tab 3</button>
</div>
<div id="Tab1" class="tab-content" style="display: block;">
<h3>Tab 1</h3>
<p>Tab 1 내용입니다.</p>
</div>
<div id="Tab2" class="tab-content">
<h3>Tab 2</h3>
<p>Tab 2 내용입니다.</p>
</div>
<div id="Tab3" class="tab-content">
<h3>Tab 3</h3>
<p>Tab 3 내용입니다.</p>
</div>
<script>
function openTab(evt, tabName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tab-content");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
</body>
</html>
개선점으로
- 기본으로 표시할 탭 설정:
style=”display: block”을 사용하여 기본으로 열릴 탭을 지정합니다.
해당 탭 버튼에 active 클래스를 추가합니다. - 스타일 개선:
활성화된 탭에 배경색을 적용하여 시각적인 구분을 제공합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>1</title>
<style>
.tab {
display: flex;
}
.tab button {
background-color: inherit;
border: none;
outline: none;
cursor: pointer;
padding: 10px;
transition: background-color 0.3s;
}
.tab button.active {
background-color: #ccc;
}
.tab button:hover {
background-color: #ddd;
}
.tab-content {
display: none;
margin-top: 10px;
}
</style>
</head>
<body>
<div class="tab" role="tablist">
<button class="tablinks active" onclick="openTab(event, 'Tab1')" role="tab" aria-controls="Tab1" aria-selected="true" tabindex="0">Tab 1</button>
<button class="tablinks" onclick="openTab(event, 'Tab2')" role="tab" aria-controls="Tab2" aria-selected="false" tabindex="-1">Tab 2</button>
<button class="tablinks" onclick="openTab(event, 'Tab3')" role="tab" aria-controls="Tab3" aria-selected="false" tabindex="-1">Tab 3</button>
</div>
<div id="Tab1" class="tab-content" role="tabpanel" aria-labelledby="Tab1-button" style="display: block;">
<h3>Tab 1</h3>
<p>Tab 1 내용입니다.</p>
</div>
<div id="Tab2" class="tab-content" role="tabpanel" aria-labelledby="Tab2-button">
<h3>Tab 2</h3>
<p>Tab 2 내용입니다.</p>
</div>
<div id="Tab3" class="tab-content" role="tabpanel" aria-labelledby="Tab3-button">
<h3>Tab 3</h3>
<p>Tab 3 내용입니다.</p>
</div>
<script>
function openTab(evt, tabName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tab-content");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
tablinks[i].setAttribute("aria-selected", "false");
tablinks[i].setAttribute("tabindex", "-1");
}
document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " active";
evt.currentTarget.setAttribute("aria-selected", "true");
evt.currentTarget.setAttribute("tabindex", "0");
}
// 키보드 탐색 기능 추가
document.addEventListener("keydown", function (event) {
const keys = ["ArrowLeft", "ArrowRight"];
if (keys.includes(event.key)) {
const currentActive = document.querySelector(".tab button.active");
let newIndex = [...document.querySelectorAll(".tab button")].indexOf(currentActive);
if (event.key === "ArrowLeft") {
newIndex = (newIndex - 1 + 3) % 3; // 탭 개수에 따라 수정
} else if (event.key === "ArrowRight") {
newIndex = (newIndex + 1) % 3;
}
const newActive = document.querySelectorAll(".tab button")[newIndex];
newActive.click();
newActive.focus();
}
});
</script>
</body>
</html>
추가 개선 사항으로
- 탭 버튼에 스타일 추가 :
- 기본 스타일을 지정하고, 마우스를 올렸을 떄 배경색을 변경합니다.
- 기본 스타일을 지정하고, 마우스를 올렸을 떄 배경색을 변경합니다.
- 접근성 개선 :
- role, aria-* 속성을 통해 탭과 탭 콘텐츠 사이의 관계를 명확히 합니다. 키보드 탐색을 지원합니다.
- role, aria-* 속성을 통해 탭과 탭 콘텐츠 사이의 관계를 명확히 합니다. 키보드 탐색을 지원합니다.
- 애니메이션 :
- 탭 전환 시 콘텐츠가 부드럽게 전환되도록 CSS 애니메이션이나 트랜지션을 추가할 수 있습니다.
- 탭 전환 시 콘텐츠가 부드럽게 전환되도록 CSS 애니메이션이나 트랜지션을 추가할 수 있습니다.
- 탭 버튼 구성 개선 :
- 탭 버튼을 동적으로 생성하여 중복된 코드량을 줄일 수 있습니다.
다음시간에 계속…
This post is licensed under CC BY 4.0 by the author.