써치킴의 우당탕탕 개발 블로그

[HTML/CSS][Ch9][스타벅스] 순차적 애니메이션 - 전역 버튼 스타일, 요소 보이기 본문

알아두자 HTML, CSS

[HTML/CSS][Ch9][스타벅스] 순차적 애니메이션 - 전역 버튼 스타일, 요소 보이기

써치킴 2022. 1. 18. 06:15

index.html

<!DOCTYPE html>
<html lang="kor">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>startbucks Coffee Korea</title>
  <!-- 오픈그래프 -->
  <meta property="og:type" content="website" />
  <meta property="og:site_name" content="Starbucks" />
  <meta property="og:title" content="Starbucks Coffee Korea" />
  <meta property="og:description" content="스타벅스는 세계에서 가장 큰 다국적 커피 전문점으로, 64개국에서 총 23,187개의 매점을 운영하고 있습니다." />
  <meta property="og:image" content="./images/starbucks_seo.jpg" />
  <meta property="og:url" content="https://starbucks.co.kr" />
  <!-- 트위터카트 -->
  <meta property="twitter:card" content="summary" />
  <meta property="twitter:site" content="Starbucks" />
  <meta property="twitter:title" content="Starbucks Coffee Korea" />
  <meta property="twitter:description" content="스타벅스는 세계에서 가장 큰 다국적 커피 전문점으로, 64개국에서 총 23,187개의 매점을 운영하고 있습니다." />
  <meta property="twitter:image" content="./images/starbucks_seo.jpg" />
  <meta property="twitter:url" content="https://starbucks.co.kr" />
  <!-- 파비콘 -->
  <link rel="icon" href="./favicon.png">
  <!-- 브라우저 스타일 초기화 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css">
  <!-- 폰트 태그  -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Nanum+Gothic:wght@400;700&display=swap" rel="stylesheet">
  <!-- google meterial icons 추가 -->
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <!-- css 연결 -->
  <link rel="stylesheet" href="./css/main.css">
  <!-- js 연결 -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js" integrity="sha512-H6cPm97FAsgIKmlBA4s774vqoN24V5gSQL4yBTDOY2su2DeXZVhQPxFK4P6GPdnZqM9fg1G3cMv5wD7e6cFLZQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script defer src="./js/main.js"></script>
</head>
<body>

  <!-- HEADER -->
  <header>
    <div class="inner">
      
      <a href="/" class="logo">
        <img src="./images/starbucks_logo.png" alt="STARBUCKS">
      </a>

      <div class="sub-menu">
        <ul class="menu">
          <li>
            <a href="/signin">Sign In</a>
          </li>
          <li>
            <a href="javascript:void(0)">My Starbucks</a>
          </li>
          <li>
            <a href="javascript:void(0)">Customer Service & Ideas</a>
          </li>
          <li>
            <a href="javascript:void(0)">Find a Store</a>
          </li>
        </ul>
        <div class="search">
          <input type="text">
          <div class="material-icons">search</div>
        </div>
      </div>

      <ul class="main-menu">
        <li class="item">
          <div class="item__name">COFFEE</div>
          <div class="item__contents">
            <div class="contents__menu">
              <ul class="inner">
                <li>
                  <h4>커피</h4>
                  <ul>
                    <li>스타벅스 원두</li>
                    <li>스타벅스 비아</li>
                    <li>스타벅스 오리가미</li>
                  </ul>
                </li>
                <li>
                  <h4>에스프레소 음료</h4>
                  <ul>
                    <li>도피오</li>
                    <li>에스프레소 마키아또</li>
                    <li>아메리카노</li>
                    <li>마키아또</li>
                    <li>카푸치노</li>
                    <li>라떼</li>
                    <li>모카</li>
                    <li>리스트레또 비안코</li>
                  </ul>
                </li>
                <li>
                  <h4>커피 이야기</h4>
                  <ul>
                    <li>스타벅스 로스트 스팩트럼</li>
                    <li>최상의 아라비카 원두</li>
                    <li>한 잔의 커피가 완성되기까지</li>
                    <li>클로버® 커피 추출 시스템</li>
                  </ul>
                </li>
                <li>
                  <h4>최상의 커피를 즐기는 법</h4>
                  <ul>
                    <li>커피 프레스</li>
                    <li>푸어 오버</li>
                    <li>아이스 푸어 오버</li>
                    <li>커피 메이커</li>
                    <li>리저브를 매장에서 다양하게 즐기는 법</li>
                  </ul>
                </li>
              </ul>
            </div>
            <div class="contents__texture">
              <div class="inner">
                <h4>나와 어울리는 커피 찾기</h4>
                <p>스타벅스가 여러분에게 어울리는 커피를 찾아드립니다.</p>
                <h4>최상의 커피를 즐기는 법</h4>
                <p>여러가지 방법을 통해 다양한 풍미의 커피를 즐겨보세요.</p>
              </div>
            </div>
          </div>
        </li>
        <li class="item">
          <div class="item__name">MENU</div>
          <div class="item__contents">
            <div class="contents__menu">
              <ul class="inner">
                <li>
                  <h4>음료</h4>
                  <ul>
                    <li>콜드 브루</li>
                    <li>브루드 커피</li>
                    <li>에스프레소</li>
                    <li>프라푸치노</li>
                    <li>블렌디드 음료</li>
                    <li>스타벅스 피지오</li>
                    <li>티(티바나)</li>
                    <li>기타 제조 음료</li>
                    <li>스타벅스 주스(병음료)</li>
                  </ul>
                </li>
                <li>
                  <h4>푸드</h4>
                  <ul>
                    <li>베이커리</li>
                    <li>케익</li>
                    <li>샌드위치 & 샐러드</li>
                    <li>따뜻한 푸드</li>
                    <li>과일 & 요거트</li>
                    <li>스낵 & 미니 디저트</li>
                    <li>아이스크림</li>
                  </ul>
                </li>
                <li>
                  <h4>상품</h4>
                  <ul>
                    <li>머그</li>
                    <li>글라스</li>
                    <li>플라스틱 텀블러</li>
                    <li>스테인리스 텀블러</li>
                    <li>보온병</li>
                    <li>액세서리</li>
                    <li>커피 용품</li>
                    <li>패키지 티(티바나)</li>
                  </ul>
                </li>
                <li>
                  <h4>카드</h4>
                  <ul>
                    <li>실물카드</li>
                    <li>e-Gift 카드</li>
                  </ul>
                </li>
                <li>
                  <h4>메뉴 이야기</h4>
                  <ul>
                    <li>콜드 브루</li>
                    <li>스타벅스 티바나</li>
                  </ul>
                </li>
              </ul>
            </div>
            <div class="contents__texture">
              <div class="inner">
                <h4 class="new">스타벅스 티바나</h4>
                <p>다양한 찻잎과 향신료 등 개성있는 재료로 새로운 맛과 향의 티를 선보입니다.</p>
              </div>
            </div>
          </div>
        </li>
        <li class="item">
          <div class="item__name">STORE</div>
          <div class="item__contents">
            <div class="contents__menu">
              <ul class="inner">
                <li>
                  <h4>매장 찾기</h4>
                  <ul>
                    <li>퀵 검색</li>
                    <li>지역 검색</li>
                    <li>My 매장</li>
                  </ul>
                </li>
                <li>
                  <h4>매장 이야기</h4>
                  <ul>
                    <li>청담스타</li>
                    <li>티바나 인스파이어드 매장</li>
                    <li>파미에파크</li>
                  </ul>
                </li>
              </ul>
            </div>
            <div class="contents__texture">
              <div class="inner">
                <h4>매장 찾기</h4>
                <p>보다 빠르게 매장을 찾아보세요.</p>
                <h4 class="new">청담스타</h4>
                <p>스타벅스 1,000호점인 청담스타점을 만나보세요.</p>
              </div>
            </div>
          </div>
        </li>
        <li class="item">
          <div class="item__name">RESPONSIBILITY</div>
          <div class="item__contents">
            <div class="contents__menu">
              <ul class="inner">
                <li>
                  <h4>지역 사회 참여 활동</h4>
                  <ul>
                    <li>회망배달 캠페인</li>
                    <li>재능기부 카페 소식</li>
                    <li>커뮤니티 스토어</li>
                    <li>청년인재 양성</li>
                    <li>우리 농산물 사랑 캠페인</li>
                    <li>우리 문화 지키기</li>
                  </ul>
                </li>
                <li>
                  <h4>환경보호 활동</h4>
                  <ul>
                    <li>환경 발자국 줄이기</li>
                    <li>일회용 컵 없는 매장</li>
                    <li>커피 원두 재활용</li>
                  </ul>
                </li>
                <li>
                  <h4>윤리 구매</h4>
                  <ul>
                    <li>윤리적 원두 구매</li>
                    <li>공정무역 인증</li>
                    <li>커피 농가 지원 활동</li>
                  </ul>
                </li>
                <li>
                  <h4>글로벌 사회 공헌</h4>
                  <ul>
                    <li>윤리경영 보고서</li>
                    <li>스타벅스 재단</li>
                    <li>지구촌 봉사의 달</li>
                  </ul>
                </li>
              </ul>
            </div>
            <div class="contents__texture">
              <div class="inner">
                <h4>커피원두 재활용</h4>
                <p>스타벅스 커피 원두를 재활용 해보세요.</p>
              </div>
            </div>
          </div>
        </li>
        <li class="item">
          <div class="item__name">MY STARBUCKS REWARDS</div>
          <div class="item__contents">
            <div class="contents__menu">
              <ul class="inner">
                <li>
                  <h4>마이 스타벅스 리워드</h4>
                  <ul>
                    <li>마이 스타벅스 리워드 소개</li>
                    <li>등급 및 혜택</li>
                    <li>스타벅스 별</li>
                    <li>자주하는 질문</li>
                  </ul>
                </li>
                <li>
                  <h4>스타벅스 카드</h4>
                  <ul>
                    <li>스타벅스 카드 소개</li>
                    <li>스타벅스 카드 갤러리</li>
                    <li>등록 및 조회</li>
                    <li>충전 및 이용안내</li>
                    <li>분실신고/환불신청</li>
                    <li>자주하는 질문</li>
                  </ul>
                </li>
                <li>
                  <h4>스타벅스 카드 e-Gift</h4>
                  <ul>
                    <li>스타벅스 카드 e-Gift 소개</li>
                    <li>이용안내</li>
                    <li>선물하기</li>
                    <li>자주하는 질문</li>
                  </ul>
                </li>
              </ul>
            </div>
            <div class="contents__texture">
              <div class="inner">
                <h4>스타벅스 카드 등록하기</h4>
                <p>카드 등록 후 리워드 서비스를 누리고 사용내역도 조회해보세요.</p>
              </div>
            </div>
          </div>
        </li>
        <li class="item">
          <div class="item__name">WHAT'S NEW</div>
          <div class="item__contents">
            <div class="contents__menu">
              <ul class="inner">
                <li>
                  <h4>프로모션 & 이벤트</h4>
                  <ul>
                    <li>전체</li>
                    <li>스타벅스 카드</li>
                    <li>마이 스타벅스 리워드</li>
                    <li>온라인</li>
                    <li>2017 스타벅스 플래너</li>
                  </ul>
                </li>
                <li>
                  <h4>새소식</h4>
                  <ul>
                    <li>전체</li>
                    <li>상품 출시</li>
                    <li>스타벅스의 문화</li>
                    <li>스타벅스 사회공헌</li>
                    <li>스타벅스 카드출시</li>
                  </ul>
                </li>
                <li>
                  <h4>매장별 이벤트</h4>
                  <ul>
                    <li>일반 매장</li>
                    <li>신규 매장</li>
                  </ul>
                </li>
              </ul>
            </div>
            <div class="contents__texture">
              <div class="inner">
                <h4>매장별 이벤트</h4>
                <p>스타벅스의 매장 이벤트 정보를 확인 하실 수 있습니다.</p>
                <h4>소셜 스타벅스</h4>
                <p>다양한 스타벅스 SNS 채널을 통해 스타벅스를 만나보세요!</p>
              </div>
            </div>
          </div>
        </li>
      </ul>
    
    </div>

    <div class="badges">
      <div class="badge">
        <img src="./images/badge1.jpg" alt="Badge" />
      </div>
      <div class="badge">
        <img src="./images/badge2.jpg" alt="Badge" />
      </div>
    </div>
  </header>

  <!-- section : 기능적으로 특별하게 동작하진 않으나 명시적으로 섹션을 나누기 위해 사용 -->
 <!--VISUAL-->
  <section class="visual">
    <div class="inner">

      <div class="title fade-in">
        <img src="./images/visual_title.png" alt="STARBUCKS DELIGHTFUL START TO THE YEARS" />
        <a href="javascript:void(0)" class="btn btn--brown">자세히 보기</a>
      </div>
      <div class="fade-in">
        <img src="./images/visual_cup1.png" alt="new OATMEAL LATTE" class="cup1 image" />
        <img src="./images/visual_cup1_text.png" alt="오트밀 라떼" class="cup1 text" />
      </div>
      <div class="fade-in">
        <img src="./images/visual_cup2.png" alt="new STARBUCKS CARAMEL CRUMBLE MOCHA" class="cup2 image" />
        <img src="./images/visual_cup2_text.png" alt="스타벅스 카라멜 크럼블 모카" class="cup2 text" />
      </div>
      <div class="fade-in">
        <img src="./images/visual_spoon.png" alt="Spoon" class="spoon" />
      </div>

    </div>
  </section>

</body>
</html>

main.css

/* COMMON */
body{
  color: #333;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.4;
  font-family: 'Nanum Gothic', sans-serif;
  height: 3000px;
}
/* 이미지는 하나의 블록(상자)처럼 취급됨 */
img {
  display: block;
}
/* a 태그는 선 사용 X */
a {
  text-decoration: none;
}
/* INNER */
.inner {
  width: 1100px;
  margin: 0 auto;
  position: relative;    /* 자신 기준 */
}
/* BUTTON */
.btn {
  width: 130px;
  padding: 10px;
  border: 2px solid #333;
  border-radius: 4px;
  color: #333;
  font-size: 16px;
  font-weight: 700;
  text-align: center;
  cursor: pointer;
  box-sizing: border-box;
  display: block;
  transition: .4s;
}
.btn:hover {
  background-color: #333;
  color: #FFF;
}
.btn.btn--reverse {
  background-color: #333;
  color: #FFF;
}
.btn.btn--reverse:hover {
  background-color: transparent;
  color: #333;
}
.btn.btn--brown {
  color: #592B18;
  border-color: #592B18;
}
.btn.btn--brown:hover {
  color: #FFF;
  background-color: #592B18;
}
.btn.btn--gold {
  color: #D9AA8A;
  border-color: #D9AA8A;
}
.btn.btn--gold:hover {
  color: #FFF;
  background-color: #D9AA8A;
}
.btn.btn--white {
  color: #FFF;
  border-color: #FFF;
}
.btn.btn--white:hover {
  color: #333;
  background-color: #FFF;
}

/* HEADER */
header {
  width: 100%;
  background-color: #f6f5f0;
  border-bottom: 1px solid #c8c8c8;
  position: fixed;
  top: 0;
  z-index: 9;
}
header > .inner {
  height: 120px;
}
header .logo {
  height: 75px;
  position: absolute;   /* 부모 기준 */
  top: 0 ;
  bottom: 0;
  left: 0;
  margin: auto;
}
header .sub-menu {
  position: absolute;
  top: 10px;
  right: 0;
  display: flex;
}
header .sub-menu ul.menu {
  font-family: Arial, sans-serif; /* Arial가 있으면 적용, 없으면 sans-serif 적용 */
  display: flex; /* 수직 -> 수평으로 변경 */
}
header .sub-menu ul.menu li {
  position: relative;
}
/* 가상요소 선택자(구분선 만들기) */
header .sub-menu ul.menu li::before {
  content: "";
  width: 1px;
  height: 12px;
  background-color: #e5e5e5;
  position: absolute;
  top: 0;
  bottom: 0;
  margin: auto;
}
/* 제일 왼쪽 구분선 display : none 처리 */
header .sub-menu ul.menu li:first-child:before {
  display: none;
}
/* a 태그가 인라인 요소이기 때문에 display: block을 추가해서 블록요소로 사용 */
header .sub-menu ul.menu li a {
  font-size: 12px;
  padding: 11px 16px;
  display: block;
  color: #656565;
}
/* 서브 메뉴에 마우스 올리면 검정색으로 변경됨 */
header .sub-menu ul.menu li a:hover {
  color: #000;

}
/* 검색 부분 */
header .sub-menu .search {
  height: 34px;
  position: relative;
}
header .sub-menu .search input {
  width: 36px;
  height: 34px;
  padding: 4px 10px;
  border: 1px solid #ccc;
  box-sizing: border-box;
  border-radius: 5px;
  outline: none;
  background-color: #fff;
  color: #777;
  font-size: 12px;
  transition: width .4s;  /* 가로길이 0.4초동안 전환효과 */
}
header .sub-menu .search input:focus {
  width: 190px;
  border-color: #669900;
}
header .sub-menu .search .material-icons {
  height: 24px;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 5px;
  margin: auto;
  transition: .4s;
}
header .sub-menu .search.focused .material-icons {
  opacity : 0;
}
header .main-menu {
  display: flex;
  position: absolute;
  bottom: 0;
  right: 0;
  z-index: 1;
}
header .main-menu .item {

}
header .main-menu .item .item__name {
  padding: 10px 20px 34px 20px;
  font-family: Arial, sans-serif;
  font-size: 13px;
}
header .main-menu .item:hover .item__name {
  background-color: #2c2a29;
  color: #669900;
  border-radius: 6px 6px 0 0;
}
header .main-menu .item .item__contents {
  width: 100%;
  position: fixed;     /* 뷰포트를 기준으로 함 */
  left: 0;
  display: none;
}
header .main-menu .item:hover .item__contents {
  display: block;
}
header .main-menu .item .item__contents .contents__menu {
  background-color: #2C2A29;
}
header .main-menu .item .item__contents .contents__menu > ul {
  display: flex;
  padding: 20px 0;
}
header .main-menu .item .item__contents .contents__menu > ul > li{
  width: 220px;
}
header .main-menu .item .item__contents .contents__menu > ul > li h4{
  padding: 3px 0 12px 0;
  font-size: 14px;
  color: #fff;
}
header .main-menu .item .item__contents .contents__menu > ul > li ul li{
  padding: 5px 0;
  font-size: 12px;
  color: #999;
  cursor: pointer;
}
header .main-menu .item .item__contents .contents__menu > ul > li ul li:hover {
  color: #669900;
}
header .main-menu .item .item__contents .contents__texture {
  font-size: 12px;
  padding: 26px 0;
  background-image: url("../images/main_menu_pattern.jpg");
}
header .main-menu .item .item__contents .contents__texture h4 {
  color: #999;
  font-weight: 700;
}
header .main-menu .item .item__contents .contents__texture p {
  color: #669900;
  margin: 4px 0 14px;
}
header .badges {
  position: absolute;
  top: 132px;
  right: 12px;
}
header .badges .badge {
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 12px;
  box-shadow: 4px 4px 10px rgba(0, 0, 0, .15);
  cursor: pointer;
}


/* VISUAL */
.visual {
  margin-top: 120px;
  background-image: url(../images/visual_bg.jpg);
  background-position: center;
}
.visual .inner {
  height: 646px;
}
.visual .title {
  position: absolute;
  top: 88px;
  left: -10px;
}
.visual .title .btn {
  position: absolute;
  top: 259px;
  left: 173px;
}
.visual .cup1.image {
  position: absolute;
  bottom: 0;
  right: -47px;
}
.visual .cup1.text {
  position: absolute;
  top: 38px;
  right: 171px;
}
.visual .cup2.image {
  position: absolute;
  bottom: 0;
  right: 162px;
}
.visual .cup2.text {
  position: absolute;
  top: 321px;
  right: 416px;
}
.visual .spoon {
  position: absolute;
  bottom: 0;
  left: 275px;
}
.visual .fade-in {
  opacity: 0;
}

main.js

const searchEl = document.querySelector('.search');
const searchInputEl = searchEl.querySelector('input');    // searchEl 안에서 input 요소를 찾음

// search라는 클래스를 갖고 있는 요소를 클릭하면 input 요소에 포커스하라.
searchEl.addEventListener('click', function () {
  searchInputEl.focus();
});

// input 요소가 포커스되면 search 클래스 요소에 focused라는 클래스 추가
searchInputEl.addEventListener('focus', function () {
  searchEl.classList.add('focused');
  // input 요소에 placeholder : 통합검색 설정
  searchInputEl.setAttribute('placeholder', '통합검색');    
});

// 포커스 해제됐을 때
searchInputEl.addEventListener('blur', function () {
  searchEl.classList.remove('focused');
  // input 요소에 placeholder : 통합검색 설정
  searchInputEl.setAttribute('placeholder', '');    
});

// 배지
const badgeEl = document.querySelector('header .badges');

// window 객체 : 브라우저 창을 의미
/* 화면을 스크롤할 때 (스크롤할때마다 해당함수가 실행되기 때문에 사이트 자체가 무거워짐 -> 화면 버벅임 현상 발생)
window.addEventListener('scroll', function () {
  console.log('scroll!!');
}); */
// _.throttle(함수, 시간) : 0.3초 단위(사용자 지정)로 부하를 줘서 함수가 연속으로 실행되는 것을 방지 (lodash.js)
window.addEventListener('scroll', _.throttle(function () {
  // window.scrollY : 화면이 몇 px 지점에 위치하는지 확인
  if(window.scrollY > 500) {
    // 배지 숨기기
    // badgeEl.style.display = 'none'; > 이렇게 하면 부자연스러워 보일 수 있어서 gsap.js 사용
    // gsap.to(요소, 지속시간, 옵션)
    // badgeEl 요소를 0.6초 동안 opacity : 0(점점 투명해지는) + display : none 애니메이션이 처리
    gsap.to(badgeEl, .6, {
      opacity : 0,
      display : 'none'
    })
  }else{
    // 배지 보이기
    // badgeEl.style.display = 'block';
    // badgeEl 요소를 0.6초 동안 opacity : 1(점점 나타나는) + display : block 애니메이션이 처리
    gsap.to(badgeEl, .6, {
      opacity : 1,
      display : 'block'
    })
  }
}, 300));

/**
 * 순서대로 나타나는 기능
 */
// 나타날 요소들(.fade-in) 찾기.
const fadeEls = document.querySelectorAll('.visual .fade-in')
// 나타날 요소들을 하나씩 반복해서 처리!
fadeEls.forEach(function (fadeEl, index) {
  // 각 요소들을 순서대로(delay) 보여지게 함!
  gsap.to(fadeEl, 1, {
    delay: (index + 1) * .7,    // 0.7, 1.4, 2.1, 2.8
    opacity: 1
  })
});

출력

Comments