web Language/css

3. accordion 메뉴창 내부 html 보여주기

wooweee 2023. 4. 25. 10:51
728x90

1. property

 

  • outline: outline은 단지 테두리만 생기는 것 뿐 - border와 차이점
  • border: 은 두께만큼 박스의 전체 크기도 커진다.

 

  • text-align: block 내부 글자 위치 선정
  • transition: property의 값의 변화가 생길 경우 부드럽게 변화 시켜준다.

 

  • ::after : 가상요소, 선택한 요소의 일부에만 style 적용, html에 elelment를 적용한 것 처럼 동작
    • content : ::after ::before와 보통 같이 사용, 요소로 추가된다.
  • overflow : 부모 영역 바깥으로 나가면 해당 부분 자르기
  • float : 좌우 이동

 

  • max-height: div 높이 설정
  • scrollHeight: 원글이 길어서 화면 바깥으로 빠져나간 부분을 포함해서 전체 글의 길이를 의미
  • clientHeight : 현재 화면에서 보이는 height
  • clientWidth : 현재 화면에서 보이는 width
  • scrollTop: 실제 scroll 초기 위치 설정(상하)
  • scrollLeft: 실제 scroll 초기 위치 설정(좌우)

 

2. display

  • display: none -> block을 이용한 방식
  • 해당 방식은 transition 적용이 되지 않는다.
    • display: block과 display: none은 CSS에서 요소의 렌더링 방법을 결정하는 속성으로, 해당 속성이 변경되면 요소의 높이와 너비가 변하게 된다.
    • 반면에 transition 속성은 요소의 속성 값의 변화에 대해 시간 지연을 설정해 애니메이션 효과를 부여하는 속성

    • display: none은 요소를 화면에서 숨기기 때문에 요소의 높이와 너비가 0이 되어버리기 때문에, 이 상태에서 transition을 사용하더라도 애니메이션 효과가 적용되지 않는다.
      *ps.  display none, block 하는 경우 opacity, visibility 를 이용도 고려

 

 

  • html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Accordion</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <button class="accordion">Section 1</button>
    <div class="panel">
      <p>Lorem ipsum...</p>
    </div>

    <button class="accordion">Section 2</button>
    <div class="panel">
      <p>Lorem ipsum...</p>
    </div>

    <button class="accordion">Section 3</button>
    <div class="panel">
      <p>Lorem ipsum...</p>
    </div>

    <script src="app.js"></script>
  </body>
</html>

 

  • css
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px; /* 실제 text가 들어갈 공간보다 padding이 크게 되면 block사이즈가 커진다.*/
  width: 100%;
  border: none;
  text-align: left; /* 글자 위치가 왼쪽으로 붙음*/
  outline: none; /*border와 차이점 : outline은 단지 테두리만 생기는 것 뿐, border은 두께만큼 박스의 전체 크기도 커진다.*/
  transition: 0.4s;
}

.active,
.accordion:hover {
  background-color: #ccc;
}

.panel {
  padding: 0 18px;
  display: none;
  background-color: white;
  overflow: hidden; /* 부모 영역 바깥으로 나가면 해당 부분 자르기 */
  transition: 0.4s; /* 적용 안됨*/
}

/* ::after 는 가상 요소로 content라는 가상 요소가 생성된다. */
.accordion::after {
  content: "\02795";
  font-size: 13px;
  color: #777;
  float: right;
  margin-left: 5px;
}

/* active::after가 .accordion::after보다 아래에 위치하므로 마지막 적용이 됨*/
.active::after {
  content: "\2796";
}

 

  • JS
const accordions = document.getElementsByClassName("accordion");

function handleShowAccordion() {
  // 향상된 for문 사용시 let accordion = this; 작성 필요
  // let accordion = this;
  this.classList.toggle("active");

  // nextElementSibling: 현 element의 다음 element만 가져옴
  // nextSibling : 현 element의 다음 모든 것(element, text)를 상관 없이 가져옴
  let panel = this.nextElementSibling;

  // 숨겨진 글 보여주기 1 - 딱딱하게 생성
  if (panel.style.display === "block") {
    panel.style.display = "none";
  } else {
    panel.style.display = "block";
  }
}

for (let accordion of accordions) {
  accordion.addEventListener("click", handleShowAccordion);
}

 

3. max-height

 

 

  • transition 적용을 위해서 max-height를 이용

 

  • html 동일
  • css
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px; /* 실제 text가 들어갈 공간보다 padding이 크게 되면 block사이즈가 커진다.*/
  width: 100%;
  border: none;
  text-align: left; /* 글자 위치가 왼쪽으로 붙음*/
  outline: none; /*border와 차이점 : outline은 단지 테두리만 생기는 것 뿐, border은 두께만큼 박스의 전체 크기도 커진다.*/
  transition: 0.4s;
}

.active,
.accordion:hover {
  background-color: #ccc;
}

.panel {
  padding: 0 18px;
  /* display: none; none 있으면 작동안함*/
  max-height: 0; /*display: none 대신에 display heigth를 0으로 둬서 없는 것처럼 둔다.*/
  background-color: white;
  overflow: hidden; /* 부모 영역 바깥으로 나가면 해당 부분 자르기 */
  transition: max-height 0.2s ease-out; /* 적용 됨*/
}

/* ::after 는 가상 요소로 content라는 가상 요소가 생성된다. */
.accordion::after {
  content: "\02795";
  font-size: 13px;
  color: #777;
  float: right;
  margin-left: 5px;
}

/* active::after가 .accordion::after보다 아래에 위치하므로 마지막 적용이 됨*/
.active::after {
  content: "\2796";
}

 

  • JS
const accordions = document.getElementsByClassName("accordion");

function handleShowAccordion() {
  // 향상된 for문 사용시 let accordion = this; 작성 필요
  // let accordion = this;
  this.classList.toggle("active");

  // nextElementSibling: 현 element의 다음 element만 가져옴
  // nextSibling : 현 element의 다음 모든 것(element, text)를 상관 없이 가져옴
  let panel = this.nextElementSibling;

  // 숨겨진 글 보여주기 2 - transition 적용
  if (panel.style.maxHeight) {
    // maxHeight: element 내용영역 높이의 최대값 지정
    panel.style.maxHeight = null;
  } else {
    panel.style.maxHeight = panel.scrollHeight + "px";
    // scrollHeight: 스크롤 할 수 있는 최대 길이
  }
}

for (let accordion of accordions) {
  accordion.addEventListener("click", handleShowAccordion);
}