Junhyunny's Devlogs

글 검색

기술 글 제목, 본문, 카테고리에서 검색합니다.

    이전 화면으로

    아코디언 뷰

    • html
    • css
    • javascript
    이 글의 목차

    1. Accordion View

    내용이 많을 경우 내부 컨텐츠를 접거나 펴서 볼 수 있는 아코디언(accordion) 뷰를 구현하였다.

    1.1. HTML 코드

    • .contract__header 클래스를 지닌 블록은 헤더 부분이며 이를 눌러 내용이 담긴 블록을 열었다 닫을 수 있다.
    • .contract__content 클래스를 지닌 블록은 컨텐츠 부분이며 해당 블록이 열리고, 닫힌다.
    <div class="contract__header">
        <p class="contract__header--title">이용 약관</p>
        <div class="contract__header--icon"></div>
    </div>
    <div class="contract__content">
        <p class="contract__content--title">Lorem ipsum dolor sit</p>
        <p class="contract__content--detail">
            amet consectetur adipisicing elit.
            Magnam facilis maxime minima expedita, error perferendis amet facere veritatis?
            Quibusdam architecto laudantium incidunt, perspiciatis quaerat consequatur provident similique unde aut quisquam!
        </p>
        <br/>
        <p class="contract__content--title">Lorem ipsum dolor sit</p>
        <p class="contract__content--detail">
            amet consectetur adipisicing elit.
            Rerum id atque nesciunt vero, debitis culpa dolor.
            Perspiciatis illo recusandae, facilis reiciendis exercitationem, incidunt ipsam officiis, aut non maiores quis ullam.
        </p>
    </div>
    
    <div class="contract__header">
        <p class="contract__header--title">주의 사항</p>
        <div class="contract__header--icon"></div>
    </div>
    <div class="contract__content">
        <p class="contract__content--title">Lorem ipsum dolor sit</p>
        <p class="contract__content--detail">
            amet consectetur adipisicing elit.
            Magnam facilis maxime minima expedita, error perferendis amet facere veritatis?
            Quibusdam architecto laudantium incidunt, perspiciatis quaerat consequatur provident similique unde aut quisquam!
        </p>
        <br/>
        <p class="contract__content--title">Lorem ipsum dolor sit</p>
        <p class="contract__content--detail">
            amet consectetur adipisicing elit.
            Rerum id atque nesciunt vero, debitis culpa dolor.
            Perspiciatis illo recusandae, facilis reiciendis exercitationem, incidunt ipsam officiis, aut non maiores quis ullam.
        </p>
    </div>

    1.2. CSS 코드

    • 영역 표시나 크기를 설정한 속성들에 대한 설명은 제외하였다.
    • 설명에 대한 내용은 가독성을 높이기 위해 주석에 작성하였다.
    body {
        border: 1px solid #555555;
        width: 75%;
        padding: 5px;
    }
    
    p {
        padding: 0;
        margin: 0;
    }
    
    .contract__header {
        position: relative;
        border: 1px solid #555555;
        width: 100%;
        height: 3rem;
    }
    
    .contract__header--title {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
    
    .contract__header--icon {
        position: absolute;
        top: 50%;
        right: 3rem;
        transform: translateY(-50%);
    }
    
    .contract__header--icon:before {
        /* 헤더 부분 오른쪽에 표시되는 화살표 */
        content: ">";
        display: inline-block;
        font-size: 1.5rem;
        font-weight: 700;
        transform: rotate(-90deg);
        /* 회전 애니메이션 처리 */
        transition: transform 0.5s;
    }
    
    .contract__header.on .contract__header--icon:before {
        /* 헤더 부분이 선택된 경우 오른쪽 아이콘이 회전됩니다. */
        transform: rotate(90deg);
    }
    
    .contract__content {
        /* 최대 높이를 0으로 지정합니다. */
        max-height: 0;
        /* 영역을 벗어나는 내용은 보이지 않도록 hidden 처리합니다. */
        overflow: hidden;
        /* max-height 변경을 애니메이션 처리합니다. */
        transition: max-height 0.5s ease-out;
    }
    
    .contract__content--title {
        font-size: 1.5rem;
        font-weight: 700;
        color: #3e7ec7;
    }
    
    .contract__content--detail {
        font-size: 1rem;
        font-weight: 400;
        color: #000000;
    }

    1.3. JavaScript 코드

    • .contract__header 클래스를 지닌 DOM 객체들을 찾아서 클릭 이벤트를 지정한다.
    • openAccordion(event) 함수
      • 현재 선택된 DOM 객체가 .on 클래스를 지녔는지 여부에 따라 .on 클래스를 제거하거나 추가한다.
      • 바로 옆 형제 DOM 객체의 maxHeight 값이 존재하는지 여부에 따라 제거하거나 scrollHeight 값으로 대체한다.
    const accordionHeaders = document.querySelectorAll(".contract__header");
    accordionHeaders.forEach((accordionHeader) => {
        accordionHeader.addEventListener("click", (e) => openAccordion(e));
    });
    
    function openAccordion(event) {
        const target = event.currentTarget;
        if (target.classList.contains("on")) {
            target.classList.remove("on");
        } else {
            target.classList.add("on");
        }
        const sibling = target.nextElementSibling;
        if (sibling.style.maxHeight) {
            sibling.style.maxHeight = null;
        } else {
            sibling.style.maxHeight = sibling.scrollHeight + "px";
        }
    }

    2. 결과

    CodePen에서 예제 열기

    KEEP READING

    DISCUSSION

    댓글