web-dev-qa-db-ja.com

ディスプレイなしからディスプレイブロックへ、またはその逆へのCSS移行

私はこの質問がおそらくSOで何百万回も尋ねられたことを知っていますが、ほとんどの解決策を試しましたが、なぜ私にとってうまくいかないのか分かりません。

そのため、最初はdisplayをターゲットとしたnoneのドロップダウンがあります。クリックすると、素敵な移行が表示されます。 (ここまでは順調ですね)。しかし、ドロップダウンを非表示にするためにもう一度クリックすると、すぐに非表示になりますが、それは望ましくありません。表示するように割り当てられた同様のトランジションで非表示にします。 CSSのコードは次のとおりです。

.dropdown-menu {
  padding: 0 0;
  display: none;
  -webkit-animation: slide-down .3s ease-out;
  -moz-animation: slide-down .3s ease-out;
}

.table-dropdown-open {
  display: block;
  -webkit-animation: slide-down .3s ease-out;
  -moz-animation: slide-down .3s ease-out;
}

@-webkit-keyframes slide-down {
  0% {
    opacity: 0;
    -webkit-transform: translateY(-10%);
  }
  100% {
    opacity: 1;
    -webkit-transform: translateY(0);
  }
}

@-moz-keyframes slide-down {
  0% {
    opacity: 0;
    -moz-transform: translateY(-10%);
  }
  100% {
    opacity: 1;
    -moz-transform: translateY(0);
  }
}

Imはblockからnoneへの移行を試みているため、これは重複ではありません。 noneからblockへではありません

7
DingDong

display常に要素であり、transition任意のanimatableプロパティのみ。あなたの場合、opacityは良い候補のように見えますが、transformで遊ぶことはあなたに望ましい結果を与えるかもしれません。簡単な例:

any {
  transform: scale(0);
  transition: transform .4s cubic-bezier(.5,0,.3,1);
}
any.animated {
  transform: scale(1);
}

実際には、opacitytransformは、アニメーション要素以外にDOMを再ペイントする必要がないため、アニメーション化する必要がある2つのプロパティである必要があります。大量の要素を同時にアニメーション化する場合でも、ブラウザのパフォーマンスが向上します。

ペイントされていなくても、要素は、実際には、transformedがまったくない場合にある場所にあることに注意してください。したがって、 "invisible"状態にあるときにpointer-events:noneを、にあるときにpointer-events:allを与えることができます。 「可視」状態。したがって、表示されていない間はポインターイベントをキャッチしません。


あなたの例を考慮して、2つのアニメーションの例を示しました(キーフレームありとなし)。 prefix your code にする必要があることを忘れないでください。ブラウザとの完全な互換性を得るには、設定で> 0%を使用します(下部の小さなボックス)。

setTimeout(function(){
  var dm = document.querySelector('.dropdown-menu');
  dm.classList.remove('hide-menu');
}, 300);
/* simple animation example, on parent. No keyframes. */
.dropdown-menu.hide-menu {
  opacity: 0;
}
.dropdown-menu {
  opacity: 1;
  transition: opacity .2s cubic-bezier(.4,0,.2,1);
  position: relative;
  animation: delay-overflow .3s;
  animation-fill-mode: forwards;
  animation-iteration-count: 1;
}
.dropdown-menu:hover {
  animation: none;
  cursor: pointer;
}

/* animation example with keyframes, on child */

.dropdown-menu ul {
  position: absolute;
  margin-top: 0;
  padding-top: 1rem;
  top: 100%;
  opacity: 0;
  transform: translateY(-10%);
  animation: slide-up .3s;
  animation-fill-mode: forwards;
  animation-iteration-count: 1;
}

.drowdown-menu.hide-menu ul {
  animation-duration: 0s;
}
.dropdown-menu:hover ul {
  animation: slide-down .3s;
  animation-fill-mode: forwards;
}


@keyframes slide-down {
  from {
    opacity: 0;
    transform: translateY(-10%);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slide-up {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(-10%);
  }
}
@keyframes delay-overflow {
  0% {
    overflow: visible;
  }
  99% {
    overflow: visible;
  }
  100% {
    overflow: hidden;
  }
}
<div class="dropdown-menu hide-menu">
  <span>Menu</span>
  <ul>
    <li>A menu item</li>
    <li>Another menu item</li>
    <li>...</li>
    <li>And so on...</li>
  </ul>
</div>

注:animationプロパティの非常に便利なトリックは、アニメーション化されていないプロパティでも適用を遅らせることができるということです。希望の時間。このトリックを使用して、overflow:hiddenが親に適用されるのを遅らせます(overflowはアニメートできません)。子のアニメーション(親の境界の外側で発生)は最後まで表示されます。 。終了後、overflow:hiddenが適用され、メニューオープナーの外側のマウスイベントをキャッチしなくなります。

11

これは単純なロジックであり、現在は下にスライドするスタイルを設定していますが、divのキャンセルのスタイルは設定していません。最初に閉じた状態にする必要があります。

.dropdown-menu {
    transition: all 500ms ease;
}

または単に使用する

.dropdown-menu {
    transition: margin 300ms cubic-bezier(0.17, 0.04, 0.03, 0.94);
}

これが機能しない場合、

0
Tsitso Makhakhe