Question
: 질문 상자(box)를 누르면 내용(content)을 보여주는 바가 내려간다.
사용 언어
- HTML
- CSS
- Javascript
구조
- index.html - 전체 구조
- index.js - 기능 구현
- main.css - 전체 디자인
코드
구현 계획
- 버튼 html, css 생성
- 버튼 누르면 서브 메뉴 열리게 구현 (js)
- 버튼 누르면 서브 메뉴 열고 닫히게 토글 생성
- 서브 메뉴가 열려있으면 (if(max-height)) 서브메뉴 닫고(max-height == null) 닫혀있으면 (max-height + "px")
- css에서 transition에 시간 설정
기능 구현
- for문을 이용하여 3개의 버튼에 토글 기능 부여
- 버튼의 다음 요소(=내용content)를 가지고 온다. (nextElementSibling)
- 요소의 최대 높이를 통해 열려있는지 확인한다.(.style.maxHeight)
(1) 내용이 열려있으면(content.style.maxHeight)
내용을 닫는다. (content.style.maxHeight = null;)
(2) 내용이 닫혀있으면
내용을 연다. (= 내용의 최대 높이를 스크롤 높이로 만든다.
maxHeight = content.scrollHeight + "px")
for (let i = 0; i < button.length; i++) {
button[i].addEventListener("click", function () {
this.classList.toggle("show");
let content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="main.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,300;0,400;0,700;0,900;1,300;1,400;1,700;1,900&display=swap');
</style>
</head>
<body style="background-color: hsl(210, 36%, 96%)">
<div id="question">
<p>Questions</p>
</div>
<div class="container">
<button type="button" class="btn">Do You Accept All Major Credit Cards?</button>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
</div>
</div>
<div class="container2">
<button type="button" class="btn">Do You Suppport Local Farmers?</button>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</div>
</div>
<div class="container3">
<button type="button" class="btn">Do You Use Organic Ingredients?</button>
<div class="content">
<p>Lorem ipsum dolor sit ametLorLorem ipsum dolor sit ametem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
</div>
</div>
<script src="main.js">
</script>
</body>
</html>
index.js
let button = document.getElementsByClassName("btn"); // 버튼 변수 생성
for (let i = 0; i < button.length; i++) {
button[i].addEventListener("click", function () {
this.classList.toggle("show");
let content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
main.css
#question {
color: #050505;
font-family: "Merriweather", serif;
font-weight: 400;
font-style: italic;
font-size: 35px;
text-align: center;
font-weight: 360;
padding-top: 100px;
margin: -60px;
}
/* 버튼 */
.btn {
background-color: #ffffff;
color: #050505;
font-size: 16px;
font-family: "Merriweather", serif;
font-weight: 400;
font-style: italic;
cursor: pointer;
padding: 30px;
width: 100%;
border-radius: 10px;
border: none;
text-align: center;
outline: none;
box-shadow: 1px 2px 1px rgb(172, 172, 172), 1px 1px 0px rgb(237, 237, 237);
}
/* 버튼에 마우스 오버 시 색상 변경 */
.btn:hover {
background-color: #ededed;
}
/* 버튼 토글 */
.show {
display: block;
}
/* 내용 */
.content {
background-color: white;
font-family: "Merriweather", serif;
font-weight: 400;
font-style: italic;
font-size: 13px;
text-align: center;
max-height: 0;
overflow: hidden;
box-shadow: 1px 2px 1px rgb(172, 172, 172), 1px 1px 0px rgb(237, 237, 237);
border-radius: 10px;
transition: max-height 0.2s ease-out;
}
/* 버튼 위치 */
.container {
/* padding: top, right, bottom, left */
padding: 70px 50px 8px 50px;
}
.container2 {
padding: 20px 50px 20px 50px;
}
.container3 {
padding: 10px 50px 30px 50px;
}
/* 버튼 옆에 아이콘(+, -) */
.btn::after {
content: '\02795'; /* (+) 유니코드 */
font-size: 13px;
color: rgb(157, 23, 23);
float: right;
margin-left: 10px;
}
.show::after {
content: "\2796"; /* (-) 아이콘 유니코드 */
}
아쉬운 점
1. 하단의 내용 바가 내려가는 모양이 이상하다.
- 버튼 박스의 높이가 조절되며 열리는 것이 아니라 내용 박스가 따로 버튼 박스 아래에 생기는 방식으로 구현되었다.
- 버튼의 height를 기본값 → 결과값(내용 바가 내려간 값)으로 변경하면 되지 않을까 싶었으나 시간이 부족하여 구현하지 못했다.이로 인해 버튼 박스 안에 버튼과 하단 내용 바를 구분하는 구분선을 넣지 못했다.
링크를 참고해서 다시 만들어보고 싶다.
https://kasterra.github.io/making-performant-collapsing-animation/
2. 박스 너비가 고정된 상태가 아닌 창 크기에 따라 달라진다.
- 전체 창에서 보면 너비가 너무 넓어진다.
3. 박스 아무 곳을 눌러도 하단 바가 열린다.
- 버튼 박스가 아닌 오른쪽의 (+)아이콘만 선택해서 하단 내용 바를 열 수 있게 해야 한다.
깃허브
https://github.com/kwonboryong/study_of_FE/tree/main/Question
출처
https://www.w3schools.com/howto/howto_js_collapsible.asp
https://kasterra.github.io/making-performant-collapsing-animation/
배운것
https://limsw.tistory.com/m/108
https://aljjabaegi.tistory.com/m/548
https://nykim.work/71
https://poiemaweb.com/css3-transition