Как заставить элемент li в моем проекте не двигаться?

У меня есть боковое меню, в котором есть индикатор, показывающий выбранную кнопку.

Результат, которого я ожидал, состоял в том, что индикатор двигался, а элементы li — нет. Но оказывается, они оба двигаются. Я знаю, что то, как я закодировал это, очень не нужно, но я не знаю, как это сделать иначе. Может ли кто-нибудь объяснить мне, почему элементы li перемещаются, как я могу сделать свой код более эффективным и как решить мою проблему?

const menuButtonElements   = document.querySelectorAll('#menu-sdbr-list-item button');
const menuIndicatorElement = document.getElementById('menu-sdbr-list-indicator');
const menuSidebarUlElement = document.getElementById('menu-sdbr-list');
let selectedButtonIndex = 0;

menuButtonElements.forEach((value, index) => {
  value.addEventListener('click', () => {
    selectedButtonIndex = index;
    menuIndicatorElement.setAttribute('style', `
    margin-bottom: ${(index + 1) * -65}px;
    `)
    menuButtonElements.forEach(value => {
      value.setAttribute('style', `
      color: var(--color-surface-300);
      `)
    })
    menuButtonElements[index].setAttribute('style', `
    color: white;
    `)
  })
})
@import url('https://fonts.googleapis.com/css2?family=Fira+Sans+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
@import "https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Round";
body {
  --color-primary-100: rgb(105, 54, 245);
  --color-primary-200: rgb(128, 78, 247);
  --color-primary-300: rgb(148, 100, 249);
  --color-primary-400: rgb(166, 122, 251);
  --color-primary-500: rgb(183, 144, 252);
  --color-primary-600: rgb(199, 165, 253);
  --color-surface-100: rgb(0, 0, 0);
  --color-surface-200: rgb(30, 30, 30);
  --color-surface-300: rgb(53, 53, 53);
  --color-surface-400: rgb(78, 78, 78);
  --color-surface-500: rgb(105, 105, 105);
  --color-surface-600: rgb(133, 133, 133);
  --color-surface-mixed-100: rgb(26, 22, 37);
  --color-surface-mixed-200: rgb(40, 35, 48);
  --color-surface-mixed-300: rgb(63, 58, 70);
  --color-surface-mixed-400: rgb(88, 83, 94);
  --color-surface-mixed-500: rgb(113, 109, 119);
  --color-surface-mixed-600: rgb(140, 136, 144);
  --color-primary-100-mix: 105, 54, 245;
  --color-primary-500-mix: 183, 144, 252;
  font-family: Fira Sans Condensed, Arial;
  margin: 0;
}

.menu-sidebar-overlay {
  position: fixed;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 200;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  color: white;
}

.menu-sidebar {
  position: relative;
  height: 100%;
  width: 35vw;
  background-color: var(--color-primary-100);
  display: flex;
}

.menu-sidebar .rectangle {
  width: 15%;
  height: 100%;
  background-color: var(--color-surface-300);
}

.menu-sdbr-title {
  display: inline;
  color: var(--color-primary-200);
  font-size: 40px;
  margin: 15px 0 0 10px;
  color: white;
}

.menu-sdbr-contents {
  width: 100%;
  position: relative;
  height: 100%;
  flex: 1;
  display: flex;
  flex-direction: column;
  margin-left: 10px;
}

.menu-sdbr-list {
  position: absolute;
  width: 100%;
  padding: 0;
  margin: 90px 0 0 0;
  list-style-type: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  flex: 1;
  height: 100%;
}

.menu-sdbr-list-indicator {
  margin-bottom: -65px;
  width: 100%;
  height: 60px;
  background-color: var(--color-surface-300);
  z-index: 250;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  transition: margin-bottom 150ms;
}

.menu-sdbr-list-item button {
  position: relative;
  background-color: transparent;
  border: 0 solid rgba(0, 0, 0, 1);
  width: 100%;
  padding: 0 15px;
  height: 60px;
  text-align: left;
  display: flex;
  align-items: center;
  color: var(--color-surface-300);
  z-index: 300;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  font-size: 15px;
  font-weight: 400;
  z-index: 300;
  /*
border: 1px solid rgba(0, 0, 0, 1);
border-right: none;
*/
  transition: color 150ms;
}

.menu-sdbr-list-item button .material-icons {
  margin-right: 15px;
  font-size: 20px;
}
<nav class = "menu-sidebar-overlay">
  <div class = "menu-sidebar">
    <div class = "menu-sdbr-contents">
      <h1 class = "menu-sdbr-title">MENU</h1>
      <ul class = "menu-sdbr-list" id = "menu-sdbr-list">
        <li class = "menu-sdbr-list-indicator" id = "menu-sdbr-list-indicator">
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                  <span class = "material-icons">dark_mode</span>
                  Dark Mode
                </button>
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                  <span class = "material-icons">settings</span>
                  Settings
                </button>
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                  <span class = "material-icons">logout</span>
                  Log Out
                </button>
        </li>
      </ul>
    </div>
    <div class = "rectangle"></div>
  </div>
</nav>

Наличие этого <div> в качестве дочернего элемента элемента <ul> является недопустимым HTML.

Pointy 09.08.2023 15:09

@Pointy О, я этого не знал, я обновлю это очень быстро

CindyTheCat 09.08.2023 15:12

Чтобы быть более ясным, причина, по которой хорошо сохранять «честность» со структурой HTML, заключается в том, что когда вы этого не делаете, вам приходится иметь дело с тем, как браузер решает исправить ситуацию за вас, что иногда может привести к странным вещам. В этом случае браузеры, кажется, терпят плохие структуры <ul>, по крайней мере, в разумных пределах, но я бы все равно это исправил, если бы заметил это в коде, который мне небезразличен.

Pointy 09.08.2023 15:15

@Pointy о, хорошо, теперь я понял, спасибо

CindyTheCat 09.08.2023 15:17

мой плохой, это <menu> -> <menu> может заменить верхний <ul>

Mister Jojo 09.08.2023 15:27

Отрицательное значение margin-bottom, которое вы устанавливаете для этого элемента индикатора, позволяет следующим элементам «скользить вверх». Удалите начальное отрицательное поле из таблицы стилей, замените его на position: relative. А в вашей JS части ставьте не margin-bottom, а вместо этого top - но с положительным коэффициентом (т.е. умножайте на 65, а не -65)

CBroe 09.08.2023 15:51

И в идеале этот индикатор должен быть реализован не через пустой дополнительный элемент списка (семантически тоже довольно плохой), а через псевдо-потомок (::before) на UL.

CBroe 09.08.2023 15:52

На мой взгляд, это не лучшее решение, которое вы можете найти. У вас есть смещение контейнера, потому что вы играете с полями и эффективно меняете высоту контейнера (который центрируется на родительском элементе). Вместо того, чтобы перемещать «ли», я бы поместил черную вкладку над линиями (в абсолютном выражении) и переместил ее.

Alex 09.08.2023 15:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
8
80
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вместо того, чтобы перемещать абсолютно позиционированный элемент вверх и вниз, было бы проще добавить и удалить класс родительского элемента li, а затем добавить к нему фон и выделить кнопку на основе класса.

Это также имеет дополнительное преимущество, позволяя вам добавить этот класс в один из li, если вы хотите, чтобы он был предварительно выбран, в приведенном ниже примере я добавил его в первый li.

const menuButtonElements = document.querySelectorAll('#menu-sdbr-list-item button');

// change the name of this foreach variable so you don't have matching var name inside the closure
menuButtonElements.forEach(button => {
  button.addEventListener('click', () => {
    // remove class from all button parent lis
    menuButtonElements.forEach(value => {
      value.parentNode.classList.remove('selected');
    });
    
    // add class to the clicked button parent li
    button.parentNode.classList.add('selected');
  })
})
@import url('https://fonts.googleapis.com/css2?family=Fira+Sans+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
@import "https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Round";
body {
  --color-primary-100: rgb(105, 54, 245);
  --color-primary-200: rgb(128, 78, 247);
  --color-primary-300: rgb(148, 100, 249);
  --color-primary-400: rgb(166, 122, 251);
  --color-primary-500: rgb(183, 144, 252);
  --color-primary-600: rgb(199, 165, 253);
  --color-surface-100: rgb(0, 0, 0);
  --color-surface-200: rgb(30, 30, 30);
  --color-surface-300: rgb(53, 53, 53);
  --color-surface-400: rgb(78, 78, 78);
  --color-surface-500: rgb(105, 105, 105);
  --color-surface-600: rgb(133, 133, 133);
  --color-surface-mixed-100: rgb(26, 22, 37);
  --color-surface-mixed-200: rgb(40, 35, 48);
  --color-surface-mixed-300: rgb(63, 58, 70);
  --color-surface-mixed-400: rgb(88, 83, 94);
  --color-surface-mixed-500: rgb(113, 109, 119);
  --color-surface-mixed-600: rgb(140, 136, 144);
  --color-primary-100-mix: 105, 54, 245;
  --color-primary-500-mix: 183, 144, 252;
  font-family: Fira Sans Condensed, Arial;
  margin: 0;
}

.menu-sidebar-overlay {
  position: fixed;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 200;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  color: white;
}

.menu-sidebar {
  position: relative;
  height: 100%;
  width: 35vw;
  background-color: var(--color-primary-100);
  display: flex;
}

.menu-sidebar .rectangle {
  width: 15%;
  height: 100%;
  background-color: var(--color-surface-300);
}

.menu-sdbr-title {
  display: inline;
  color: var(--color-primary-200);
  font-size: 40px;
  margin: 15px 0 0 10px;
  color: white;
}

.menu-sdbr-contents {
  width: 100%;
  position: relative;
  height: 100%;
  flex: 1;
  display: flex;
  flex-direction: column;
  margin-left: 10px;
}

.menu-sdbr-list {
  position: absolute;
  width: 100%;
  padding: 0;
  margin: 90px 0 0 0;
  list-style-type: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  flex: 1;
  height: 100%;
}

.menu-sdbr-list-item button {
  position: relative;
  background-color: transparent;
  border: 0 solid rgba(0, 0, 0, 1);
  width: 100%;
  padding: 0 15px;
  height: 60px;
  text-align: left;
  display: flex;
  align-items: center;
  color: var(--color-surface-300);
  z-index: 300;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  font-size: 15px;
  font-weight: 400;
  z-index: 300;
  /*
border: 1px solid rgba(0, 0, 0, 1);
border-right: none;
*/
  transition: color 150ms;
}

.menu-sdbr-list-item button .material-icons {
  margin-right: 15px;
  font-size: 20px;
}

/* the below are the new classes for the selected item */
.menu-sdbr-list-item.selected {
  background-color: var(--color-surface-300);
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
}

.menu-sdbr-list-item.selected button {
    color: white;
}
<nav class = "menu-sidebar-overlay">
  <div class = "menu-sidebar">
    <div class = "menu-sdbr-contents">
      <h1 class = "menu-sdbr-title">MENU</h1>
      <ul class = "menu-sdbr-list" id = "menu-sdbr-list">
        <li class = "menu-sdbr-list-item selected" id = "menu-sdbr-list-item">
          <button>
                <span class = "material-icons">dark_mode</span>
                Dark Mode
              </button>
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                <span class = "material-icons">settings</span>
                Settings
              </button>
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                <span class = "material-icons">logout</span>
                Log Out
              </button>
        </li>
      </ul>
    </div>
    <div class = "rectangle"></div>
  </div>
</nav>

Извините, только что понял, что у вас есть анимация на вашем фоне, чтобы он скользил между щелкнутыми элементами - приведенный выше ответ не будет этого делать, вместо этого вам нужно будет использовать абсолютное позиционирование для перемещения выделения без перемещения остальной его части:

const menuButtonElements   = document.querySelectorAll('#menu-sdbr-list-item button');
const menuIndicatorElement = document.getElementById('menu-sdbr-list-indicator');
const menuSidebarUlElement = document.getElementById('menu-sdbr-list');
let selectedButtonIndex = 0;

const elementHeight = 65;
const initialPosition = -((menuButtonElements.length - 1) / 2) * elementHeight;

menuButtonElements.forEach((value, index) => {
  value.addEventListener('click', () => {
    selectedButtonIndex = index;
    menuIndicatorElement.setAttribute('style', `
    margin-top: ${initialPosition + (index * elementHeight)}px;
    `)
    menuButtonElements.forEach(value => {
      value.setAttribute('style', `
      color: var(--color-surface-300);
      `)
    })
    menuButtonElements[index].setAttribute('style', `
    color: white;
    `)
  })
})
@import url('https://fonts.googleapis.com/css2?family=Fira+Sans+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
@import "https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Round";
body {
  --color-primary-100: rgb(105, 54, 245);
  --color-primary-200: rgb(128, 78, 247);
  --color-primary-300: rgb(148, 100, 249);
  --color-primary-400: rgb(166, 122, 251);
  --color-primary-500: rgb(183, 144, 252);
  --color-primary-600: rgb(199, 165, 253);
  --color-surface-100: rgb(0, 0, 0);
  --color-surface-200: rgb(30, 30, 30);
  --color-surface-300: rgb(53, 53, 53);
  --color-surface-400: rgb(78, 78, 78);
  --color-surface-500: rgb(105, 105, 105);
  --color-surface-600: rgb(133, 133, 133);
  --color-surface-mixed-100: rgb(26, 22, 37);
  --color-surface-mixed-200: rgb(40, 35, 48);
  --color-surface-mixed-300: rgb(63, 58, 70);
  --color-surface-mixed-400: rgb(88, 83, 94);
  --color-surface-mixed-500: rgb(113, 109, 119);
  --color-surface-mixed-600: rgb(140, 136, 144);
  --color-primary-100-mix: 105, 54, 245;
  --color-primary-500-mix: 183, 144, 252;
  font-family: Fira Sans Condensed, Arial;
  margin: 0;
}

.menu-sidebar-overlay {
  position: fixed;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 200;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  color: white;
}

.menu-sidebar {
  position: relative;
  height: 100%;
  width: 35vw;
  background-color: var(--color-primary-100);
  display: flex;
}

.menu-sidebar .rectangle {
  width: 15%;
  height: 100%;
  background-color: var(--color-surface-300);
}

.menu-sdbr-title {
  display: inline;
  color: var(--color-primary-200);
  font-size: 40px;
  margin: 15px 0 0 10px;
  color: white;
}

.menu-sdbr-contents {
  width: 100%;
  position: relative;
  height: 100%;
  flex: 1;
  display: flex;
  flex-direction: column;
  margin-left: 10px;
}

.menu-sdbr-list {
  position: absolute;
  width: 100%;
  padding: 0;
  margin: 90px 0 0 0;
  list-style-type: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  flex: 1;
  height: 100%;
}

.menu-sdbr-list-indicator {
  position: absolute;
  top: 50%;
  margin-top: -65px;
  right: 0;
  width: 100%;
  height: 60px;
  background-color: var(--color-surface-300);
  z-index: 250;
  transform: translateY(-50%);
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  transition: margin-top 150ms;
}

.menu-sdbr-list-item button {
  position: relative;
  background-color: transparent;
  border: 0 solid rgba(0, 0, 0, 1);
  width: 100%;
  padding: 0 15px;
  height: 60px;
  text-align: left;
  display: flex;
  align-items: center;
  color: var(--color-surface-300);
  z-index: 300;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  font-size: 15px;
  font-weight: 400;
  z-index: 300;
  /*
border: 1px solid rgba(0, 0, 0, 1);
border-right: none;
*/
  transition: color 150ms;
}

.menu-sdbr-list-item button .material-icons {
  margin-right: 15px;
  font-size: 20px;
}
<nav class = "menu-sidebar-overlay">
  <div class = "menu-sidebar">
    <div class = "menu-sdbr-contents">
      <h1 class = "menu-sdbr-title">MENU</h1>
      <ul class = "menu-sdbr-list" id = "menu-sdbr-list">
        <li class = "menu-sdbr-list-indicator" id = "menu-sdbr-list-indicator">
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button style = "color: white">
                  <span class = "material-icons">dark_mode</span>
                  Dark Mode
                </button>
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                  <span class = "material-icons">settings</span>
                  Settings
                </button>
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                  <span class = "material-icons">logout</span>
                  Log Out
                </button>
        </li>
      </ul>
    </div>
    <div class = "rectangle"></div>
  </div>
</nav>

Начальный margin-top основан на количестве элементов над средним элементом, который есть — поскольку есть три элемента, и каждый элемент имеет высоту 60 пикселей с промежутком 5 пикселей, есть один элемент выше, поэтому вы имеете отступ -65 пикселей. Если бы было 4 элемента, было бы 1,5 элемента выше, то есть 1,5 * -65.

Если вы измените -65 в css, вам также нужно будет изменить его в js.

Ух ты. Я понимаю часть css, но я не понимаю переменную initialPosition, если все в порядке, можете ли вы объяснить мне это?

CindyTheCat 09.08.2023 19:33

Немного хакерский, но это та функциональность, которую вы ищете?

const menuButtonElements   = document.querySelectorAll('#menu-sdbr-list-item button');
const menuIndicatorElement = document.getElementById('menu-sdbr-list-indicator');
const menuSidebarUlElement = document.getElementById('menu-sdbr-list');
let selectedButtonIndex = 0;
let marginTop = 27;

menuButtonElements.forEach((value, index) => {
  value.addEventListener('click', () => {
    menuIndicatorElement.style.display = "block";
    marginTop = (index - selectedButtonIndex) * 65 + marginTop;
    menuIndicatorElement.style.marginTop = marginTop + "px";
    menuButtonElements.forEach(value => {
      value.setAttribute('style', `
      color: var(--color-surface-300);
      `)
    })
    menuButtonElements[index].setAttribute('style', `
    color: white;
    `)
    selectedButtonIndex = index;
  })
})
@import url('https://fonts.googleapis.com/css2?family=Fira+Sans+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
@import "https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Round";
body {
  --color-primary-100: rgb(105, 54, 245);
  --color-primary-200: rgb(128, 78, 247);
  --color-primary-300: rgb(148, 100, 249);
  --color-primary-400: rgb(166, 122, 251);
  --color-primary-500: rgb(183, 144, 252);
  --color-primary-600: rgb(199, 165, 253);
  --color-surface-100: rgb(0, 0, 0);
  --color-surface-200: rgb(30, 30, 30);
  --color-surface-300: rgb(53, 53, 53);
  --color-surface-400: rgb(78, 78, 78);
  --color-surface-500: rgb(105, 105, 105);
  --color-surface-600: rgb(133, 133, 133);
  --color-surface-mixed-100: rgb(26, 22, 37);
  --color-surface-mixed-200: rgb(40, 35, 48);
  --color-surface-mixed-300: rgb(63, 58, 70);
  --color-surface-mixed-400: rgb(88, 83, 94);
  --color-surface-mixed-500: rgb(113, 109, 119);
  --color-surface-mixed-600: rgb(140, 136, 144);
  --color-primary-100-mix: 105, 54, 245;
  --color-primary-500-mix: 183, 144, 252;
  font-family: Fira Sans Condensed, Arial;
  margin: 0;
}

.menu-sidebar-overlay {
  position: fixed;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 200;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  color: white;
}

.menu-sidebar {
  position: relative;
  height: 100%;
  width: 35vw;
  background-color: var(--color-primary-100);
  display: flex;
}

.menu-sidebar .rectangle {
  width: 15%;
  height: 100%;
  background-color: var(--color-surface-300);
}

.menu-sdbr-title {
  display: inline;
  color: var(--color-primary-200);
  font-size: 40px;
  margin: 15px 0 0 10px;
  color: white;
}

.menu-sdbr-contents {
  width: 100%;
  position: relative;
  height: 100%;
  flex: 1;
  display: flex;
  flex-direction: column;
  margin-left: 10px;
}

.menu-sdbr-list {
  position: absolute;
  width: 100%;
  padding: 0;
  margin: 90px 0 0 0;
  list-style-type: none;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  flex: 1;
  height: 100%;
}

.menu-sdbr-list-indicator {
  display: none;
  width: 100%;
  height: 60px;
  background-color: var(--color-surface-300);
  z-index: 250;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  transition: margin-top 150ms;
}

.menu-sdbr-list-item {
  width: 100%;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;  
}

.menu-sdbr-list-item button {
  position: relative;
  background-color: transparent;
  border: 0 solid rgba(0, 0, 0, 1);
  width: 100%;
  padding: 0 15px;
  height: 60px;
  text-align: left;
  display: flex;
  align-items: center;
  color: var(--color-surface-300);
  z-index: 300;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  font-size: 15px;
  font-weight: 400;
  z-index: 300;
  /*
border: 1px solid rgba(0, 0, 0, 1);
border-right: none;
*/
  transition: color 150ms;
}

.menu-sdbr-list-item button .material-icons {
  margin-right: 15px;
  font-size: 20px;
}
<nav class = "menu-sidebar-overlay">
  <div class = "menu-sidebar">
    <div class = "menu-sdbr-contents">
      <h1 class = "menu-sdbr-title">MENU</h1>
        <div class = "menu-sdbr-list-indicator" id = "menu-sdbr-list-indicator">
        </div>
      <ul class = "menu-sdbr-list" id = "menu-sdbr-list">
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                  <span class = "material-icons">dark_mode</span>
                  Dark Mode
                </button>
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                  <span class = "material-icons">settings</span>
                  Settings
                </button>
        </li>
        <li class = "menu-sdbr-list-item" id = "menu-sdbr-list-item">
          <button>
                  <span class = "material-icons">logout</span>
                  Log Out
                </button>
        </li>
      </ul>
    </div>
    <div class = "rectangle"></div>
  </div>
</nav>

Другие вопросы по теме