728x90
오늘은 간단하게 FAQ페이지를 만들어 보겠습니다.
css파일에서 알아야할 내용은
1. `.question-text { ... } ` : (display: none;) 로 인해 페이지가 로드될 때 모든 답변은 숨겨져 있습니다.
2. ` .show-text .question-text {}` : .show-text 클래스가 적용된 element의 내부에 위치한 .question-text 클래스를 가진 요소를 대상으로 적용되며, (display: block;) 으로 인해 답변이 보이게됩니다.
js파일에서 알아야 할 내용은
1. question.classList.remove("show-text"): 현재 클릭한 질문을 제외한 모든 질문에서 show-text 클래스를 제거하게됩니다.
2. question.classList.toggle("show-text"); : question의 클래스 목록에 접근하여, show-text 클래스가 이미 존재하면 제거하고, 존재하지 않는다면 추가합니다. 즉, 답변이 현재 보이지 않는 상태라면 보이게 하고, 이미 보이는 상태라면 숨기게 합니다.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Q & A</title>
<!-- font-awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />
<!-- extra fonts -->
<link
href="https://fonts.googleapis.com/css?family=Great+Vibes&display=swap"
rel="stylesheet"
/>
<!-- styles -->
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<section class="questions">
<!-- title -->
<div class="title">
<h2>general questions</h2>
</div>
<!-- questions -->
<div class="section-center">
<!-- single question -->
<article class="question">
<!-- question title -->
<div class="question-title">
<p>do you accept all major credit cards?</p>
<button type="button" class="question-btn">
<span class="plus-icon">
<i class="far fa-plus-square"></i>
</span>
<span class="minus-icon">
<i class="far fa-minus-square"></i>
</span>
</button>
</div>
<!-- question text -->
<div class="question-text">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est
dolore illo dolores quia nemo doloribus quaerat, magni numquam
repellat reprehenderit.
</p>
</div>
</article>
<!-- end of single question -->
<!-- single question -->
<article class="question">
<!-- question title -->
<div class="question-title">
<p>do you suppport local farmers?</p>
<button type="button" class="question-btn">
<span class="plus-icon">
<i class="far fa-plus-square"></i>
</span>
<span class="minus-icon">
<i class="far fa-minus-square"></i>
</span>
</button>
</div>
<!-- question text -->
<div class="question-text">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est
dolore illo dolores quia nemo doloribus quaerat, magni numquam
repellat reprehenderit.
</p>
</div>
</article>
<!-- end of single question -->
<!-- single question -->
<article class="question">
<!-- question title -->
<div class="question-title">
<p>do you use organic ingredients?</p>
<!-- button -->
<button type="button" class="question-btn">
<span class="plus-icon">
<i class="far fa-plus-square"></i>
</span>
<span class="minus-icon">
<i class="far fa-minus-square"></i>
</span>
</button>
</div>
<!-- question text -->
<div class="question-text">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est
dolore illo dolores quia nemo doloribus quaerat, magni numquam
repellat reprehenderit.
</p>
</div>
</article>
<!-- end of single question -->
</section>
</main>
<!-- javascript -->
<script src="app.js"></script>
</body>
</html>
app.js
// 모든 ".question" 클래스를 가진 요소를 선택
const questions = document.querySelectorAll(".question");
// 각 질문에 대해 반복
questions.forEach(function (question) {
// 현재 질문의 버튼을 선택
const btn = question.querySelector(".question-btn");
// 버튼에 클릭 이벤트 리스너 추가
btn.addEventListener("click", function () {
// 다른 모든 질문 항목에 대해 반복
questions.forEach(function (item) {
// 현재 질문이 아닌 항목에서 "show-text" 클래스 제거
if (item !== question) {
item.classList.remove("show-text");
}
});
// 현재 질문의 "show-text" 클래스를 토글
question.classList.toggle("show-text");
});
});
styles.css
/*
===============
Fonts
===============
*/
@import url("https://fonts.googleapis.com/css?family=Open+Sans|Roboto:400,700&display=swap");
/*
===============
Variables
===============
*/
:root {
/* dark shades of primary color*/
--clr-primary-1: hsl(205, 86%, 17%);
--clr-primary-2: hsl(205, 77%, 27%);
--clr-primary-3: hsl(205, 72%, 37%);
--clr-primary-4: hsl(205, 63%, 48%);
/* primary/main color */
--clr-primary-5: #49a6e9;
/* lighter shades of primary color */
--clr-primary-6: hsl(205, 89%, 70%);
--clr-primary-7: hsl(205, 90%, 76%);
--clr-primary-8: hsl(205, 86%, 81%);
--clr-primary-9: hsl(205, 90%, 88%);
--clr-primary-10: hsl(205, 100%, 96%);
/* darkest grey - used for headings */
--clr-grey-1: hsl(209, 61%, 16%);
--clr-grey-2: hsl(211, 39%, 23%);
--clr-grey-3: hsl(209, 34%, 30%);
--clr-grey-4: hsl(209, 28%, 39%);
/* grey used for paragraphs */
--clr-grey-5: hsl(210, 22%, 49%);
--clr-grey-6: hsl(209, 23%, 60%);
--clr-grey-7: hsl(211, 27%, 70%);
--clr-grey-8: hsl(210, 31%, 80%);
--clr-grey-9: hsl(212, 33%, 89%);
--clr-grey-10: hsl(210, 36%, 96%);
--clr-white: #fff;
--clr-red-dark: hsl(360, 67%, 44%);
--clr-red-light: hsl(360, 71%, 66%);
--clr-green-dark: hsl(125, 67%, 44%);
--clr-green-light: hsl(125, 71%, 66%);
--clr-gold: #c59d5f;
--clr-black: #222;
--ff-primary: "Roboto", sans-serif;
--ff-secondary: "Open Sans", sans-serif;
--transition: all 0.3s linear;
--spacing: 0.25rem;
--radius: 0.5rem;
--light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
--dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
--max-width: 1170px;
--fixed-width: 620px;
}
/*
===============
Global Styles
===============
*/
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--ff-secondary);
background: var(--clr-grey-10);
color: var(--clr-grey-1);
line-height: 1.5;
font-size: 0.875rem;
}
ul {
list-style-type: none;
}
a {
text-decoration: none;
}
img:not(.logo) {
width: 100%;
}
img {
display: block;
}
h1,
h2,
h3,
h4 {
letter-spacing: var(--spacing);
text-transform: capitalize;
line-height: 1.25;
margin-bottom: 0.75rem;
font-family: var(--ff-primary);
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.25rem;
}
h4 {
font-size: 0.875rem;
}
p {
margin-bottom: 1.25rem;
color: var(--clr-grey-5);
}
@media screen and (min-width: 800px) {
h1 {
font-size: 4rem;
}
h2 {
font-size: 2.5rem;
}
h3 {
font-size: 1.75rem;
}
h4 {
font-size: 1rem;
}
body {
font-size: 1rem;
}
h1,
h2,
h3,
h4 {
line-height: 1;
}
}
/* global classes */
.btn {
text-transform: uppercase;
background: transparent;
color: var(--clr-black);
padding: 0.375rem 0.75rem;
letter-spacing: var(--spacing);
display: inline-block;
transition: var(--transition);
font-size: 0.875rem;
border: 2px solid var(--clr-black);
cursor: pointer;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
border-radius: var(--radius);
}
.btn:hover {
color: var(--clr-white);
background: var(--clr-black);
}
/* section */
.section {
padding: 5rem 0;
}
.section-center {
width: 90vw;
margin: 0 auto;
max-width: 1170px;
}
@media screen and (min-width: 992px) {
.section-center {
width: 95vw;
}
}
main {
min-height: 100vh;
display: grid;
place-items: center;
}
/*
===============
Questions
===============
*/
.title {
margin-top: 15vh;
margin-bottom: 4rem;
}
.title h2 {
color: var(--clr-gold);
font-family: "Great Vibes", cursive;
text-align: center;
}
.section-center {
max-width: var(--fixed-width);
}
.question {
background: var(--clr-white);
border-radius: var(--radius);
box-shadow: var(--light-shadow);
padding: 1.5rem 1.5rem 0 1.5rem;
margin-bottom: 2rem;
}
.question-title {
display: flex;
justify-content: space-between;
align-items: center;
text-transform: capitalize;
padding-bottom: 1rem;
}
.question-title p {
margin-bottom: 0;
letter-spacing: var(--spacing);
color: var(--clr-grey-1);
}
.question-btn {
font-size: 1.5rem;
background: transparent;
border-color: transparent;
cursor: pointer;
color: var(--clr-gold);
transition: var(--transition);
}
.question-btn:hover {
transform: rotate(90deg);
}
.question-text {
padding: 1rem 0 1.5rem 0;
border-top: 1px solid rgba(0, 0, 0, 0.2);
}
.question-text p {
margin-bottom: 0;
}
/* hide text */
/* 기본적으로 모든 질문의 답변 텍스트를 숨깁니다. */
.question-text {
display: none;
}
/* '.show-text' 클래스가 부모 요소에 추가됐을 때, 해당 부모 요소 내의 '.question-text' 요소를 보이게 합니다.
이는 사용자가 질문을 클릭했을 때 답변을 표시하기 위해 사용됩니다. */
.show-text .question-text {
display: block;
}
/* 기본적으로 모든 'minus-icon'을 숨깁니다.
이 아이콘은 질문이 확장되어 답변이 보이는 상태를 나타내기 위해 사용됩니다. */
.minus-icon {
display: none;
}
/* '.show-text' 클래스가 부모 요소에 추가됐을 때, 해당 부모 요소 내의 '.minus-icon' 요소를 보이게 합니다.
이는 질문이 확장되어 답변이 보일 때 '닫기' 아이콘으로 사용자에게 시각적 피드백을 제공합니다. */
.show-text .minus-icon {
display: inline;
}
/* '.show-text' 클래스가 부모 요소에 추가됐을 때, 해당 부모 요소 내의 '.plus-icon' 요소를 숨깁니다.
이는 질문이 확장될 때 '열기' 아이콘을 숨기기 위해 사용됩니다. */
.show-text .plus-icon {
display: none;
}
결과
버튼을 눌러 답변이 나오는지 확인해보세요.
'JavaScript' 카테고리의 다른 글
[Javascript] 식당 메뉴판 만들기 (0) | 2024.05.04 |
---|---|
[Javascript] 버튼 이동 시키기 (0) | 2024.04.29 |
[Javascript] 모달 만들기 (0) | 2024.04.19 |
[Javascript] 자바스크립트로 5초 마다 변경되는 배너 만들기 (0) | 2024.04.18 |
[Javascript] 마우스 오버 텍스트 색상 변경 (0) | 2024.04.11 |