Как вы переходите между display: none и display: block? - PullRequest
4 голосов
/ 04 апреля 2019

Я пытаюсь отложить появление элементов мобильной навигации (в идеале, не используя JS для задержки их появления), пока наложение навигации полностью не расширится (0,4 с).

Существует два состояния: 1. несостояние наложения: слева вверху навигация с меню гамбургера и справа с моим именем.4 навигационные ссылки скрыты.2. состояние наложения: меню гамбургера превращается в x, верхняя навигационная панель переходит на всю страницу, и 4 навигационные ссылки отображаются централизованно на оверлейной странице.

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

Похоже, здесь работает: https://codepen.io/KingKabir/pen/QyPwgG, но я не уверен, как они это делают?

Я пытался использовать visibility: и opacity: но они не полностью скрывают 4 навигационных элемента в неперекрывающемся состоянии, таким образом путая мое имя в правой части навигационного меню всостояние наложения.

HTML:

  <nav class="nav_container" id="overlay">
    <div class="hamburger" id="hamburger" onclick="mobileMenu()">
      <div class="bar1"></div>
      <div class="bar2"></div>
      <div class="bar3"></div>
    </div>
    <div class="icon_personal_container">
      <a href="../index.html">
        <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon_personal">
          <title>J Logo</title>
          <defs>
            <linearGradient x1="14.6040568%" y1="100%" x2="85.3959432%" y2="0%" id="linearGradient-1">
              <stop stop-color="#12A9FF" offset="0%"></stop>
              <stop stop-color="#FF0096" offset="100%"></stop>
            </linearGradient>
          </defs>
          <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
            <circle fill="#333333" cx="12" cy="11.94" r="12"></circle>
            <polygon points="18.57144 7.82616 14.68812 7.82616 12 7.82616 12 5.16 18.57144 5.16"></polygon>
            <path d="M12.0021063,5.16 L17.3805494,5.16 L14.6827527,7.80073139 L14.6827527,13.044557 C14.6827527,16.5810127 13.1030779,18.9 9.57770614,18.9 C8.045129,18.9 6.72924975,18.3030871 5.82008559,17.4140986 C5.81142009,17.4056254 6.46074609,16.7540162 7.76806357,15.459271 C8.20030047,15.9163181 8.81488621,16.2138397 9.57770614,16.2138397 C11.2344382,16.2138397 11.985747,15.1509705 11.985747,13.1218565 L11.985747,5.16 L12.0021063,5.16 Z"
              fill="url(#linearGradient-1)"></path>
          </g>
        </svg>
      </a>
    </div>
    <div class="nav_tab" id="nav_tab_about"><a href="#about" class="nav_tab_hover_effect" onclick="mobileMenu()">About</a></div>
    <div class="nav_tab" id="nav_tab_work"><a href="#work" class="nav_tab_hover_effect" onclick="mobileMenu()">Work</a></div>
    <div class="nav_tab" id="nav_tab_skills"><a href="#skills" class="nav_tab_hover_effect" onclick="mobileMenu()">Skills</a></div>
    <div class="nav_tab" id="nav_tab_contact"><a href="#contact" class="nav_tab_hover_effect" onclick="mobileMenu()">Contact</a></div>
    <div class="blanks"></div>
    <div class="blanks"></div>
    <div id="nav_text">Jordan Tranchina</div>
  </nav>

CSS:

    .nav_container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr !important;
    grid-template-rows: auto;
    column-gap: 16px;
    grid-template-areas:
      "nav-far-left nav-left nav-right nav-far-right";
  }
  .nav_container.open {
    max-height: 100%;
    height: 200%;
    background-color: #000000;
    display: grid;
    grid-template-rows: auto auto auto auto auto;
    grid-template-areas:
      "nav-far-left nav-left nav-right nav-far-right"
      "second second second second"
      "third third third third"
      "fourth fourth fourth fourth"
      "fifth fifth fifth fifth";
    transition: all 0.4s cubic-bezier(0.455, 0.03, 0.515, 0.955);
  }

  .icon_personal_container,.blanks{
    display: none;
  }
  .nav_tab {
    display: block;
    height: 0;
    width: 0;
    visibility: hidden;
    opacity: 0;
  }
  .nav_tab.open{
    display: block;
    height: auto;
    font-size: 32px;
    font-weight: 500;
    padding-top: 64px;
    visibility: visible;
    opacity: 1;
    transition: visibility 0s linear;
  }

  #nav_tab_about.open{
    grid-area: second;
    transition-delay: .10s;
    width: auto;
  }
  #nav_tab_work.open {
    grid-area: third;
    transition-delay: .15s;
    width: auto;
  }
  #nav_tab_skills.open {
    grid-area: fourth;
    transition-delay: .2s;
    width: auto;
  }
  #nav_tab_contact.open {
    grid-area: fifth;
    transition-delay: .25s;
    width: auto;
  }

  #nav_text {
    grid-area: 1 / nav-right / 1 / nav-far-right;
  }

Javascript:

function mobileMenu() {
  document.getElementById("hamburger").classList.toggle("active"); // toggling active class
  document.body.classList.toggle("overlay-body"); //toggling overlay state on body
  document.getElementById("overlay").classList.toggle("open"); //toggling overlay state on nav by setting classlist to "open"
  // improve below by grabing by class not by id
  document.getElementById("nav_tab_about").classList.toggle("open");
  document.getElementById("nav_tab_work").classList.toggle("open");
  document.getElementById("nav_tab_skills").classList.toggle("open");
  document.getElementById("nav_tab_contact").classList.toggle("open");
}

Я ожидаю элементы nav класса«nav_tab» появляется через несколько десятых секунды после того, как nav_container успевает полностью развернуться.

Текущий результат заключается в том, что элементы nav класса «nav_tab» появляются немедленно, прежде чем nav_container успеет полностью развернуться.

Ответы [ 2 ]

5 голосов
/ 04 апреля 2019

Если вы используете visibility и opacity в сочетании с max-height, вы можете добиться хорошего перехода от видимого к скрытому или наоборот.Установка элемента max-height в 0, когда он скрыт, и max-height в Xpx (больше, чем будет когда-либо элемент), когда он виден, предотвращает возможность какого-либо взаимодействия элемента с вашим макетом (как вы упомянули вВаш вопрос).

Вот краткий пример:

var visible = document.querySelector(".visible");

function hide() {
  visible.classList.add("hidden");
}

visible.addEventListener("click", hide);
div {
  background-color: blue;
  padding: 40px;
  color: white;
  cursor: pointer;
  transition: all .1s ease;
}

.visible {
  visibility: visible;
  opacity: 1;
  max-height: 1000px;
}

.hidden {
  visibility: hidden;
  opacity: 0;
  max-height: 0;
}
<div class="visible">Click to hide</div>
1 голос
/ 05 апреля 2019

Вы можете просто добавить к вам еще один параметр transition, который называется 'delay'.Задержка является четвертым параметром для перехода, в вашем случае это может выглядеть следующим образом:

transition: all 0.4s cubic-bezier(0.455, 0.03, 0.515, 0.955) 2s;

Теперь эта анимация начнется с задержкой в ​​2 секунды.

Чтобы сделать вас ближе к тому, что вы хотитедобившись, я внес в ваш CSS небольшие изменения, которые я опишу ниже:

  1. Для элемента .nav_container.open замените строки:

    max-height: 100%;
    height: 200%;
    

    одной строкой:

    min-height: 100vh;
    

    Это заставит ваш контейнер расширяться как минимум до высоты окна.

  2. Для элемента .nav_tab заменить:

    display: none;
    

    с:

    display: block;
    opacity: 0;
    

    С этим вы можете скрыть свои ссылки и избежать анимации их отображения.

  3. Для элемента .nav_tab.open удалите эти две строки:

    display: block;
    visibility: visible;
    

    и добавьте эти две строки:

    opacity: 1;
    transition: all 0.6s linear 0.4s;
    

    Где 0,6 с - длительность анимации, а 0,4 с - задержка - установите ее не ниже, чем длительность для расширения nav_container.

Проверьте результат и дайте мне знать, если вы ближе к вашей цели;)

...