프로젝트/블로그 사이트

4. 홈페이지 구현하기

syleemomo 2023. 7. 9. 15:32
728x90

홈페이지 뼈대코드 구성하기

<!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>Sunrise 블로그 - 홈</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  <link href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp" rel="stylesheet">
  <link rel="stylesheet" href="../css/home.css">
</head>
<body>
  <script src="../js/scroll.js"></script>
  <script src="../js/home.js"></script>
</body>
</html>

html 폴더에 home.html 파일을 생성하고 위와 같이 작성한다. 폰트아우썸 아이콘과 구글 머터리얼 아이콘을 함께 사용한다. 

<link href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp" rel="stylesheet">

구글 머터리얼 아이콘은 CDN 형태로 위와 같이 추가하면 사용이 가능하다.

 

헤더 디자인하기

홈페이지 헤더에는 사용자 정보를 조회하기 위한 아바타 아이콘과 알림 메세지를 조회하기 위한 종모양 아이콘이 위치하고 있다.

헤더

<!-- 헤더 -->
  <header>
    <a href="#" class="logo"><i class="fa-brands fa-blogger"></i>Sunblog</a>
    
    <div class="menu">
      <nav class="navbar">
        <ul>
          <li><a href="#">
            <span class="material-icons">
              notifications
            </span>
          </a></li>
          <li><a href="#">
            <div class="account">
              <img src="../imgs/avatar.jpg" alt="">
            </div>
          </a></li>
        </ul>
      </nav>
      
      <div class="mode">
        <i class="fa-solid fa-toggle-on"></i>
        <i class="fa-solid fa-toggle-off active"></i>
      </div>
    </div>
  </header>

홈페이지의 헤더는 랜딩페이지 헤더와 유사하다. 다만, 네비게이션 메뉴 대신에 알림 메세지를 조회하기 위한 종모양 아이콘과 로그인후 사용자 정보를 확인할 수 있는 아바타 아이콘이 있다. 

<!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>Sunrise 블로그 - 홈</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  <link href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp" rel="stylesheet">
  <link rel="stylesheet" href="../css/home.css">
</head>
<body>
  
  <!-- 헤더 -->
  <header>
    <a href="#" class="logo"><i class="fa-brands fa-blogger"></i>Sunblog</a>
    
    <div class="menu">
      <nav class="navbar">
        <ul>
          <li><a href="#">
            <span class="material-icons">
              notifications
            </span>
          </a></li>
          <li><a href="#">
            <div class="account">
              <img src="../imgs/avatar.jpg" alt="">
            </div>
          </a></li>
        </ul>
      </nav>
      
      <div class="mode">
        <i class="fa-solid fa-toggle-on"></i>
        <i class="fa-solid fa-toggle-off active"></i>
      </div>
    </div>
  </header>

  
  <script src="../js/scroll.js"></script>
  <script src="../js/home.js"></script>
</body>
</html>

현재까지의 home.html 파일은 위와 같다. 

@import url('reset.css');
@import url('global.css');
@import url('header.css');
@import url('footer.css');
@import url('animation.css');

css 폴더에 home.css 파일을 생성하고 위와 같이 작성한다. 미리 만들어둔 헤더/푸터/애니메이션 스타일을 재사용한다. 홈페이지에서는 애니메이션 스타일의 left, right 클래스를 HTML 문서에서 사용하지 않을 예정이므로 animation.css 파일을 임포트해도 된다.

header .navbar ul li .material-icons{ /* 종모양 스타일링 추가 */
  font-size: 2rem;
}
header .navbar ul li .account img{ /* 아바타 스타일링 추가 */
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
}

home.css 파일에 위 코드를 추가한다. 종모양과 아바타 아이콘 스타일이 추가되었다. 헤더 스타일은 재사용하기 때문에 코드량이 많이 줄어든 모습이다. 

@import url('reset.css');
@import url('global.css');
@import url('header.css');
@import url('footer.css');
@import url('animation.css');

header .navbar ul li .material-icons{ /* 종모양 스타일링 추가 */
  font-size: 2rem;
}
header .navbar ul li .account img{ /* 아바타 스타일링 추가 */
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
}

현재까지의 home.css 파일은 위와 같다. 

 

푸터 디자인하기 

푸터

<!-- 푸터 -->
  <section class="footer">
    <div class="icons">
      <a href="https://ko-kr.facebook.com/" class="fab fa-facebook-f"></a>
      <a href="https://twitter.com/?lang=ko" class="fab fa-twitter"></a>
      <a href="https://www.instagram.com/" class="fab fa-instagram"></a>
      <a href="https://github.com/" class="fab fa-github"></a>
      <a href="https://www.pinterest.co.kr/" class="fab fa-pinterest"></a>
      <div class="scroll-up"><i class="fa-solid fa-circle-up"></i></div>
    </div>
    <div class="credit"><i class="fa-brands fa-blogger"></i>Sunrise. All rights reserved </div>
  </section>

home.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>Sunrise 블로그 - 홈</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  <link href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp" rel="stylesheet">
  <link rel="stylesheet" href="../css/home.css">
</head>
<body>
  
  <!-- 헤더 -->
  <header>
    <a href="#" class="logo"><i class="fa-brands fa-blogger"></i>Sunblog</a>
    
    <div class="menu">
      <nav class="navbar">
        <ul>
          <li><a href="#">
            <span class="material-icons">
              notifications
            </span>
          </a></li>
          <li><a href="#">
            <div class="account">
              <img src="../imgs/avatar.jpg" alt="">
            </div>
          </a></li>
        </ul>
      </nav>
      
      <div class="mode">
        <i class="fa-solid fa-toggle-on"></i>
        <i class="fa-solid fa-toggle-off active"></i>
      </div>
    </div>
  </header>


  <!-- 푸터 -->
  <section class="footer">
    <div class="icons">
      <a href="https://ko-kr.facebook.com/" class="fab fa-facebook-f"></a>
      <a href="https://twitter.com/?lang=ko" class="fab fa-twitter"></a>
      <a href="https://www.instagram.com/" class="fab fa-instagram"></a>
      <a href="https://github.com/" class="fab fa-github"></a>
      <a href="https://www.pinterest.co.kr/" class="fab fa-pinterest"></a>
      <div class="scroll-up"><i class="fa-solid fa-circle-up"></i></div>
    </div>
    <div class="credit"><i class="fa-brands fa-blogger"></i>Sunrise. All rights reserved </div>
  </section>
  
  <script src="../js/scroll.js"></script>
  <script src="../js/home.js"></script>
</body>
</html>

현재까지의 home.html 파일은 위와 같다. 

/* 푸터 */
.footer{
  position: fixed;
  z-index: 1;
  bottom: 0;
  transition: 1s ease-in-out; 
}
.footer.hide{
  opacity: 0;
  height: 0;
}

웹페이지 사용자가 스크롤바를 내릴때 푸터를 화면에서 보이지 않도록 할 예정이다. 

@import url('reset.css');
@import url('global.css');
@import url('header.css');
@import url('footer.css');
@import url('animation.css');

/* 헤더 */
header .navbar ul li .material-icons{ /* 종모양 스타일링 추가 */
  font-size: 2rem;
}
header .navbar ul li .account img{ /* 아바타 스타일링 추가 */
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
}

/* 푸터 */
.footer{
  position: fixed;
  z-index: 1;
  bottom: 0;
  transition: 1s ease-in-out; 
}
.footer.hide{
  opacity: 0;
  height: 0;
}

현재까지의 home.css 파일은 위와 같다. 

 

컨텐츠 섹션 디자인하기 

<!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>Sunrise 블로그 - 홈</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  <link href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp" rel="stylesheet">
  <link rel="stylesheet" href="../css/home.css">
</head>
<body>
  
  <!-- 헤더 -->
  <header>
    <a href="#" class="logo"><i class="fa-brands fa-blogger"></i>Sunblog</a>
    
    <div class="menu">
      <nav class="navbar">
        <ul>
          <li><a href="#">
            <span class="material-icons">
              notifications
            </span>
          </a></li>
          <li><a href="#">
            <div class="account">
              <img src="../imgs/avatar.jpg" alt="">
            </div>
          </a></li>
        </ul>
      </nav>
      
      <div class="mode">
        <i class="fa-solid fa-toggle-on"></i>
        <i class="fa-solid fa-toggle-off active"></i>
      </div>
    </div>
  </header>

  <!-- 컨텐츠 섹션 -->
  <section class="blog-container">
    <div class="follow bottom-line padding">
      
    </div>
    <div class="my-blog bottom-line padding">

    </div>
    <div class="favorite-blog bottom-line padding">

    </div>
    <div class="latest-blog bottom-line padding">

    </div>
  </section>


  <!-- 푸터 -->
  <section class="footer">
    <div class="icons">
      <a href="https://ko-kr.facebook.com/" class="fab fa-facebook-f"></a>
      <a href="https://twitter.com/?lang=ko" class="fab fa-twitter"></a>
      <a href="https://www.instagram.com/" class="fab fa-instagram"></a>
      <a href="https://github.com/" class="fab fa-github"></a>
      <a href="https://www.pinterest.co.kr/" class="fab fa-pinterest"></a>
      <div class="scroll-up"><i class="fa-solid fa-circle-up"></i></div>
    </div>
    <div class="credit"><i class="fa-brands fa-blogger"></i>Sunrise. All rights reserved </div>
  </section>
  
  <script src="../js/scroll.js"></script>
  <script src="../js/home.js"></script>
</body>
</html>

home.html 파일의 헤더와 푸터 영역 사이에 컨텐츠 섹션에 대한 틀을 잡아둔다. 공통적인 스타일을 적용하고 스타일 코드를 재활용하기 위하여 bottom-line 과 padding 스타일은 따로 빼서 정의한다. 

/* 공통 스타일 */
.bottom-line{
  border-bottom: 1px solid #eee;
}
.padding{
  padding: 2rem 0rem;
}
/* 블로그 (컨텐츠) 섹션 */
.blog-container{
  width: 50vw;
  margin: 0 auto;
}

home.css 파일에 위의 코드를 추가한다. 

 

구독중 / 구독자 

구독중/구독자 섹션

<div class="follow bottom-line padding">
  <ul>
    <li><a>구독중</a><span>37</span></li>
    <li><a>구독자</a><span>119</span></li>
  </ul>
</div>

home.html 파일에 위의 코드를 추가한다. 구독중, 구독자 정보를 보여주기 위한 코드이다. 

.blog-container .follow > ul{ /* 구독중 */
  display: flex;
  flex-wrap: wrap;
}
.blog-container .follow > ul li{
  font-size: 1.2rem;
  padding-right: 1.2rem;
}
.blog-container .follow > ul li a{
  padding-right: .3rem;
  color: var(--primary-color);
  cursor: pointer;
}
.blog-container .follow > ul li a:hover{
  text-decoration: underline;
}

home.css 파일에 위 코드를 추가한다. 구독중, 구독자 정보를 수평으로 나열하기 위하여 display: flex 를 적용한다. 

 

최근에 내가 업로드한 글 

최근 내가 업로드한 글

<div class="my-blog bottom-line padding">
  <h3>최근 내가 업로드한 글</h3>
  <ul>
    <li></li>
    <li></li>
    <li></li>
  </ul>
  <a href="#"><button>더보기</button></a>
</div>

home.html 파일에 위의 코드를 추가한다. 최근에 내가 업로드한 글을 보여주기 위한 코드이다. 

<div class="blog">
  <div class="left">
    <ul>
      <li class="category-name"><a href="#">여행</a></li>
      <li class="posting-time">1시간전</li>
      <li><a href="#" class="likes">공감</a><span>9</span></li>
    </ul>
  </div>
  <div class="middle">
    <ul>
      <li><h3>제주도 오른 까페 방문하기</h3></li>
      <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
      <li>
       <ul>
         <li>
           <div class="account">
             <img src="../imgs/avatar.jpg" alt="">
             촌부 <span>by 농돌이</span>
           </div>
         </li>
         <li><button>구독하기</button></li>
       </ul>
      </li>
    </ul>
  </div>
  <div class="right">
    <ul>
      <li>
       <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
      </li>
    </ul>
  </div>
</div>

하나의 블로그 글에 대한 HTML 코드는 story.html 파일에서 작성했던 것과 동일하다. li 태그에는 story.html 파일의 해당 코드를 재사용하기 위하여 복사 붙여넣기 한다. 하나의 블로그 글은 리액트에서는 컴포넌트라고 한다. 즉, 재사용이 가능한 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>Sunrise 블로그 - 홈</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  <link href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp" rel="stylesheet">
  <link rel="stylesheet" href="../css/home.css">
</head>
<body>
  
  <!-- 헤더 -->
  <header>
    <a href="#" class="logo"><i class="fa-brands fa-blogger"></i>Sunblog</a>
    
    <div class="menu">
      <nav class="navbar">
        <ul>
          <li><a href="#">
            <span class="material-icons">
              notifications
            </span>
          </a></li>
          <li><a href="#">
            <div class="account">
              <img src="../imgs/avatar.jpg" alt="">
            </div>
          </a></li>
        </ul>
      </nav>
      
      <div class="mode">
        <i class="fa-solid fa-toggle-on"></i>
        <i class="fa-solid fa-toggle-off active"></i>
      </div>
    </div>
  </header>

  <!-- 컨텐츠 섹션 -->
  <section class="blog-container">
    <div class="follow bottom-line padding">
      <ul>
        <li><a>구독중</a><span>37</span></li>
        <li><a>구독자</a><span>119</span></li>
      </ul>
    </div>
    <div class="my-blog bottom-line padding">
      <h3>최근 내가 업로드한 글</h3>
      <ul>
        <li>
          <div class="blog">
            <div class="left">
              <ul>
                <li class="category-name"><a href="#">여행</a></li>
                <li class="posting-time">1시간전</li>
                <li><a href="#" class="likes">공감</a><span>9</span></li>
              </ul>
            </div>
            <div class="middle">
              <ul>
                <li><h3>제주도 오른 까페 방문하기</h3></li>
                <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
                <li>
                 <ul>
                   <li>
                     <div class="account">
                       <img src="../imgs/avatar.jpg" alt="">
                       촌부 <span>by 농돌이</span>
                     </div>
                   </li>
                   <li><button>구독하기</button></li>
                 </ul>
                </li>
              </ul>
            </div>
            <div class="right">
              <ul>
                <li>
                 <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li>
          <div class="blog">
            <div class="left">
              <ul>
                <li class="category-name"><a href="#">여행</a></li>
                <li class="posting-time">1시간전</li>
                <li><a href="#" class="likes">공감</a><span>9</span></li>
              </ul>
            </div>
            <div class="middle">
              <ul>
                <li><h3>제주도 오른 까페 방문하기</h3></li>
                <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
                <li>
                 <ul>
                   <li>
                     <div class="account">
                       <img src="../imgs/avatar.jpg" alt="">
                       촌부 <span>by 농돌이</span>
                     </div>
                   </li>
                   <li><button>구독하기</button></li>
                 </ul>
                </li>
              </ul>
            </div>
            <div class="right">
              <ul>
                <li>
                 <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li>
          <div class="blog">
            <div class="left">
              <ul>
                <li class="category-name"><a href="#">여행</a></li>
                <li class="posting-time">1시간전</li>
                <li><a href="#" class="likes">공감</a><span>9</span></li>
              </ul>
            </div>
            <div class="middle">
              <ul>
                <li><h3>제주도 오른 까페 방문하기</h3></li>
                <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
                <li>
                 <ul>
                   <li>
                     <div class="account">
                       <img src="../imgs/avatar.jpg" alt="">
                       촌부 <span>by 농돌이</span>
                     </div>
                   </li>
                   <li><button>구독하기</button></li>
                 </ul>
                </li>
              </ul>
            </div>
            <div class="right">
              <ul>
                <li>
                 <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
                </li>
              </ul>
            </div>
          </div>
        </li>
      </ul>
      <a href="#"><button>더보기</button></a>
    </div>
    <div class="favorite-blog bottom-line padding">

    </div>
    <div class="latest-blog bottom-line padding">

    </div>
  </section>


  <!-- 푸터 -->
  <section class="footer">
    <div class="icons">
      <a href="https://ko-kr.facebook.com/" class="fab fa-facebook-f"></a>
      <a href="https://twitter.com/?lang=ko" class="fab fa-twitter"></a>
      <a href="https://www.instagram.com/" class="fab fa-instagram"></a>
      <a href="https://github.com/" class="fab fa-github"></a>
      <a href="https://www.pinterest.co.kr/" class="fab fa-pinterest"></a>
      <div class="scroll-up"><i class="fa-solid fa-circle-up"></i></div>
    </div>
    <div class="credit"><i class="fa-brands fa-blogger"></i>Sunrise. All rights reserved </div>
  </section>
  
  <script src="../js/scroll.js"></script>
  <script src="../js/home.js"></script>
</body>
</html>

현재까지의 home.html 파일은 위와 같다. 

.blog-container .blog{
  display: flex;
  padding: 2rem 1rem;
  border-bottom: 1px solid #eee;
}
.blog-container .blog > div > ul{
  display: flex;
  flex-flow: column;
  height: 100%;
}
.blog-container .blog .left, 
.blog-container .blog .right{
  width: 150px;
  min-width: 150px;
}
.blog-container .blog .left .posting-time{
  margin-top: 1rem;
  margin-bottom: .3rem;
  color: #aaa;
}
.blog-container .blog .left .category-name a{
  color: var(--primary-color);
}
.blog-container .blog .left .category-name a:hover{
  color: var(--secondary-color);
  text-decoration: underline;
}
.blog-container .blog .left .likes{
  margin-right: .5rem;
}
.blog-container .blog .left span{
  color: var(--primary-color);
}
.blog-container .blog .middle{
  flex-grow: 1;
  padding: 0rem 1.5rem;
}
.blog-container .blog .middle > ul h3{
  font-weight: 700;
  font-size: 1.5rem;
}
.blog-container .blog .middle > ul p{
  padding: 1rem 0;
  line-height: 1.3rem;
  font-size: 1rem;
  color: gray;
}
.blog-container .blog .middle .account{
  display: flex;
  align-items: center;
}
.blog-container .blog .middle .account img{
  width: 2rem;
  height: 2rem;
  margin-right: .5rem;
  border-radius: 50%;
  cursor: pointer;
  object-fit: cover;
}
.blog-container .blog .middle .account span{
  font-size: .9rem;
  color: #bbb;
  margin-left: .5rem;
}
.blog-container .blog .middle > ul ul{
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.blog-container .blog .middle > ul ul button{
  width: 5rem;
  height: 2rem;
  color: #333;
  cursor: pointer;
  border: 2px solid #eee;
  border-radius: 1rem;
  background: #fff;
  transform: .2s;
}
.blog-container .blog .middle > ul ul button:hover{
  box-shadow: 0 0 .1rem rgba(0, 0, 0, .3);
}
.blog-container .blog .right ul,
.blog-container .blog .right ul li{
  height: 100%;
}
.blog-container .blog .right img{
  height: 100%;
  width: 100%;
  object-fit: cover;
  object-position: center;
}

하나의 블로그 글에 대한 디자인은 story.css 의 위 코드와 유사하다. 그래서 위 코드를 일단 home.css 파일에 복사붙여넣기 한다.

.blog-container .blog{ /* 수정 */
  display: flex;
  flex-wrap: wrap;
  flex-flow: column-reverse;
  padding: 2rem 1rem;
  margin-bottom: 2.5rem;
  border-bottom: none;
  box-shadow: 0 0 .2rem rgba(0, 0, 0, .3);
  cursor: pointer;
}

home.css 파일에서 해당 선택자 부분을 수정한다. 스토리 페이지의 반응형 웹에서 작성했던 것처럼 블로그 글을 카드 형태로 변환해서 보여줄 것이기 때문에 위와 같이 flex-flow: column-reverse 를 적용하여 세로방향으로 나열한다. 

.blog-container .blog .left, 
.blog-container .blog .right{ /* 수정 */
  width: 100%;
  min-width: 100%;
  opacity: 1;
  transform: none;
}

home.css 파일에서 해당 선택자 부분을 수정한다. 이미지의 너비는 카드 컴포넌트 너비를 채울수 있도록 width: 100% 로 설정한다. animation.css 의 left, right 클래스와 해당 코드의 left, right 클래스가 충돌하여 이미지가 화면에 보이지 않는다. 그래서 css 우선순위에 따라 opacity: 1 과 transform: none 을 적용하여 화면에 이미지가 보일수 있도록 하였다. 

.blog-container .blog .middle{ /* 수정 */
  flex-grow: 1;
  margin: 2rem 0rem; 
  padding: 0rem 0rem;
}

home.css 파일에서 해당 선택자 부분을 수정한다. middle 컨텐츠는 위아래 마진을 적용한다. 

.blog-container > div:not(.follow){ /* 추가 */
  position: relative;
}
.blog-container > div:not(.follow) > ul{ /* 추가 */
  display: flex;
}
.blog-container > div:not(.follow) > ul > li:nth-child(2){ /* 추가 */
  margin: 0rem 2rem;
}
.blog-container > div:not(.follow) > h3{  /* 추가 */
  font-size: 2rem;
  margin-bottom: 2rem;
}
.blog-container > div:not(.follow) > a button{ /* 추가 */
  width: 5rem;
  height: 2rem;
  color: #fff;
  cursor: pointer;
  border: none;
  background: #333;
  box-shadow: 0 0 .3rem rgba(0, 0, 0, .3);
  position: absolute; 
  bottom: 1.5rem; right: 0;
  transform: .2s;
}
.blog-container > div:not(.follow) > a button:hover{ /* 추가 */
  background: var(--secondary-color);
  box-shadow: none;
}

home.css 파일에 위 코드를 추가한다. display: flex 를 적용해서 블로그 글을 수평으로 나열한다. 3개의 블로그 글 중에서 중앙에 위치한 블로그 글의 좌우 마진을 적용한다. 더보기 버튼은 position: absolute 와 right: 0 을 설정하여 블로그 컨테이너의 우측에 위치하도록 한다. 

@import url('reset.css');
@import url('global.css');
@import url('header.css');
@import url('footer.css');
@import url('animation.css');

/* 헤더 */
header .navbar ul li .material-icons{ /* 종모양 스타일링 추가 */
  font-size: 2rem;
}
header .navbar ul li .account img{ /* 아바타 스타일링 추가 */
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
}

/* 푸터 */
.footer{
  position: fixed;
  z-index: 1;
  bottom: 0;
  transition: 1s ease-in-out; 
}
.footer.hide{
  opacity: 0;
  height: 0;
}

/* 공통 스타일 */
.bottom-line{
  border-bottom: 1px solid #eee;
}
.padding{
  padding: 2rem 0rem;
}
/* 컨텐츠 섹션 */
.blog-container{
  width: 50vw;
  margin: 0 auto;
}

.blog-container .follow > ul{ /* 구독중 */
  display: flex;
  flex-wrap: wrap;
}
.blog-container .follow > ul li{
  font-size: 1.2rem;
  padding-right: 1.2rem;
}
.blog-container .follow > ul li a{
  padding-right: .3rem;
  color: var(--primary-color);
  cursor: pointer;
}
.blog-container .follow > ul li a:hover{
  text-decoration: underline;
}

/* 블로그 섹션 */
.blog-container .blog{ /* 수정 */
  display: flex;
  flex-wrap: wrap;
  flex-flow: column-reverse;
  padding: 2rem 1rem;
  margin-bottom: 2.5rem;
  border-bottom: none;
  box-shadow: 0 0 .2rem rgba(0, 0, 0, .3);
  cursor: pointer;
}
.blog-container .blog > div > ul{
  display: flex;
  flex-flow: column;
  height: 100%;
}
.blog-container .blog .left, 
.blog-container .blog .right{ /* 수정 */
  width: 100%;
  min-width: 100%;
  opacity: 1;
  transform: none;
}
.blog-container .blog .left .posting-time{
  margin-top: 1rem;
  margin-bottom: .3rem;
  color: #aaa;
}
.blog-container .blog .left .category-name a{
  color: var(--primary-color);
}
.blog-container .blog .left .category-name a:hover{
  color: var(--secondary-color);
  text-decoration: underline;
}
.blog-container .blog .left .likes{
  margin-right: .5rem;
}
.blog-container .blog .left span{
  color: var(--primary-color);
}
.blog-container .blog .middle{ /* 수정 */
  flex-grow: 1;
  margin: 2rem 0rem; 
  padding: 0rem 0rem;
}
.blog-container .blog .middle > ul h3{
  font-weight: 700;
  font-size: 1.5rem;
}
.blog-container .blog .middle > ul p{
  padding: 1rem 0;
  line-height: 1.3rem;
  font-size: 1rem;
  color: gray;
}
.blog-container .blog .middle .account{
  display: flex;
  align-items: center;
}
.blog-container .blog .middle .account img{
  width: 2rem;
  height: 2rem;
  margin-right: .5rem;
  border-radius: 50%;
  cursor: pointer;
  object-fit: cover;
}
.blog-container .blog .middle .account span{
  font-size: .9rem;
  color: #bbb;
  margin-left: .5rem;
}
.blog-container .blog .middle > ul ul{
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.blog-container .blog .middle > ul ul button{
  width: 5rem;
  height: 2rem;
  color: #333;
  cursor: pointer;
  border: 2px solid #eee;
  border-radius: 1rem;
  background: #fff;
  transform: .2s;
}
.blog-container .blog .middle > ul ul button:hover{
  box-shadow: 0 0 .1rem rgba(0, 0, 0, .3);
}
.blog-container .blog .right ul,
.blog-container .blog .right ul li{
  height: 100%;
}
.blog-container .blog .right img{
  height: 100%;
  width: 100%;
  object-fit: cover;
  object-position: center;
}

.blog-container > div:not(.follow){ /* 추가 */
  position: relative;
}
.blog-container > div:not(.follow) > ul{ /* 추가 */
  display: flex;
}
.blog-container > div:not(.follow) > ul > li:nth-child(2){ /* 추가 */
  margin: 0rem 2rem;
}
.blog-container > div:not(.follow) > h3{  /* 추가 */
  font-size: 2rem;
  margin-bottom: 2rem;
}
.blog-container > div:not(.follow) > a button{ /* 추가 */
  width: 5rem;
  height: 2rem;
  color: #fff;
  cursor: pointer;
  border: none;
  background: #333;
  box-shadow: 0 0 .3rem rgba(0, 0, 0, .3);
  position: absolute; 
  bottom: 1.5rem; right: 0;
  transform: .2s;
}
.blog-container > div:not(.follow) > a button:hover{ /* 추가 */
  background: var(--secondary-color);
  box-shadow: none;
}

현재까지 home.css 파일은 위와 같다. 

 

추천글  

<div class="favorite-blog bottom-line padding">
      <h3>추천글</h3>
      <ul>
        <li>
          <div class="blog">
            <div class="left">
              <ul>
                <li class="category-name"><a href="#">여행</a></li>
                <li class="posting-time">1시간전</li>
                <li><a href="#" class="likes">공감</a><span>9</span></li>
              </ul>
            </div>
            <div class="middle">
              <ul>
                <li><h3>제주도 오른 까페 방문하기</h3></li>
                <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
                <li>
                 <ul>
                   <li>
                     <div class="account">
                       <img src="../imgs/avatar.jpg" alt="">
                       촌부 <span>by 농돌이</span>
                     </div>
                   </li>
                   <li><button>구독하기</button></li>
                 </ul>
                </li>
              </ul>
            </div>
            <div class="right">
              <ul>
                <li>
                 <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li>
          <div class="blog">
            <div class="left">
              <ul>
                <li class="category-name"><a href="#">여행</a></li>
                <li class="posting-time">1시간전</li>
                <li><a href="#" class="likes">공감</a><span>9</span></li>
              </ul>
            </div>
            <div class="middle">
              <ul>
                <li><h3>제주도 오른 까페 방문하기</h3></li>
                <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
                <li>
                 <ul>
                   <li>
                     <div class="account">
                       <img src="../imgs/avatar.jpg" alt="">
                       촌부 <span>by 농돌이</span>
                     </div>
                   </li>
                   <li><button>구독하기</button></li>
                 </ul>
                </li>
              </ul>
            </div>
            <div class="right">
              <ul>
                <li>
                 <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li>
          <div class="blog">
            <div class="left">
              <ul>
                <li class="category-name"><a href="#">여행</a></li>
                <li class="posting-time">1시간전</li>
                <li><a href="#" class="likes">공감</a><span>9</span></li>
              </ul>
            </div>
            <div class="middle">
              <ul>
                <li><h3>제주도 오른 까페 방문하기</h3></li>
                <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
                <li>
                 <ul>
                   <li>
                     <div class="account">
                       <img src="../imgs/avatar.jpg" alt="">
                       촌부 <span>by 농돌이</span>
                     </div>
                   </li>
                   <li><button>구독하기</button></li>
                 </ul>
                </li>
              </ul>
            </div>
            <div class="right">
              <ul>
                <li>
                 <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
                </li>
              </ul>
            </div>
          </div>
        </li>
      </ul>
    </div>

최근 내가 업로드한 글과 추천글은 동일한 HTML 코드를 사용하므로 위와 같이 home.html 파일에 추가해준다. 

 

최근에 읽은 글

<div class="latest-blog bottom-line padding">
      <h3>최근에 읽은 글</h3>
      <ul>
        <li>
          <div class="blog">
            <div class="left">
              <ul>
                <li class="category-name"><a href="#">여행</a></li>
                <li class="posting-time">1시간전</li>
                <li><a href="#" class="likes">공감</a><span>9</span></li>
              </ul>
            </div>
            <div class="middle">
              <ul>
                <li><h3>제주도 오른 까페 방문하기</h3></li>
                <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
                <li>
                 <ul>
                   <li>
                     <div class="account">
                       <img src="../imgs/avatar.jpg" alt="">
                       촌부 <span>by 농돌이</span>
                     </div>
                   </li>
                   <li><button>구독하기</button></li>
                 </ul>
                </li>
              </ul>
            </div>
            <div class="right">
              <ul>
                <li>
                 <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li>
          <div class="blog">
            <div class="left">
              <ul>
                <li class="category-name"><a href="#">여행</a></li>
                <li class="posting-time">1시간전</li>
                <li><a href="#" class="likes">공감</a><span>9</span></li>
              </ul>
            </div>
            <div class="middle">
              <ul>
                <li><h3>제주도 오른 까페 방문하기</h3></li>
                <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
                <li>
                 <ul>
                   <li>
                     <div class="account">
                       <img src="../imgs/avatar.jpg" alt="">
                       촌부 <span>by 농돌이</span>
                     </div>
                   </li>
                   <li><button>구독하기</button></li>
                 </ul>
                </li>
              </ul>
            </div>
            <div class="right">
              <ul>
                <li>
                 <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li>
          <div class="blog">
            <div class="left">
              <ul>
                <li class="category-name"><a href="#">여행</a></li>
                <li class="posting-time">1시간전</li>
                <li><a href="#" class="likes">공감</a><span>9</span></li>
              </ul>
            </div>
            <div class="middle">
              <ul>
                <li><h3>제주도 오른 까페 방문하기</h3></li>
                <li><p>성산의 해안도로를 따라 달리다 보면 보이는 오른 카페는 제주도의 자연요소 중 하나인 오름을 모티브로 한 카페의 콘셉트인 만큼 자연과 함께 커피를 마시며 즐길 수 있었던 것 같아요.😋</p></li>
                <li>
                 <ul>
                   <li>
                     <div class="account">
                       <img src="../imgs/avatar.jpg" alt="">
                       촌부 <span>by 농돌이</span>
                     </div>
                   </li>
                   <li><button>구독하기</button></li>
                 </ul>
                </li>
              </ul>
            </div>
            <div class="right">
              <ul>
                <li>
                 <img src="../imgs/waterfall.jpg" alt="blog-thumbnail">
                </li>
              </ul>
            </div>
          </div>
        </li>
      </ul>
    </div>

최근 내가 업로드한 글과 최근 내가 읽은 글은 동일한 HTML 코드를 사용하므로 위와 같이 home.html 파일에 추가해준다. 

 

반응형 웹

/* 반응형웹 */
@media (max-width: 420px){
  header{
    padding: 1rem 1rem;
  }
  .blog-container{
    width: 90vw;
  }
  .blog-container > div:not(.follow) > ul {
    flex-flow: column;
  }
  .blog-container > div:not(.follow) > ul > li:nth-child(2) {
    margin: 0rem 0rem;
  }
}

home.css 파일에 위 코드를 추가한다. 블로그 글에 대한 카드 컴포넌트를 세로방향으로 나열하기 위하여 flex-flow: column 을 적용한다. 

@media (max-width: 300px){
  header{
    padding: .5rem .5rem;
  }
  header .logo {
    font-size: 1rem;
  }
  header .logo i{
    font-size: 2rem;
  }
  header .navbar ul li {
    margin: 0 .5rem;
  }
  .blog-container > div:not(.follow) > h3 {
    font-size: 1.3rem;
    margin-bottom: 1rem;
  }
  .footer .icons{
    padding: 1rem 0;
  }
  .footer .icons .scroll-up {
    margin-right: 0.2rem;
  }
}

home.css 파일에 위 코드를 추가한다. 헤더의 로고 폰트 크기를 이전보다 작게 만든다. 헤더의 여백(마진/패딩)도 줄인다. h3 요소의 폰트 크기와 마진도 작게 변경한다. SNS 아이콘의 위아래 패딩도 줄인다. 위쪽 화살표의 우측 마진도 작게 조절한다. 

@import url('reset.css');
@import url('global.css');
@import url('header.css');
@import url('footer.css');
@import url('animation.css');

/* 헤더 */
header .navbar ul li .material-icons{ /* 종모양 스타일링 추가 */
  font-size: 2rem;
}
header .navbar ul li .account img{ /* 아바타 스타일링 추가 */
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
}

/* 푸터 */
.footer{
  position: fixed;
  z-index: 1;
  bottom: 0;
  transition: 1s ease-in-out; 
}
.footer.hide{
  opacity: 0;
  height: 0;
}

/* 공통 스타일 */
.bottom-line{
  border-bottom: 1px solid #eee;
}
.padding{
  padding: 2rem 0rem;
}
/* 컨텐츠 섹션 */
.blog-container{
  width: 50vw;
  margin: 0 auto;
}

.blog-container .follow > ul{ /* 구독중 */
  display: flex;
  flex-wrap: wrap;
}
.blog-container .follow > ul li{
  font-size: 1.2rem;
  padding-right: 1.2rem;
}
.blog-container .follow > ul li a{
  padding-right: .3rem;
  color: var(--primary-color);
  cursor: pointer;
}
.blog-container .follow > ul li a:hover{
  text-decoration: underline;
}

/* 블로그 섹션 */
.blog-container .blog{ /* 수정 */
  display: flex;
  flex-wrap: wrap;
  flex-flow: column-reverse;
  padding: 2rem 1rem;
  margin-bottom: 2.5rem;
  border-bottom: none;
  box-shadow: 0 0 .2rem rgba(0, 0, 0, .3);
  cursor: pointer;
}
.blog-container .blog > div > ul{
  display: flex;
  flex-flow: column;
  height: 100%;
}
.blog-container .blog .left, 
.blog-container .blog .right{ /* 수정 */
  width: 100%;
  min-width: 100%;
  opacity: 1;
  transform: none;
}
.blog-container .blog .left .posting-time{
  margin-top: 1rem;
  margin-bottom: .3rem;
  color: #aaa;
}
.blog-container .blog .left .category-name a{
  color: var(--primary-color);
}
.blog-container .blog .left .category-name a:hover{
  color: var(--secondary-color);
  text-decoration: underline;
}
.blog-container .blog .left .likes{
  margin-right: .5rem;
}
.blog-container .blog .left span{
  color: var(--primary-color);
}
.blog-container .blog .middle{ /* 수정 */
  flex-grow: 1;
  margin: 2rem 0rem; 
  padding: 0rem 0rem;
}
.blog-container .blog .middle > ul h3{
  font-weight: 700;
  font-size: 1.5rem;
}
.blog-container .blog .middle > ul p{
  padding: 1rem 0;
  line-height: 1.3rem;
  font-size: 1rem;
  color: gray;
}
.blog-container .blog .middle .account{
  display: flex;
  align-items: center;
}
.blog-container .blog .middle .account img{
  width: 2rem;
  height: 2rem;
  margin-right: .5rem;
  border-radius: 50%;
  cursor: pointer;
  object-fit: cover;
}
.blog-container .blog .middle .account span{
  font-size: .9rem;
  color: #bbb;
  margin-left: .5rem;
}
.blog-container .blog .middle > ul ul{
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.blog-container .blog .middle > ul ul button{
  width: 5rem;
  height: 2rem;
  color: #333;
  cursor: pointer;
  border: 2px solid #eee;
  border-radius: 1rem;
  background: #fff;
  transform: .2s;
}
.blog-container .blog .middle > ul ul button:hover{
  box-shadow: 0 0 .1rem rgba(0, 0, 0, .3);
}
.blog-container .blog .right ul,
.blog-container .blog .right ul li{
  height: 100%;
}
.blog-container .blog .right img{
  height: 100%;
  width: 100%;
  object-fit: cover;
  object-position: center;
}

.blog-container > div:not(.follow){ /* 추가 */
  position: relative;
}
.blog-container > div:not(.follow) > ul{ /* 추가 */
  display: flex;
}
.blog-container > div:not(.follow) > ul > li:nth-child(2){ /* 추가 */
  margin: 0rem 2rem;
}
.blog-container > div:not(.follow) > h3{  /* 추가 */
  font-size: 2rem;
  margin-bottom: 2rem;
}
.blog-container > div:not(.follow) > a button{ /* 추가 */
  width: 5rem;
  height: 2rem;
  color: #fff;
  cursor: pointer;
  border: none;
  background: #333;
  box-shadow: 0 0 .3rem rgba(0, 0, 0, .3);
  position: absolute; 
  bottom: 1.5rem; right: 0;
  transform: .2s;
}
.blog-container > div:not(.follow) > a button:hover{ /* 추가 */
  background: var(--secondary-color);
  box-shadow: none;
}

/* 반응형웹 */
@media (max-width: 420px){
  header{
    padding: 1rem 1rem;
  }
  .blog-container{
    width: 90vw;
  }
  .blog-container > div:not(.follow) > ul {
    flex-flow: column;
  }
  .blog-container > div:not(.follow) > ul > li:nth-child(2) {
    margin: 0rem 0rem;
  }
}
@media (max-width: 300px){
  header{
    padding: .5rem .5rem;
  }
  header .logo {
    font-size: 1rem;
  }
  header .logo i{
    font-size: 2rem;
  }
  header .navbar ul li {
    margin: 0 .5rem;
  }
  .blog-container > div:not(.follow) > h3 {
    font-size: 1.3rem;
    margin-bottom: 1rem;
  }
  .footer .icons{
    padding: 1rem 0;
  }
  .footer .icons .scroll-up {
    margin-right: 0.2rem;
  }
}

완성된 home.css 파일은 위와 같다. 

 

페이지 모드(다크/일반) 기능 구현하기 & 브라우저 상단으로 스크롤링하기

const scroller = new Scroller(false) // 스크롤 객체 생성 

window.addEventListener("load", (event) => {
  // 테마변경 (다크모드/ 일반모드)
  const mode = document.querySelector('.mode')
  const icons = mode.querySelectorAll('.fa-solid')
  const header = document.querySelector('header')

  mode.addEventListener('click', (event) => {
    document.body.classList.toggle('dark')
    header.classList.toggle('dark')
    
    for(const icon of icons){
      icon.classList.contains('active') ? 
        icon.classList.remove('active') 
        : icon.classList.add('active')
    }
  })

  // 브라우저 상단으로 스크롤하기
  const arrowUp = document.querySelector('.footer .icons .scroll-up') // 위쪽 화살표 클릭 
  arrowUp.addEventListener('click', (event) => {
    history.pushState({}, "", `#`); // URL 주소 변경 
    scroller.setScrollPosition({top: 0, behavior: 'smooth'})
  })

  const logo = document.querySelector('header .logo') // 로고 클릭 
  logo.addEventListener('click', (event) => {
    event.preventDefault() // 부드러운 스크롤링
    history.pushState({}, "", `#`); // URL 주소 변경 
    scroller.setScrollPosition({top: 0, behavior: 'smooth'}) 
  })
})

js 폴더에 home.js 파일을 생성하고 landing.js 파일의 해당 코드를 복사붙여넣기 한다. 

 

블로그 목록에 애니메이션 적용하기 

home.html

home.html 파일에서 blog 클래스가 들어간 모든 요소에 down 클래스를 추가한다. 

.blog-container .blog{ 
  display: flex;
  flex-wrap: wrap;
  flex-flow: column-reverse;
  padding: 2rem 1rem;
  margin-bottom: 2.5rem;
  border-bottom: none;
  box-shadow: 0 0 .2rem rgba(0, 0, 0, .3);
  cursor: pointer;
  transition: .5s; /* 추가 */
}

home.css 의 해당 선택자에 transition 속성을 추가한다. 

const sections = document.querySelectorAll('.blog-container > div:not(.follow)') // 푸터를 제외한 section 엘리먼트 조회
const footer = document.querySelector('.footer')

window.addEventListener('scroll', (event) => {

    sections.forEach(section => {
      // console.log(section.getBoundingClientRect().top, header.offsetHeight)

      // 해당 섹션이 헤더에 가까워지면 애니메이션 적용하기 
      if(section.getBoundingClientRect().top < header.offsetHeight + 200){
        const blogs = section.querySelectorAll('.blog') 
        blogs.forEach(blog => blog.classList.add('show'))
      }

      // 스크롤바가 브라우저 상단에 도달하면 애니메이션 해제하기 
      if(scroller.getScrollPosition() < 10){
        const blogs = section.querySelectorAll('.blog') 
        blogs.forEach(blog => blog.classList.remove('show'))
      }
    })
})

home.js 파일에 위 코드를 추가한다. sections 는 최근 내가 업로드한 글/추천글/최근에 읽은 글 섹션을 의미한다. 스크롤링하는 동안 각 섹션이 헤더와 가까워지면 해당 섹션안의 블로그 글에 애니메이션을 적용한다. 스크롤바가 브라우저 상단에 도달하면 애니메이션을 해제한다. 

 

스크롤링시 헤더에 그림자 주기 & 푸터 숨기기 

if(scroller.getScrollPosition() > header.offsetHeight){ // 스크롤바를 헤더높이만큼 내린 경우 
  header.classList.add('active') // 헤더 하단에 그림자 주기
  footer.classList.add('hide')   // 푸터 숨기기 
}else{
  header.classList.remove('active')
  footer.classList.remove('hide')
}

home.js 파일의 스크롤 이벤트핸들러 함수 안에 위 코드를 추가한다. 스크롤바가 헤더높이만큼 내려오면 헤더 하단에 그림자를 적용하고 푸터는 숨긴다. 다시 스크롤바가 브라우저 상단에 도달하면 헤더에 적용된 그림자는 사라지고 푸터는 나타난다. 

const scroller = new Scroller(false) // 스크롤 객체 생성 

window.addEventListener("load", (event) => {
  // 테마변경 (다크모드/ 일반모드)
  const mode = document.querySelector('.mode')
  const icons = mode.querySelectorAll('.fa-solid')
  const header = document.querySelector('header')

  mode.addEventListener('click', (event) => {
    document.body.classList.toggle('dark')
    header.classList.toggle('dark')
    
    for(const icon of icons){
      icon.classList.contains('active') ? 
        icon.classList.remove('active') 
        : icon.classList.add('active')
    }
  })

  // 브라우저 상단으로 스크롤하기
  const arrowUp = document.querySelector('.footer .icons .scroll-up') // 위쪽 화살표 클릭 
  arrowUp.addEventListener('click', (event) => {
    history.pushState({}, "", `#`); // URL 주소 변경 
    scroller.setScrollPosition({top: 0, behavior: 'smooth'})
  })

  const logo = document.querySelector('header .logo') // 로고 클릭 
  logo.addEventListener('click', (event) => {
    event.preventDefault() // 부드러운 스크롤링
    history.pushState({}, "", `#`); // URL 주소 변경 
    scroller.setScrollPosition({top: 0, behavior: 'smooth'}) 
  })

  const sections = document.querySelectorAll('.blog-container > div:not(.follow)') // 푸터를 제외한 section 엘리먼트 조회
  const footer = document.querySelector('.footer')

  window.addEventListener('scroll', (event) => {

    sections.forEach(section => {
      // console.log(section.getBoundingClientRect().top, header.offsetHeight)

      // 해당 섹션이 헤더에 가까워지면 애니메이션 적용하기 
      if(section.getBoundingClientRect().top < header.offsetHeight + 200){
        const blogs = section.querySelectorAll('.blog') 
        blogs.forEach(blog => blog.classList.add('show'))
      }

      // 스크롤바가 브라우저 상단에 도달하면 애니메이션 해제하기 
      if(scroller.getScrollPosition() < 10){
        const blogs = section.querySelectorAll('.blog') 
        blogs.forEach(blog => blog.classList.remove('show'))
      }
    })
  
    if(scroller.getScrollPosition() > header.offsetHeight){ // 스크롤바를 헤더높이만큼 내린 경우 
      header.classList.add('active') // 헤더 하단에 그림자 주기
      footer.classList.add('hide')   // 푸터 숨기기 
    }else{
      header.classList.remove('active')
      footer.classList.remove('hide')
    }
  })
})

 완성된 home.js 파일은 위와 같다. 

728x90

'프로젝트 > 블로그 사이트' 카테고리의 다른 글

5. 포스트 페이지 구현하기  (0) 2023.07.16
3. 스토리 페이지 구현하기  (0) 2023.07.08
2. 랜딩 페이지 구현하기  (0) 2023.07.07
1. 프로젝트 준비  (0) 2023.07.07