Frage

Ich versuche, nach unten mit Hilfe von CSS-Übergängen ein <ul> Dia zu machen.

Die <ul> beginnt bei height: 0; ab. Auf schweben, wird die Höhe auf height:auto; gesetzt. Dies ist jedoch so dass es zu einfach erscheinen, nicht Übergang

Wenn ich es von height: 40px; zu height: auto; tun, dann wird es zu height: 0; nach oben schieben, und dann auf die richtige Höhe plötzlich springen.

Wie sonst könnte ich dies tun, ohne Verwendung von JavaScript?

#child0 {
  height: 0;
  overflow: hidden;
  background-color: #dedede;
  -moz-transition: height 1s ease;
  -webkit-transition: height 1s ease;
  -o-transition: height 1s ease;
  transition: height 1s ease;
}
#parent0:hover #child0 {
  height: auto;
}
#child40 {
  height: 40px;
  overflow: hidden;
  background-color: #dedede;
  -moz-transition: height 1s ease;
  -webkit-transition: height 1s ease;
  -o-transition: height 1s ease;
  transition: height 1s ease;
}
#parent40:hover #child40 {
  height: auto;
}
h1 {
  font-weight: bold;
}
The only difference between the two snippets of CSS is one has height: 0, the other height: 40.
<hr>
<div id="parent0">
  <h1>Hover me (height: 0)</h1>
  <div id="child0">Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>
  </div>
</div>
<hr>
<div id="parent40">
  <h1>Hover me (height: 40)</h1>
  <div id="child40">Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>
  </div>
</div>

War es hilfreich?

Lösung

Mit max-height in der Transformation und nicht height. Und legt Wert auf max-height etwas größer als Ihre Box jemals erhalten.

Siehe JSFiddle Demo zur Verfügung gestellt von Chris Jordan in einem anderen answer hier.

#menu #list {
    max-height: 0;
    transition: max-height 0.15s ease-out;
    overflow: hidden;
    background: #d5d5d5;
}

#menu:hover #list {
    max-height: 500px;
    transition: max-height 0.25s ease-in;
}
<div id="menu">
    <a>hover me</a>
    <ul id="list">
        <!-- Create a bunch, or not a bunch, of li's to see the timing. -->
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
    </ul>
</div>

Andere Tipps

Sie sollten scaleY verwenden stattdessen.

HTML:

<p>Here (scaleY(1))</p>
<ul>
  <li>Coffee</li>
  <li>Tea</li>
  <li>Milk</li>
</ul>

CSS:

ul {
    background-color: #eee;
    transform: scaleY(0);    
    transform-origin: top;
    transition: transform 0.26s ease;
}

p:hover ~ ul {
    transform: scaleY(1);
}

Ich habe einen Anbieter als Präfix Version des obigen Code auf jsfiddle gemacht, http://jsfiddle.net/dotnetCarpenter/PhyQc / 9 / und Ihre jsfiddle zu verwenden scaleY statt Höhe geändert, http://jsfiddle.net/dotnetCarpenter/7cnfc 206 / / .

Sie können derzeit nicht belebter auf Höhe, wenn eine der beteiligten Höhen ist auto, haben Sie zwei explizite Höhen eingestellt werden.

Die Lösung, dass ich immer zum ersten Fade-Out war verwendet haben, dann schrumpfen die font-size, padding und margin Werte. Es sieht nicht das gleiche wie ein Tuch, aber es funktioniert ohne statische height oder max-height.

Arbeits Beispiel:

/* final display */
#menu #list {
    margin: .5em 1em;
    padding: 1em;
}

/* hide */
#menu:not(:hover) #list {
    font-size: 0;
    margin: 0;
    opacity: 0;
    padding: 0;
    /* fade out, then shrink */
    transition: opacity .25s,
                font-size .5s .25s,
                margin .5s .25s,
                padding .5s .25s;
}

/* reveal */
#menu:hover #list {
    /* unshrink, then fade in */
    transition: font-size .25s,
                margin .25s,
                padding .25s,
                opacity .5s .25s;
}
<div id="menu">
    <b>hover me</b>
    <ul id="list">
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
    </ul>
</div>

<p>Another paragraph...</p>

Ich weiß, das ist der dreißig somethingth Antwort auf diese Frage, aber ich denke, es lohnt sich, geht so hier. Dies ist eine CSS-only Lösung mit den folgenden Eigenschaften:

  • Es gibt keine Verzögerung am Anfang, und der Übergang früh nicht zu stoppen. In beiden Richtungen (Auf- und Zuklappen), wenn Sie eine Übergangsdauer von 300 ms in Ihrem CSS angeben, dann erfolgt der Übergang 300ms, period.
  • Es ist die tatsächliche Höhe Übergang (im Gegensatz zu transform: scaleY(0)), so dass er das Richtige tut, wenn es nach dem Inhalt zusammenklappbaren Elemente ist.
  • Während (wie in anderen Lösungen) es sind magische Zahlen (wie „eine Länge auswählen, die höher ist als Ihre Box jemals sein wird“), ist es nicht tödlich ist, wenn Ihre Annahme endet als falsch. Der Übergang kann in diesem Fall nicht toll aussehen, aber vor und nach dem Übergang, ist dies kein Problem: In dem erweiterten (height: auto) Zustand, der gesamte Inhalt immer die richtige Höhe (im Gegensatz zu zB hat, wenn Sie ein max-height auswählen, die herausstellt, als zu niedrig). Und im zusammengeklappten Zustand ist die Höhe null ist, wie es sein sollte.

Demo

Hier ist ein Demo mit drei zusammenklappbare Elemente, die alle unterschiedlichen Höhen, dass alle verwenden die gleichen CSS. Vielleicht möchten Sie „ganze Seite“ nach einem Klick auf „run-Schnipsel“ klicken. Beachten Sie, dass die JavaScript schaltet nur die collapsed CSS-Klasse, gibt es keine Mess beteiligt. (Sie können durch die Verwendung einer Checkbox oder :target ganz ohne JavaScript genau dieses Demo tun). Beachten Sie auch, dass der Teil der CSS, die für den Übergang verantwortlich ist ziemlich kurz ist, und die HTML erfordert nur einen einzigen zusätzlichen Wrapperelement.

$(function () {
  $(".toggler").click(function () {
    $(this).next().toggleClass("collapsed");
    $(this).toggleClass("toggled"); // this just rotates the expander arrow
  });
});
.collapsible-wrapper {
  display: flex;
  overflow: hidden;
}
.collapsible-wrapper:after {
  content: '';
  height: 50px;
  transition: height 0.3s linear, max-height 0s 0.3s linear;
  max-height: 0px;
}
.collapsible {
  transition: margin-bottom 0.3s cubic-bezier(0, 0, 0, 1);
  margin-bottom: 0;
  max-height: 1000000px;
}
.collapsible-wrapper.collapsed > .collapsible {
  margin-bottom: -2000px;
  transition: margin-bottom 0.3s cubic-bezier(1, 0, 1, 1),
              visibility 0s 0.3s, max-height 0s 0.3s;
  visibility: hidden;
  max-height: 0;
}
.collapsible-wrapper.collapsed:after
{
  height: 0;
  transition: height 0.3s linear;
  max-height: 50px;
}

/* END of the collapsible implementation; the stuff below
   is just styling for this demo */

#container {
  display: flex;
  align-items: flex-start;
  max-width: 1000px;
  margin: 0 auto;
}  


.menu {
  border: 1px solid #ccc;
  box-shadow: 0 1px 3px rgba(0,0,0,0.5);
  margin: 20px;

  
}

.menu-item {
  display: block;
  background: linear-gradient(to bottom, #fff 0%,#eee 100%);
  margin: 0;
  padding: 1em;
  line-height: 1.3;
}
.collapsible .menu-item {
  border-left: 2px solid #888;
  border-right: 2px solid #888;
  background: linear-gradient(to bottom, #eee 0%,#ddd 100%);
}
.menu-item.toggler {
  background: linear-gradient(to bottom, #aaa 0%,#888 100%);
  color: white;
  cursor: pointer;
}
.menu-item.toggler:before {
  content: '';
  display: block;
  border-left: 8px solid white;
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  width: 0;
  height: 0;
  float: right;
  transition: transform 0.3s ease-out;
}
.menu-item.toggler.toggled:before {
  transform: rotate(90deg);
}

body { font-family: sans-serif; font-size: 14px; }

*, *:after {
  box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
  <div class="menu">
    <div class="menu-item">Something involving a holodeck</div>
    <div class="menu-item">Send an away team</div>
    <div class="menu-item toggler">Advanced solutions</div>
    <div class="collapsible-wrapper collapsed">
      <div class="collapsible">
        <div class="menu-item">Separate saucer</div>
        <div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
        <div class="menu-item">Ask Worf</div>
        <div class="menu-item">Something involving Wesley, the 19th century, and a holodeck</div>
        <div class="menu-item">Ask Q for help</div>
      </div>
    </div>
    <div class="menu-item">Sweet-talk the alien aggressor</div>
    <div class="menu-item">Re-route power from auxiliary systems</div>
  </div>

  <div class="menu">
    <div class="menu-item">Something involving a holodeck</div>
    <div class="menu-item">Send an away team</div>
    <div class="menu-item toggler">Advanced solutions</div>
    <div class="collapsible-wrapper collapsed">
      <div class="collapsible">
        <div class="menu-item">Separate saucer</div>
        <div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
      </div>
    </div>
    <div class="menu-item">Sweet-talk the alien aggressor</div>
    <div class="menu-item">Re-route power from auxiliary systems</div>
  </div>

  <div class="menu">
    <div class="menu-item">Something involving a holodeck</div>
    <div class="menu-item">Send an away team</div>
    <div class="menu-item toggler">Advanced solutions</div>
    <div class="collapsible-wrapper collapsed">
      <div class="collapsible">
        <div class="menu-item">Separate saucer</div>
        <div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
        <div class="menu-item">Ask Worf</div>
        <div class="menu-item">Something involving Wesley, the 19th century, and a holodeck</div>
        <div class="menu-item">Ask Q for help</div>
        <div class="menu-item">Separate saucer</div>
        <div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
        <div class="menu-item">Ask Worf</div>
        <div class="menu-item">Something involving Wesley, the 19th century, and a holodeck</div>
        <div class="menu-item">Ask Q for help</div>
      </div>
    </div>
    <div class="menu-item">Sweet-talk the alien aggressor</div>
    <div class="menu-item">Re-route power from auxiliary systems</div>
  </div>

</div>

Wie funktioniert es?

Es ist in der Tat zwei beteiligten Übergänge dies bei der Herstellung geschehen. Einer von ihnen geht das margin-bottom von 0px (im expandierten Zustand) zu -2000px im zusammengeklappten Zustand (ähnlich diese Antwort ) . Die 2000 hier die erste magische Zahl, es basiert auf der Annahme, dass Ihre Box nicht höher sein als dies (2000 Punkte scheinen wie eine vernünftige Wahl).

Mit dem margin-bottom Übergang allein durch selbst hat zwei Probleme:

  • Wenn Sie tatsächlich ein Feld haben, die höher als 2000 Pixel ist, dann wird ein margin-bottom: -2000px nicht versteckt alles - es werde sichtbar Sachen sein, auch in dem zusammengeklappten Fall. Dies ist ein kleineres Update, dass wir es später tun.
  • Wenn die Ist-Box ist, sagt, 1000 Pixel hoch, und die Umstellung ist 300ms lang, dann die sichtbar Übergang ist bereits vorbei nach ca. 150ms (oder in der entgegengesetzten Richtung, beginnt 150ms spät ).

Diese zweite Ausgabe Fixing ist, wo der zweite Übergang kommt, und dieser Übergang zielt konzeptionell den Wrapper des Minimum Höhe ( „konzeptionell“, weil wir eigentlich nicht die min-height Eigenschaft für diese Verwendung, mehr auf dass später).

Hier ist eine Animation, die zeigt, wie Sie den unteren Rand Übergang mit der minimalen Höhe Übergang kombiniert, beide von gleicher Dauer, gibt uns einen kombinierten Übergang von der vollen Höhe auf Null Höhe, die die gleiche Dauer hat.

 Animation wie oben

Die linken Balken zeigen, wie der negativer untere Rand nach oben dem Boden drückt, die sichtbare Höhe zu reduzieren. Die mittleren Balken zeigen, wie die Mindesthöhe sicherstellt, dass in dem zusammenbrechenden Fall wird der Übergang nicht vorzeitig beenden, und im expandierenden Fall wird der Übergang nicht zu spät beginnen. Die rechte Balken zeigt, wie die Kombination der beiden bewirkt, dass die BoxÜbergang von der vollen Höhe auf Null Höhe in der richtigen Menge an Zeit.

Für meine Demo Ich habe auf 50px als obere Mindesthöhe Wert abzurechnen. Dies ist die zweite magische Zahl, und es sollte als die Höhe ‚Box niedriger sein würde jemals sein. 50px scheint auch vernünftig; es scheint unwahrscheinlich, dass Sie sehr oft wollen würden ein Element zusammenklappbar machen, das nicht einmal 50 Pixel hoch in erster Linie ist.

Wie Sie in der Animation sehen können, ist der resultierende Übergang kontinuierlich ist, aber es ist nicht differenzierbar - im Moment, wenn die Mindesthöhe auf die volle Höhe des unteren Rand angepasst gleich ist, gibt es eine plötzliche Veränderung der Geschwindigkeit . Dies ist sehr auffällig in der Animation, weil es eine lineare Zeitfunktion für beiden Übergänge verwendet, und weil der ganze Übergang ist sehr langsam. Im konkreten Fall (meine Demo an der Spitze), findet der Übergang nur 300ms, und der untere Rand Übergang ist nicht linear. Ich habe mit vielen verschiedenen Timing-Funktionen für beide Übergänge rumgespielt, und die, die ich am Ende mit fühlte sich wie sie für die unterschiedlichsten Fälle am besten funktioniert.

Zwei Probleme bleiben fix:

  1. der Punkt, von oben, wo Kisten von mehr als 2000 Pixeln in der Höhe nicht vollständig im zusammengeklappten Zustand versteckt,
  2. und das umgekehrte Problem, wo in dem nicht-versteckten Fall, Schachteln von weniger als 50 Pixeln Höhe zu hoch sind, auch wenn der Übergang nicht läuft, weil die minimale Höhe sie bei 50 Pixeln hält.

Wir lösen das erste Problem, das durch das Containerelement eine max-height: 0 im kollabierten Fall geben, mit einem 0s 0.3s Übergang. Dies bedeutet, dass es nicht wirklich ein Übergang, aber die max-height wird mit einer Verzögerung angelegt wird; es gilt nur, wenn der Übergang vorbei ist. Damit dies korrekt funktioniert, müssen wir auch eine numerische max-height für das Gegenteil, nicht zusammenbrach, Zustand holen. Aber anders als im 2000px Fall, wo zu sammeln großen eine Zahl, die die Qualität des Übergangs beeinflusst, in diesem Fall, es ist wirklich egal. So können wir nur eine Nummer wählen, die so hoch ist, dass wir wissen , dass keine Höhe immer nah an diese kommen wird. Ich nahm eine Million Pixel. Wenn Sie das Gefühl, Sie zu unterstützen Inhalt einer Höhe von mehr als einer Million Pixel benötigen, dann 1) Es tut mir leid, und 2) fügen Sie einfach ein paar Nullen.

Das zweite Problem ist der Grund, warum sind wir nicht wirklich min-height für die Mindesthöhe Übergang verwenden. Stattdessen gibt es ein ::after Pseudoelement in den Behälter mit einem height, dass Übergänge von 50 Pixel auf Null ab. Dies hat den gleichen Effekt wie ein min-height: Es wird der Behälter unten nicht zulassen, schrumpft, was auch immer die Höhe des Pseudoelement hat derzeit. Aber weil wir height verwenden, nicht min-height, können wir jetzt max-height (wieder einmal mit einer Verzögerung angewendet wird) verwenden, das Pseudoelement tatsächlichen Höhe auf Null zu setzen, sobald der Übergang vorbei ist, sicherzustellen, dass zumindest außerhalb des Übergangs, auch kleine Elemente haben die richtige Höhe. Da min-height als max-height href="https://stackoverflow.com/q/13845224/115866">, dies würde nicht funktionieren, wenn wir den Behälter min-height anstelle des Pseudo-Elements height verwendet. Genau wie die max-height im vorigen Absatz dieses max-height braucht auch einen Wert für das entgegengesetzte Ende des Übergangs. Aber in diesem Fall können wir nur die 50px holen.

Getestet in Chrome (Win, Mac, Android, iOS), Firefox (Win, Mac, Android), Edge IE11 (mit Ausnahme eines Flexbox Layout Problem mit meiner Demo, dass ich nicht dem Debuggen störte) und Safari ( Mac, iOS). Apropos Flexbox, sollte es möglich sein, diese Arbeit zu machen, ohne dass Flexbox verwendet wird; in der Tat denke ich, Sie fast alles, was Arbeit in IE7 machen könnte -. mit Ausnahme der Tatsache, dass Sie nicht CSS-Übergänge haben, ist es eine ziemlich sinnlose Übung machen

Sie können mit ein wenig nicht-semantischen Schmu. Mein üblicher Ansatz ist die Höhe eines äußeren DIV zu animieren, die ein einzelnes Kind, das ein stil weniger DIV nur zur Messung der Inhaltshöhe verwendet wird.

function growDiv() {
  var growDiv = document.getElementById('grow');
  if (growDiv.clientHeight) {
    growDiv.style.height = 0;
  } else {
    var wrapper = document.querySelector('.measuringWrapper');
    growDiv.style.height = wrapper.clientHeight + "px";
  }
}
#grow {
  -moz-transition: height .5s;
  -ms-transition: height .5s;
  -o-transition: height .5s;
  -webkit-transition: height .5s;
  transition: height .5s;
  height: 0;
  overflow: hidden;
  outline: 1px solid red;
}
<input type="button" onclick="growDiv()" value="grow">
<div id='grow'>
  <div class='measuringWrapper'>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
  </div>
</div>

Man würde gern nur mit dem .measuringWrapper zu Abgabe der Lage sein und nur die DIV Höhe auf auto gesetzt und diese animieren, aber das scheint nicht zu Arbeit (die Höhe gesetzt wird, aber keine Animation stattfindet).

function growDiv() {
  var growDiv = document.getElementById('grow');
  if (growDiv.clientHeight) {
    growDiv.style.height = 0;
  } else {
    growDiv.style.height = 'auto';
  }
}
#grow {
  -moz-transition: height .5s;
  -ms-transition: height .5s;
  -o-transition: height .5s;
  -webkit-transition: height .5s;
  transition: height .5s;
  height: 0;
  overflow: hidden;
  outline: 1px solid red;
}
<input type="button" onclick="growDiv()" value="grow">
<div id='grow'>
  <div>
    The contents of my div.
  </div>
  <div>
    The contents of my div.
  </div>
  <div>
    The contents of my div.
  </div>
  <div>
    The contents of my div.
  </div>
  <div>
    The contents of my div.
  </div>
  <div>
    The contents of my div.
  </div>
</div>

Meine Interpretation ist, dass eine explizite Höhe benötigt wird, für die Animation zu starten. Sie können nicht eine Animation auf der Höhe erhalten, wenn entweder Höhe (der Anfang oder das Ende Höhe) auto ist.

Meine Abhilfe ist, um den Übergang max-height auf die genaue Inhalt Höhe für eine schöne glatte Animation, dann mit einem transitionEnd Rückruf 9999px max-Höhe so eingestellt, dass der Inhalt frei skalieren kann.

var content = $('#content');
content.inner = $('#content .inner'); // inner div needed to get size of content when closed

// css transition callback
content.on('transitionEnd webkitTransitionEnd transitionend oTransitionEnd msTransitionEnd', function(e){
    if(content.hasClass('open')){
        content.css('max-height', 9999); // try setting this to 'none'... I dare you!
    }
});

$('#toggle').on('click', function(e){
    content.toggleClass('open closed');
    content.contentHeight = content.outerHeight();
    
    if(content.hasClass('closed')){
        
        // disable transitions & set max-height to content height
        content.removeClass('transitions').css('max-height', content.contentHeight);
        setTimeout(function(){
            
            // enable & start transition
            content.addClass('transitions').css({
                'max-height': 0,
                'opacity': 0
            });
            
        }, 10); // 10ms timeout is the secret ingredient for disabling/enabling transitions
        // chrome only needs 1ms but FF needs ~10ms or it chokes on the first animation for some reason
        
    }else if(content.hasClass('open')){  
        
        content.contentHeight += content.inner.outerHeight(); // if closed, add inner height to content height
        content.css({
            'max-height': content.contentHeight,
            'opacity': 1
        });
        
    }
});
.transitions {
    transition: all 0.5s ease-in-out;
    -webkit-transition: all 0.5s ease-in-out;
    -moz-transition: all 0.5s ease-in-out;
}

body {
    font-family:Arial;
    line-height: 3ex;
}
code {
    display: inline-block;
    background: #fafafa;
    padding: 0 1ex;
}
#toggle {
    display:block;
    padding:10px;
    margin:10px auto;
    text-align:center;
    width:30ex;
}
#content {
    overflow:hidden;
    margin:10px;
    border:1px solid #666;
    background:#efefef;
    opacity:1;
}
#content .inner {
    padding:10px;
    overflow:auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div id="content" class="open">
    <div class="inner">
        <h3>Smooth CSS Transitions Between <code>height: 0</code> and <code>height: auto</code></h3>
        <p>A clever workaround is to use <code>max-height</code> instead of <code>height</code>, and set it to something bigger than your content. Problem is the browser uses this value to calculate transition duration. So if you set it to <code>max-height: 1000px</code> but the content is only 100px high, the animation will be 10x too fast.</p>
        <p>Another option is to measure the content height with JS and transition to that fixed value, but then you have to keep track of the content and manually resize it if it changes.</p>
        <p>This solution is a hybrid of the two - transition to the measured content height, then set it to <code>max-height: 9999px</code> after the transition for fluid content sizing.</p>
    </div>
</div>

<br />

<button id="toggle">Challenge Accepted!</button>

Die akzeptierte Antwort ist für die meisten Fälle, aber es funktioniert nicht gut, wenn Ihr div stark in der Höhe variieren kann -. Die Animationsgeschwindigkeit auf der tatsächlichen Höhe des Inhalts nicht abhängig ist, und es kann abgehackt aussehen

Sie können immer noch die eigentliche Animation mit CSS durchführen, aber Sie müssen JavaScript verwenden, um die Höhe der Elemente zu berechnen, anstatt zu versuchen, auto zu verwenden. Keine jQuery ist erforderlich, obwohl Sie diese ein wenig ändern müssen, wenn Sie Kompatibilität (Arbeiten in der neuesten Version von Chrome:) wollen.)

window.toggleExpand = function(element) {
    if (!element.style.height || element.style.height == '0px') { 
        element.style.height = Array.prototype.reduce.call(element.childNodes, function(p, c) {return p + (c.offsetHeight || 0);}, 0) + 'px';
    } else {
        element.style.height = '0px';
    }
}
#menu #list {
    height: 0px;
    transition: height 0.3s ease;
    background: #d5d5d5;
    overflow: hidden;
}
<div id="menu">
    <input value="Toggle list" type="button" onclick="toggleExpand(document.getElementById('list'));">
    <ul id="list">
        <!-- Works well with dynamically-sized content. -->
        <li>item</li>
        <li><div style="height: 100px; width: 100px; background: red;"></div></li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
    </ul>
</div>

Verwenden max-height mit unterschiedlicher Übergang Lockerung und Verzögerung für jeden Staat.

HTML:

<a href="#" id="trigger">Hover</a>
<ul id="toggled">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
<ul>

CSS:

#toggled{
    max-height: 0px;
    transition: max-height .8s cubic-bezier(0, 1, 0, 1) -.1s;
}

#trigger:hover + #toggled{
    max-height: 9999px;
    transition-timing-function: cubic-bezier(0.5, 0, 1, 0); 
    transition-delay: 0s;
}

Siehe Beispiel: http://jsfiddle.net/0hnjehjc/1/

Keine Werte hart codiert.

Nein JavaScript.

Keine Annäherungen.

Der Trick ist, ein verstecktes & dupliziert div zu verwenden, um den Browser zu bekommen, um zu verstehen, was 100% bedeutet.

Diese Methode ist geeignet, wenn Sie in der Lage das DOM des Elements duplizieren Sie animieren möchten.

.outer {
  border: dashed red 1px;
  position: relative;
}

.dummy {
  visibility: hidden;
}

.real {
  position: absolute;
  background: yellow;
  height: 0;
  transition: height 0.5s;
  overflow: hidden;
}

.outer:hover>.real {
  height: 100%;
}
Hover over the box below:
<div class="outer">
  <!-- The actual element that you'd like to animate -->
  <div class="real">
unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable
content unpredictable content unpredictable content unpredictable content
  </div>
  <!-- An exact copy of the element you'd like to animate. -->
  <div class="dummy" aria-hidden="true">
unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable
content unpredictable content unpredictable content unpredictable content
  </div>
</div>

Es gab nur wenig Erwähnung der Element.scrollHeight Immobilien das hier nützlich sein kann und immer noch mit einem reinen CSS Übergang verwendet werden. Die Eigenschaft enthält immer die „volle“ Höhe eines Element, unabhängig davon, ob und wie sie seinen Inhalt überläuft als Ergebnis kollabierten Höhe (z.B. height: 0).

Als solche für eine height: 0 (effektiv vollständig kollabiert) Element, dessen "normal" oder "voll" Höhe noch durch seine scrollHeight Wert leicht verfügbar ist (immer ein Pixel Länge).

Für ein solches Element, das bereits unter der Annahme hat den Übergang wie z.B. aufgebaut (ul als pro Original Frage verwendet wird):

ul {
    height: 0;
    transition: height 1s; /* An example transition. */
}

Wir können animiert gewünschten Trigger „Expansion“ der Höhe, mit CSS nur, mit so etwas wie die folgenden (hier unter der Annahme ul Variable auf der Liste bezieht):

ul.style.height = ul.scrollHeight + "px";

Das ist es. Wenn Sie die Liste verkleinern müssen, eine der beiden folgenden Aussagen tun:

ul.style.height = "0";
ul.style.removeProperty("height");

Mein besonderer Anwendungsfall ging es um Animieren Listen von unbekannten und oft beträchtlichen Längen, so dass ich nicht bequem Absetzen auf einer beliebigen „groß genug“ height oder max-height Spezifikation war und zu riskieren, Cut-off-Gehalt oder Inhalt, dass Sie plötzlich zu blättern müssen ( wenn overflow: auto, zum Beispiel). Darüber hinaus werden die Lockerung und das Timing gebrochen mit max-height-basierten Lösungen, da die verwendete Höhe viel früher seinen Maximalwert erreichen kann, als es für max-height zu erreichen 9999px nehmen würde. Und als Bildschirmauflösungen wachsen, Pixellängen wie 9999px hinterlassen einen schlechten Geschmack im Mund. Diese besondere Lösung löst das Problem auf elegante Art und Weise, meiner Meinung nach.

Schließlich ist hier, dass künftige Änderungen der CSS-Adresse Autoren Notwendigkeit der Hoffnung, diese Art von Dingen noch eleganter zu tun - erneut den Begriff ‚berechnet‘ vs ‚verwendet‘ und ‚gelöst‘ Werte, und prüfen, ob Übergänge sollten gelten für berechnete Werte, einschließlich der Übergänge mit width und height (die zur Zeit ein bisschen eine spezielle Behandlung erhalten).

Wie poste ich diese gibt es mehr als 30 Antworten schon, aber ich fühle mich meine Antwort auf die bereits verbessert akzeptierte Antwort von jake.

war ich nicht zufrieden mit dem Problem, das aus einfach mit max-height und CSS3 Übergänge entsteht, da so viele Kommentatoren erwähnt, haben Sie Ihren max-height Wert setzen sehr nahe an der tatsächlichen Höhe oder Sie werden eine Verzögerung erhalten. Sehen Sie diesen JSFiddle ein Beispiel für dieses Problem.

Um dies zu umgehen (während noch kein JavaScript verwendet wird), habe ich eine andere HTML-Element, dass Übergänge der transform: translateY CSS Wert.

Dieses Mittel sowohl max-height und translateY verwendet: max-height erlaubt das Element Elemente darunter nach unten zu drücken, während translateY dem „instant“ Effekt gibt wir wollen. Das Problem mit max-height existiert noch, aber seine Wirkung verringert. Das heißt, Sie eine viel größere Höhe für Ihren max-height Wert und Sorgen um es weniger eingestellt werden.

Der Gesamt Vorteil ist, dass auf dem Übergang zurück in (der Zusammenbruch), kann der Benutzer sofort die translateY Animation sieht, so ist es nicht Minster, wie lange der max-height nimmt.

Lösung als Fiddle

body {
  font-family: sans-serif;
}

.toggle {
  position: relative;
  border: 2px solid #333;
  border-radius: 3px;
  margin: 5px;
  width: 200px;
}

.toggle-header {
  margin: 0;
  padding: 10px;
  background-color: #333;
  color: white;
  text-align: center;
  cursor: pointer;
}

.toggle-height {
  background-color: tomato;
  overflow: hidden;
  transition: max-height .6s ease;
  max-height: 0;
}

.toggle:hover .toggle-height {
  max-height: 1000px;
}

.toggle-transform {
  padding: 5px;
  color: white;
  transition: transform .4s ease;
  transform: translateY(-100%);
}

.toggle:hover .toggle-transform {
  transform: translateY(0);
}
<div class="toggle">
  <div class="toggle-header">
    Toggle!
  </div>
  <div class="toggle-height">
    <div class="toggle-transform">
      <p>Content!</p>
      <p>Content!</p>
      <p>Content!</p>
      <p>Content!</p>
    </div>
  </div>
</div>

<div class="toggle">
  <div class="toggle-header">
    Toggle!
  </div>
  <div class="toggle-height">
    <div class="toggle-transform">
      <p>Content!</p>
      <p>Content!</p>
      <p>Content!</p>
      <p>Content!</p>
    </div>
  </div>
</div>

Ok, so dass ich denke, ich kam mit einer super einfachen Antwort auf ... keine max-height verwendet relative Positionierung, arbeitet auf li Elemente, und ist reine CSS. Ich habe nicht in etwas getestet, aber Firefox, obwohl durch die CSS zu urteilen, sollte es auf allen Browsern funktionieren.

FIDDLE: http://jsfiddle.net/n5XfG/2596/

CSS

.wrap { overflow:hidden; }

.inner {
            margin-top:-100%;
    -webkit-transition:margin-top 500ms;
            transition:margin-top 500ms;
}

.inner.open { margin-top:0px; }

HTML

<div class="wrap">
    <div class="inner">Some Cool Content</div>
</div>

EDIT: Scrollen Sie nach aktualisierten Antwort
Ich war ein Drop-Down-Liste und Säge machen this Post ... viele verschiedene Antworten, aber ich entscheide, auch meine Drop-Down-Liste zu teilen, ... Es ist nicht perfekt, aber zumindest wird es nur mit CSS für Drop-down! Ich habe Transformation unter Verwendung von: translateY (y) die Liste der Ansicht ...
zu transformieren Mehr erfahren Sie in dem Test
sehen http://jsfiddle.net/BVEpc/4/
Ich habe hinter jedem li platziert div weil meine Dropdown-Liste aus nach oben kommen und ihnen zu zeigen, richtig dies nötig war, mein div-Code ist:

#menu div {
    transition: 0.5s 1s;
    z-index:-1;
    -webkit-transform:translateY(-100%);
    -webkit-transform-origin: top;
}

und Hover ist:

#menu > li:hover div {
    transition: 0.5s;
    -webkit-transform:translateY(0);
}

und weil ul Höhe auf den Inhalt eingestellt ist es Ihrem Körper Inhalt bekommen kann über Deshalb habe ich dies für ul tat:

 #menu ul {
    transition: 0s 1.5s;
    visibility:hidden;
    overflow:hidden;
}

und schweben:

#menu > li:hover ul {
     transition:none;
     visibility:visible;
}

das zweite Mal nach dem Übergang Verzögerung und es wird versteckt erhalten nach meiner Drop-Down-Liste animately geschlossen wurde ...
später jemand get Vorteil dieser eine Hoffnung.
EDIT: Ich kann einfach nicht glauben, ppl tatsächlich diesen Prototyp mit! Diese Dropdown-Menü ist nur für ein Untermenü und das ist alles !! Ich habe ein besseres aktualisiert, die zwei Untermenü für beide ltr und rtl Richtung mit IE 8-Unterstützung haben.
Fiddle für LTR
Fiddle für RTL
hoffentlich jemand das nützlich in Zukunft finden.

Sie können von der Höhe über: 0 bis Höhe:. Auto vorausgesetzt, Sie haben auch min-height und max-height bieten

div.stretchy{
    transition: 1s linear;
}

div.stretchy.hidden{
    height: 0;
}

div.stretchy.visible{
    height: auto;
    min-height:40px;
    max-height:400px;
}

Flexbox Lösung

Vorteile:

  • einfach
  • no JS
  • fließender Übergang

Nachteile:

  • muss Element in einer festen Höhe flex Behälter gestellt werden

Das System funktioniert so, indem sie immer mit Flex-Basis: Auto auf dem Element mit Inhalt und den Übergang flex-wachsen und Flex schrumpfen statt.

Edit: Verbesserte JS Fiddle von der Xbox Eine Schnittstelle inspiriert.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  transition: 0.25s;
  font-family: monospace;
}

body {
  margin: 10px 0 0 10px;
}

.box {
  width: 150px;
  height: 150px;
  margin: 0 2px 10px 0;
  background: #2d333b;
  border: solid 10px #20262e;
  overflow: hidden;
  display: inline-flex;
  flex-direction: column;
}

.space {
  flex-basis: 100%;
  flex-grow: 1;
  flex-shrink: 0;    
}

p {
  flex-basis: auto;
  flex-grow: 0;
  flex-shrink: 1;
  background: #20262e;
  padding: 10px;
  width: 100%;
  text-align: left;
  color: white;
}

.box:hover .space {
  flex-grow: 0;
  flex-shrink: 1;
}
  
.box:hover p {
  flex-grow: 1;
  flex-shrink: 0;    
}
<div class="box">
  <div class="space"></div>
  <p>
    Super Metroid Prime Fusion
  </p>
</div>
<div class="box">
  <div class="space"></div>
  <p>
    Resident Evil 2 Remake
  </p>
</div>
<div class="box">
  <div class="space"></div>
  <p>
    Yolo The Game
  </p>
</div>
<div class="box">
  <div class="space"></div>
  <p>
    Final Fantasy 7 Remake + All Additional DLC + Golden Tophat
  </p>
</div>
<div class="box">
  <div class="space"></div>
  <p>
    DerpVille
  </p>
</div>

JS Fiddle

Ich glaube, ich kam mit einer wirklich festen Lösung bis

OK! Ich weiß, das Problem ist so alt wie das Internet, aber ich denke, ich eine Lösung, die ich in eine Plugin Mutante genannt -Elektronenübergang . Meine Lösung setzt die style="" Attribute für Kettenelemente, wenn Theres eine Änderung des DOM. das Endergebnis ist, dass Sie Hacky Fixes oder spezielle Javascript gute alte CSS für Ihre Übergänge und nicht verwenden können. Das einzige, was Sie tun müssen, ist Satz, was Sie auf dem betreffenden Element verfolgen möchten mit data-mutant-attributes="X".

<div data-mutant-attributes="height">                                                                      
        This is an example with mutant-transition                                                                                                          
    </div>

Das ist es! Diese Lösung verwendet MutationObserver Änderungen im DOM zu folgen. Aus diesem Grund, haben Sie wirklich nicht zu Satz etwas haben oder zu verwenden JavaScript, um manuell animieren Dinge. Änderungen werden automatisch nachgeführt. Da es jedoch MutationObserver verwendet, wird dies nur in IE11 + übergehen.

Geigen!

Hier ist ein Weg, um den Übergang von einem beliebigen Starthöhe, einschließlich 0, auto (volle Größe und flexibel) ohne Festsatzcode zu erfordern auf einer Pro-Knoten-Basis oder einen Benutzer-Code zu initialisieren: https://github.com/csuwildcat/transition-auto . Dies ist im Grunde der heilige Gral für das, was Sie wollen, ich glaube -> http://codepen.io/csuwldcat / pen / kwsdF . Gerade schlagen die folgende JS-Datei in die Seite, und alle müssen Sie tun, nachdem das Hinzufügen / Entfernen eines einzelnen Boolesche Attribut ist - reveal="" -. Von den Knoten Sie wollen expandieren und kontrahieren

Hier ist alles, was Sie brauchen, wenn der Benutzer zu tun, sobald Sie den Code-Block umfassen unter dem Beispielcode gefunden:

/*** Nothing out of the ordinary in your styles ***/
<style>
    div {
        height: 0;
        overflow: hidden;
        transition: height 1s;
    }
</style>

/*** Just add and remove one attribute and transition to/from auto! ***/

<div>
    I have tons of content and I am 0px in height you can't see me...
</div>

<div reveal>
     I have tons of content and I am 0px in height you can't see me...
     but now that you added the 'reveal' attribute, 
     I magically transitioned to full height!...
</div>

Hier ist der Codeblock in Ihrer Seite zu schließen, danach, es ist alles Soße:

Drop diese JS-Datei auf Ihrer Seite - es funktioniert einfach ™

/ * Code für height: auto; transitioning * /

(function(doc){

/* feature detection for browsers that report different values for scrollHeight when an element's overflow is hidden vs visible (Firefox, IE) */
var test = doc.documentElement.appendChild(doc.createElement('x-reveal-test'));
    test.innerHTML = '-';
    test.style.cssText = 'display: block !important; height: 0px !important; padding: 0px !important; font-size: 0px !important; border-width: 0px !important; line-height: 1px !important; overflow: hidden !important;';
var scroll = test.scrollHeight || 2;
doc.documentElement.removeChild(test);

var loading = true,
    numReg = /^([0-9]*\.?[0-9]*)(.*)/,
    skipFrame = function(fn){
      requestAnimationFrame(function(){
        requestAnimationFrame(fn);
      });
    },
    /* 2 out of 3 uses of this function are purely to work around Chrome's catastrophically busted implementation of auto value CSS transitioning */
    revealFrame = function(el, state, height){
        el.setAttribute('reveal-transition', 'frame');
        el.style.height = height;
        skipFrame(function(){
            el.setAttribute('reveal-transition', state);
            el.style.height = '';
        });
    },
    transitionend = function(e){
      var node = e.target;
      if (node.hasAttribute('reveal')) {
        if (node.getAttribute('reveal-transition') == 'running') revealFrame(node, 'complete', '');
      } 
      else {
        node.removeAttribute('reveal-transition');
        node.style.height = '';
      }
    },
    animationstart = function(e){
      var node = e.target,
          name = e.animationName;   
      if (name == 'reveal' || name == 'unreveal') {

        if (loading) return revealFrame(node, 'complete', 'auto');

        var style = getComputedStyle(node),
            offset = (Number(style.paddingTop.match(numReg)[1])) +
                     (Number(style.paddingBottom.match(numReg)[1])) +
                     (Number(style.borderTopWidth.match(numReg)[1])) +
                     (Number(style.borderBottomWidth.match(numReg)[1]));

        if (name == 'reveal'){
          node.setAttribute('reveal-transition', 'running');
          node.style.height = node.scrollHeight - (offset / scroll) + 'px';
        }
        else {
            if (node.getAttribute('reveal-transition') == 'running') node.style.height = '';
            else revealFrame(node, 'running', node.scrollHeight - offset + 'px');
        }
      }
    };

doc.addEventListener('animationstart', animationstart, false);
doc.addEventListener('MSAnimationStart', animationstart, false);
doc.addEventListener('webkitAnimationStart', animationstart, false);
doc.addEventListener('transitionend', transitionend, false);
doc.addEventListener('MSTransitionEnd', transitionend, false);
doc.addEventListener('webkitTransitionEnd', transitionend, false);

/*
    Batshit readyState/DOMContentLoaded code to dance around Webkit/Chrome animation auto-run weirdness on initial page load.
    If they fixed their code, you could just check for if(doc.readyState != 'complete') in animationstart's if(loading) check
*/
if (document.readyState == 'complete') {
    skipFrame(function(){
        loading = false;
    });
}
else document.addEventListener('DOMContentLoaded', function(e){
    skipFrame(function(){
        loading = false;
    });
}, false);

/* Styles that allow for 'reveal' attribute triggers */
var styles = doc.createElement('style'),
    t = 'transition: none; ',
    au = 'animation: reveal 0.001s; ',
    ar = 'animation: unreveal 0.001s; ',
    clip = ' { from { opacity: 0; } to { opacity: 1; } }',
    r = 'keyframes reveal' + clip,
    u = 'keyframes unreveal' + clip;

styles.textContent = '[reveal] { -ms-'+ au + '-webkit-'+ au +'-moz-'+ au + au +'}' +
    '[reveal-transition="frame"] { -ms-' + t + '-webkit-' + t + '-moz-' + t + t + 'height: auto; }' +
    '[reveal-transition="complete"] { height: auto; }' +
    '[reveal-transition]:not([reveal]) { -webkit-'+ ar +'-moz-'+ ar + ar +'}' +
    '@-ms-' + r + '@-webkit-' + r + '@-moz-' + r + r +
    '@-ms-' + u +'@-webkit-' + u + '@-moz-' + u + u;

doc.querySelector('head').appendChild(styles);

})(document);

/ * Code für DEMO * /

    document.addEventListener('click', function(e){
      if (e.target.nodeName == 'BUTTON') {
        var next = e.target.nextElementSibling;
        next.hasAttribute('reveal') ? next.removeAttribute('reveal') : next.setAttribute('reveal', '');
      }
    }, false);

Jakes Antwort der maximale Höhe ist toll zu animieren, aber ich fand die Verzögerung durch einen großen max-height lästige Einstellung.

Man könnte den collapsable Inhalt in einen inneren div bewegen und die maximale Höhe berechnen, indem die Höhe des inneren div bekommen (über JQuery würde es die outerHeight sein ()).

$('button').bind('click', function(e) { 
  e.preventDefault();
  w = $('#outer');
  if (w.hasClass('collapsed')) {
    w.css({ "max-height": $('#inner').outerHeight() + 'px' });
  } else {
    w.css({ "max-height": "0px" });
  }
  w.toggleClass('collapsed');
});

Hier ist ein jsfiddle Link: http://jsfiddle.net/pbatey/duZpT

Hier ist ein jsfiddle mit dem absoluten Minimum an Code erforderlich: http://jsfiddle.net/8ncjjxh8/

Als Erweiterung @ Jakes Antwort, wird der Übergang der ganzen Weg bis zum Maximum Höhenwert gehen, eine extrem schnelle Animation verursachen - wenn Sie die Übergänge für beide gesetzt: Schwebe- und ausschalten Sie können dann die verrückte Geschwindigkeit ein bisschen mehr kontrollieren .

So das li. Hover ist, wenn die Maus, um den Zustand eintritt und dann der Übergang auf der nicht-hovered Eigenschaft wird die Maus verlassen sein

Dies wird hoffentlich eine Hilfe sein.

z:

.sidemenu li ul {
   max-height: 0px;
   -webkit-transition: all .3s ease;
   -moz-transition: all .3s ease;
   -o-transition: all .3s ease;
   -ms-transition: all .3s ease;
   transition: all .3s ease;
}
.sidemenu li:hover ul {
    max-height: 500px;
    -webkit-transition: all 1s ease;
   -moz-transition: all 1s ease;
   -o-transition: all 1s ease;
   -ms-transition: all 1s ease;
   transition: all 1s ease;
}
/* Adjust speeds to the possible height of the list */

Hier ist eine Geige: http://jsfiddle.net/BukwJ/

Ich weiß, das Gewinde wird alt, aber es steht hoch auf bestimmten Google-Suchanfragen, so ich meine, es lohnt aktualisiert werden.

Sie haben soeben auch erhalten / set das eigene Höhe des Elements:

var load_height = document.getElementById('target_box').clientHeight;
document.getElementById('target_box').style.height = load_height + 'px';

Sie sollten diese Javascript-Dump sofort nach target_box Schluss Tag in einem Inline-Skript-Tag.

Ich war in der Lage, dies zu tun. Ich habe einen .child & einen .parent div. Das Kind div paßt perfekt innerhalb der Eltern Breite / Höhe mit absolute Positionierung. Ich animieren dann die translate Eigenschaft auf seinen Y Wert nach unten 100% drücken. Die sehr glatte Animation, keine Pannen oder unten Seiten wie jede andere Lösung.

So etwas wie dies, Pseudo-Code

.parent{ position:relative; overflow:hidden; } 
/** shown state */
.child {
  position:absolute;top:0;:left:0;right:0;bottom:0;
  height: 100%;
  transition: transform @overlay-animation-duration ease-in-out;
  .translate(0, 0);
}

/** Animate to hidden by sliding down: */
.child.slidedown {
  .translate(0, 100%); /** Translate the element "out" the bottom of it's .scene container "mask" so its hidden */
}

Sie möchten gerne ein height auf .parent angeben, in px, % oder Urlaub, wie auto. Dieses div dann Masken aus dem .child div, wenn es nach unten gleitet.

Hier ist eine Lösung, die ich nur mit jQuery in Kombination verwendet. Dies funktioniert für die folgende HTML-Struktur:

<nav id="main-nav">
    <ul>
        <li>
            <a class="main-link" href="yourlink.html">Link</a>
            <ul>
                <li><a href="yourlink.html">Sub Link</a></li>
            </ul>
        </li>
    </ul>
</nav>

und die Funktion:

    $('#main-nav li ul').each(function(){
        $me = $(this);

        //Count the number of li elements in this UL
        var liCount = $me.find('li').size(),
        //Multiply the liCount by the height + the margin on each li
            ulHeight = liCount * 28;

        //Store height in the data-height attribute in the UL
        $me.attr("data-height", ulHeight);
    });

Sie könnten dann eine Klick-Funktion Satz verwenden und die Höhe mit css() entfernen

$('#main-nav li a.main-link').click(function(){
    //Collapse all submenus back to 0
    $('#main-nav li ul').removeAttr('style');

    $(this).parent().addClass('current');

    //Set height on current submenu to it's height
    var $currentUl = $('li.current ul'),
        currentUlHeight = $currentUl.attr('data-height');
})

CSS:

#main-nav li ul { 
    height: 0;
    position: relative;
    overflow: hidden;
    opacity: 0; 
    filter: alpha(opacity=0); 
    -ms-filter: "alpha(opacity=0)";
    -khtml-opacity: 0; 
    -moz-opacity: 0;
    -webkit-transition: all .6s ease-in-out;
    -moz-transition: all .6s ease-in-out;
    -o-transition: all .6s ease-in-out;
    -ms-transition: all .6s ease-in-out;
    transition: all .6s ease-in-out;
}

#main-nav li.current ul {
    opacity: 1.0; 
    filter: alpha(opacity=100); 
    -ms-filter: "alpha(opacity=100)";
    -khtml-opacity: 1.0; 
    -moz-opacity: 1.0;
}

.ie #main-nav li.current ul { height: auto !important }

#main-nav li { height: 25px; display: block; margin-bottom: 3px }

Ich habe vor kurzem die max-height auf den li Elemente wurden Übergang statt der Verpackung ul.

Die Begründung ist, dass die Verzögerung für kleine max-heights weit weniger auffällig ist (wenn überhaupt) zu großen max-heights verglichen, und ich kann meinen max-height Wert relativ auf die font-size der li anstatt einer beliebige große Zahl auch durch ems mit oder rems.

Wenn meine Schriftgröße 1rem ist, ich meine max-height so etwas wie 3rem gesetzt werden (Wrapped Text aufzunehmen). Sie können ein Beispiel sehen Sie hier:

http://codepen.io/mindfullsilence/pen/DtzjE

Ich habe nicht alles im Detail lesen, aber ich habe dieses Problem vor kurzem habe und ich tat, was folgt:

div.class{
   min-height:1%;
   max-height:200px;
   -webkit-transition: all 0.5s ease;
   -moz-transition: all 0.5s ease;
   -o-transition: all 0.5s ease;
   -webkit-transition: all 0.5s ease;
   transition: all 0.5s ease;
   overflow:hidden;
}

div.class:hover{
   min-height:100%;
   max-height:3000px;
}

Damit können Sie ein div haben, dass seine Größe mindestens so hoch wie der gesamte Inhalt des div auf den ersten Shows Inhalt bis zu 200 Pixel Höhe und auf schweben wird. Die Div hat sich nicht 3000px aber 3000px die Grenze ist, dass ich aufzuzwingen. Achten Sie darauf, den Übergang auf den nicht haben: schweben, sonst könnte man einige seltsame Rendering erhalten. Auf diese Art und Weise die: hover erbt von dem nicht: schweben.

ist Transition nicht Form Pixel% oder Auto arbeiten. Sie müssen gleiche Maßeinheit verwenden. Dies funktioniert gut für mich. HTML5 macht es perfekt ....

Denken Sie daran, dass es immer eine Arbeit um ...; )

Hope jemand findet dies nützlich

Dies ist nicht gerade eine „Lösung“ für das Problem, sondern eher ein Problem zu umgehen. Es funktioniert nur, wie mit Text geschrieben, kann aber mit anderen Elementen nach Bedarf Ich bin sicher, an der Arbeit geändert werden.

.originalContent {
    font-size:0px;
    transition:font-size .2s ease-in-out;
}
.show { /* class to add to content */
    font-size:14px;
}

Hier ist ein Beispiel: http://codepen.io/overthemike/pen/wzjRKa

Im Wesentlichen setzen Sie die Schriftgröße auf 0 und Übergang, der anstelle der Höhe oder max-height oder scaleY () usw. in einem schnell genug Tempo die Höhe zu verwandeln zu bekommen, was Sie wollen. die tatsächliche Höhe mit CSS Auto zu verwandeln ist nicht möglich, aber die Umwandlung der Inhalte innerhalb ist, daher der font-size Übergang.

  • Hinweis - Es gibt Javascript in codepen, aber es ist nur Zweck ist für das Akkordeon zum Hinzufügen / Entfernen CSS-Klassen auf Klick. Dies kann mit versteckten Radiobuttons erfolgen, aber ich war nicht darauf konzentriert, nur die Höhe Transformation.

Ich verstehe die Frage nach einer Lösung ohne JavaScript fragt. Aber für diejenigen, interessiert hier ist meine Lösung nur ein wenig von JS verwendet wird.

ok, also die CSS des Elements, dessen Höhe standardmäßig ändern wird auf height: 0; und wenn sie geöffnet height: auto;. Es hat auch transition: height .25s ease-out;. Aber natürlich ist das Problem, dass es nicht Übergang zu oder von height: auto;

Also, was ich getan habe, ist beim Öffnen oder die Höhe der scrollHeight Eigenschaft des Elements gesetzt zu schließen. Diese neue Inline-Stil wird eine höhere Spezifität haben und sowohl height: auto; und height: 0; und die Übergangsläufe außer Kraft setzen.

Beim Öffnen i fügt Sie einen transitionend Ereignis-Listener, die nur einmal ausgeführt werden dann den Inline-Stil entfernen Sie es zurück zu height: auto; Einstellung, die das Element erforderlich, um die Größe ermöglicht es, wenn, wie in diesem komplexeres Beispiel mit Untermenü https://codepen.io/ninjabonsai/pen/GzYyVe

Beim Schließen i den Inline-Stil entfernen direkt nach der nächsten Ereignisschleife Zyklus ohne Verzögerung mit setTimeout. Diese Mittel height: auto; vorübergehend außer Kraft gesetzt, die den Übergang zurück zum height 0;

erlaubt

const showHideElement = (element, open) => {
  element.style.height = element.scrollHeight + 'px';
  element.classList.toggle('open', open);

  if (open) {
    element.addEventListener('transitionend', () => {
      element.style.removeProperty('height');
    }, {
      once: true
    });
  } else {
    window.setTimeout(() => {
      element.style.removeProperty('height');
    });
  }
}

const menu = document.body.querySelector('#menu');
const list = document.body.querySelector('#menu > ul')

menu.addEventListener('mouseenter', () => showHideElement(list, true));
menu.addEventListener('mouseleave', () => showHideElement(list, false));
#menu>ul {
  height: 0;
  overflow: hidden;
  background-color: #999;
  transition: height .25s ease-out;
}

#menu>ul.open {
  height: auto;
}
<div id="menu">
  <a>hover me</a>
  <ul>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <li>item</li>
  </ul>
</div>

Die max-height Lösung von Jake funktioniert gut, wenn die hartcodiert max-height Wert zugeführt wird, nicht viel größer als die reale Höhe (Weil sonst gibt es unerwünschte Verzögerungen und Timing-Probleme). Auf der anderen Seite, wenn der hartcodierte Wert accidentially ist nicht größer sein als die tatsächliche Höhe wird nicht das Element vollständig öffnen.

Die folgende CSS einzige Lösung erfordert auch eine hartcodierte Größe, dass größer sein sollte als die meisten der auftretenden realen Größen. Doch diese Lösung funktioniert auch, wenn die tatsächliche Größe in einigen Situationen ist größer als die hart codierte Größe. In diesem Fall könnte der Übergang ein wenig springen, aber es wird nie ein teilweise sichtbares Element verlassen. So dass diese Lösung auch für unbekannte Inhalte verwendet werden könnte, zum Beispiel von eine Datenbank, in der Sie nur wissen, dass der Inhalt ist in der Regel nicht größer als x Pixel, aber es gibt Ausnahmen.

Idee ist, einen negativen Wert für margin-Boden zu verwenden (oder margin-Spitze für einen leicht diffenrent Animation) und den Inhalt Element in eine platzieren mittleres Element mit Überlauf: versteckt. Die negative Marge des Inhalts Element reduziert so die Höhe des mittleren Elements.

Der folgende Code verwendet einen Übergang auf margin-Boden aus zu -150px 0px. Dies allein funktioniert gut, solange das Inhaltselement ist nicht höher als 150px. Außerdem verwendet es einen Übergang auf max-Höhe für die mittleres Element von 0px bis 100%. Das blendet schließlich das mittlere Element Wenn der Gehalt höher ist als Element 150 Pixel. Für Max-Höhe wird der Übergang nur verwendet, um seine Anwendung zu verzögern durch eine zweite beim Schließen, nicht die für eine reibungslose visiual Wirkung ( und daher kann es von 0px auf 100% aufgestockt werden).

CSS:

.content {
  transition: margin-bottom 1s ease-in;
  margin-bottom: -150px;
}
.outer:hover .middle .content {
  transition: margin-bottom 1s ease-out;
  margin-bottom: 0px
}
.middle {
  overflow: hidden;
  transition: max-height .1s ease 1s;
  max-height: 0px
}
.outer:hover .middle {
  transition: max-height .1s ease 0s;
  max-height: 100%
}

HTML:

<div class="outer">
  <div class="middle">
    <div class="content">
      Sample Text
      <br> Sample Text
      <br> Sample Text
      <div style="height:150px">Sample Test of height 150px</div>
      Sample Text
    </div>
  </div>
  Hover Here
</div>

Der Wert für Rand unten sollte negativ und so nah wie möglich, auf die reale Höhe des Inhaltselements. Wenn es ( 's absoute Wert) größer sind ähnliche Verzögerung und Timing-Probleme wie bei Max-Höhe-Lösungen, die jedoch so lange der begrenzt werden kann, hart codierte Größe ist nicht viel größer als die reale. Wenn der absolute Wert für margin-Boden kleiner ist als die tatsächliche Höhe des tansition springt ein wenig. Auf jedem Fall nach dem Übergang des Content-Element wird entweder vollständig angezeigt oder vollständig entfernt werden.

Weitere Informationen finden Sie in meinem Blog-Post http://www.taccgl.org/blog /css_transition_display.html#combined_height

Es scheint keine angemessene Lösung zu sein. max-height Ansatz ist recht gut, funktioniert aber nicht gut für die Haut Phase - wird es eine merkliche Verzögerung sein, wenn Sie die Höhe des Inhalts kennen.

Ich denke, der beste Weg, max-height zu verwenden ist, aber nur für die Show Phase . Und nicht jede Animation auf Versteck zu verwenden. In den meisten Fällen sollte es nicht entscheidend sein.

max-height sollte auf einen ziemlich großen Wert festgelegt werden, um alle Inhalte passen zu gewährleisten. Animationsgeschwindigkeit kann mit transition Dauer (speed = max-height / duration) gesteuert werden. Geschwindigkeit hängt nicht von der Größe des Inhalts. Die Zeit, die den gesamten Inhalt zu zeigen, wird von seiner Größe ab.

document.querySelector("button").addEventListener(
  "click", 
  function(){
    document.querySelector("div").classList.toggle("hide");
  }
)
div {    
    max-height: 20000px;
    transition: max-height 3000ms;
    overflow-y: hidden;
}

.hide {
    max-height: 0;
    transition: none;
}
<button>Toggle</button>
<div class="hide">Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. 
</div>

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top