출처: Online Tutorials https://youtu.be/zQngLMkngQE

리액트로 프로젝트를 진행하면서 여러 기능들을 구현해보았지만,

아직 제대로 접근조차 못하고 있는 기능이 있다.

그것은 반응형 웹인데 대략적으로 미디어쿼리 사용하면 되지~ 하고 제대로 구현해 본적은 없다.

요즘 반응형 필수인데 못하고 있으면 안되지..

프로젝트에 적용하기 전에 다른 사람들은 어떻게 구현하는지 따라해봤다.

 

소스코드

index.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>Document</title>

    <link
      href="https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700&display=swap"
      rel="stylesheet"
    />

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />

    <link rel="stylesheet" type="text/css" href="./css/style.min.css" />
  </head>
  <body>
    <header class="nav-container">
      <a href="#" class="logo">LOGO</a>
      <div class="group">
        <ul class="navigation">
          <li><a href="#">Home</a></li>
          <li><a href="#">About</a></li>
          <li><a href="#">Services</a></li>
          <li><a href="#">Blog</a></li>
          <li><a href="#">Contact</a></li>
        </ul>
        <div class="search">
          <span class="icon">
            <i class="fa-solid fa-magnifying-glass"></i>
            <i class="fa-solid fa-xmark"></i>
            <i class="fa-solid fa-bars"></i>
          </span>
        </div>
      </div>
      <div class="search-box">
        <input type="text" placeholder="Search here...">
      </div>
    </header>
    
    <!-- JS -->
    <script>
      const searchBtn = document.querySelector(".fa-magnifying-glass");
      const closeBtn = document.querySelector(".fa-xmark");
      const searchBox = document.querySelector(".search-box");
      const header = document.querySelector(".nav-container");
      const navigation = document.querySelector(".navigation");
      const menuToggle = document.querySelector(".fa-bars");

      // 돋보기 버튼 클릭
      searchBtn.addEventListener("click", () => {
        searchBox.classList.add("active");
        closeBtn.classList.add("active");
        searchBtn.classList.add("active");
      });

      // 닫기 버튼 클릭
      closeBtn.addEventListener("click", () => {
        searchBox.classList.remove("active");
        closeBtn.classList.remove("active");
        searchBtn.classList.remove("active");
      });
      
      // 메뉴 버튼 클릭
      menuToggle.addEventListener("click", () => {
        header.classList.toggle("open");
      });
    </script>
  </body>
</html>

 

style.scss

* {
  margin: 0;
  padding: 0;
  font-family: 'Poppins', sans-serif;
  box-sizing: border-box;
  list-style: none;
  text-decoration: none;
}

body {
  background-color: #dee1e2;
  min-height: 100vh;
  overflow-x: hidden;
}

.nav-container {
  position: absolute;
  display: flex;
  justify-content: space-between;
  align-items: center;
  top: 0;
  left: 0;
  width: 100%;
  height: 80px;
  background-color: #fff;
  padding: 20px 40px;
  box-shadow: 0 1px 10px rgba(0,0,0,.1);

  .logo {
    color: #333;
    font-size: 1.5em;
    font-weight: 700;
    letter-spacing: 0.1em;
  }
  
  .group {
    display: flex;
    align-items: center;

    .navigation {
      position: relative;
      display: flex;
      gap: 30px;

      a {
        position: relative;
        font-size: 1em;
        color: #333;
        text-transform: uppercase;
        letter-spacing: .2em;

        &::before {
          content: "";
          position: absolute;
          bottom: -2px;
          width: 100%;
          height: 2px;
          background-color: #333;
          transform: scaleX(0);
          transition: .5s ease-in-out;
          transform-origin: left;
        }

        &:hover::before { transform: scaleX(1); }
      }
    }

    .search {
      position: relative;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 1.5em;
      z-index: 10;
      cursor: pointer;

      .fa-magnifying-glass {
        position: relative;
        left: 30px;
        transition: .5s ease-in-out;

        &.active { left: -20px; }
      }

      .fa-xmark {
        opacity: 0;
        visibility: hidden;

        &.active {
          opacity: 1;
          visibility: visible;
          transition: .5s ease-in-out;
          scale: 1;
        }
      }
    }

    .fa-bars {
      position: relative;
      display: none;
    }
  }

  .search-box {
    position: absolute;
    right: -100%;
    width: 100%;
    height: 100%;
    display: flex;
    background-color: #fff;
    align-items: center;
    padding: 0 30px;
    transition: .5s ease-in-out;

    &.active { right: 0; }

    input {
      width: 100%;
      border: none;
      outline: none;
      height: 50px;
      color: #333;
      font-size: 1.25em;
      background-color: #fff;
      border-bottom: 1px solid rgba(0,0,0,.5);
    }
  }
}

/* response */
@media (max-width: 800px) {
  .nav-container {
    .navigation {
      position: absolute;
      opacity: 0;
      visibility: hidden;
      max-width: 0px;
      padding: 40px;
    }
    
    &.open {
      .navigation {
        position: absolute;
        display: flex;
        flex-direction: column;
        padding: 40px;
        background-color: #fff;
        border-top: 1px solid rgba(0,0,0,.05);
        top: 80px;
        left: 0;
        width: 100%;
        height: calc(100vh - 80px);
        visibility: visible;
        opacity: 1;
        max-width: 100%;
        transition: 1s ease;

        li { font-size: 1.25em; }
      }
    }

    .group {
      .icon {
        display: flex;
        position: fixed;
        align-items: center;
        right: 5%;

        .fa-magnifying-glass {
          position: relative;
          left: 0;
        }
        
        .fa-xmark {
          position: relative;
          left: -10px;
        }

        .fa-bars {
          display: block;
          font-size: 1em;
          cursor: pointer;
          z-index: 10;
        }
      }
      
    }
  }
}

 

구현결과

반응형에 대해 대략적으로만 알았지 구현 방법에 대해서는 제대로 알지 못했다.

반응형을 구현할 때 해당 해상도에 맞춰 css를 새로 구상하는 방법으로 접근하면 될 듯 하다.

익숙해지면 쉽게 구현할 수 있을것으로 생각된다.

 

+ Recent posts