Анимированная Боковая панель

#javascript #html #css

Вопрос:

Я пытаюсь создать анимированную боковую панель. Изначально у меня есть верхняя панель навигации, боковая панель и раздел содержимого. Боковая панель и разделители содержимого находятся внутри контейнера div, который имеет свойство отображать гибкую строку. Я в замешательстве по поводу перехода. Я хочу, чтобы боковая панель отображалась и скрывалась при нажатии кнопки «Домой», что имеет эффект скольжения. Прямо сейчас у меня есть скользящая боковая панель, но раздел содержимого не получает полную ширину своего родителя, когда боковая панель скрывается. Как я могу это сделать? Должен ли я применить переход на flex или на transform? Любая помощь будет признательна.

 <body>
    <nav>
      <ul>
        <li><button id="home">Home</button></li>
        <li><button>Services</button></li>
        <li><button>Operations</button></li>
        <li><button>About</button></li>
        <li><button>Contact</button></li>
      </ul>
    </nav>
    <div class="container">
      <div id="sidebar" class="sidebar visible">
        <ul>
          <li><button>Inventories</button></li>
          <li><button>Employees</button></li>
          <li><button>Feedback</button></li>
           <li><button>Projects</button></li>
        </ul>
      </div>
      <div class="content" id="content">
        LOrem issum dolor sit amet
      </div>
    </div>
  </body>

nav{
  width: 100%;
  display: flex;
  justify-content : center;
}

.container{
  display: flex;
  flex-direction: row;
}

.sidebar{
  flex:1;
  background-color: rgb(40,100,250);
  height: 100vh;
  transition: transform 0.5s linear;
  transform: translatex(-100%);
}

.visible{
  transform: translatex(0);
  flex: 1;
}

.content{
  background-color: rgb(33,31,31);
  flex: 5;
  text-align: center;
  color: #fff;
  transition: flex 0.5s ease-in-out;
  
}

.afterContent{
  flex: 10;
}

    const homeButton = document.getElementById("home");
const sidebarDiv = document.getElementById("sidebar");
const content = document.getElementById("content");
homeButton.addEventListener("click", () => {
  if (sidebarDiv.classList.contains("visible")) {
    sidebarDiv.classList.remove("visible");
    if(!content.classList.contains("afterContent")){
      content.classList.add("afterContent");
    }
  } else {
    sidebarDiv.classList.add("visible");
    if(content.classList.contains("afterContent")){
      content.classList.remove("afterContent");
    }
  }
});
 

Ответ №1:

Проблема в том, что вы просто преобразуете элемент, преобразование не изменит структуру макета, оно влияет только на элемент, к которому вы применяете преобразование, и на все его дочерние элементы.

Обычно для достижения результата требуется заполнение и положение: абсолютное.

То есть у вас есть элемент боковой position: absolute; top: 0; bottom: 0; left: 0; панели . Чтобы скрыть его, вы просто трансформируете его влево. А затем у вас есть элемент содержимого, который смещает меню с отступом влево.

Вот простая демонстрация:

 <html>
<head>
<style>
html, body {margin: 0; padding: 0}

.header {
    width: 100%;
    height: 100px;
    background-color: red;
}

.body {
    position: relative;
}
.sidebar {
    position: absolute;
    background-color: blue;
    top: 0;
    bottom: 0;
    left: 0;
    width: 300px;
    transition: transform 0.2s;
}
.content {
    padding-left: 300px;
    min-height: 500px;
    background-color: teal;
    transition: padding-left 0.2s;
}

.menu-closed > .sidebar {
    transform: translateX(-300px);
}

.menu-closed > .content {
    padding-left: 0px;
}

</style>
</head>
<body>
    <div class="header">header menu</div>
    <div id="body" class="body">
            <nav class="sidebar">sidebar menu</nav>
        <div class="content"><button onclick="menu()">nav</button> content</div>
    <div>

    <script>
        const body = document.getElementById("body");
        let menuClosed = false;
    function menu() {
        menuClosed ? body.classList.remove("menu-closed") : body.classList.add("menu-closed");
        menuClosed = !menuClosed;
    }
    </script>
  </body>
</html>