Frage Wie kann ich Höhe übergehen: 0; zu Höhe: auto; Verwenden von CSS?


Ich versuche es zu machen <ul> rutschen Sie mit CSS-Übergängen nach unten.

Das <ul> beginnt um height: 0;. Bei Hover ist die Höhe auf eingestellt height:auto;. Dies führt jedoch dazu, dass es einfach erscheint, nicht Übergang,

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

Wie könnte ich das sonst ohne JavaScript machen?

#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>


1594
2017-08-18 02:50


Ursprung


Antworten:


Benutzen max-height in der Transformation und nicht height. Und setze einen Wert auf max-height zu etwas Größerem als deine Box jemals bekommen wird.

Sehen JSFiddle-Demo von Chris Jordan in einem anderen bereitgestellt Antworten 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>


2157
2017-11-30 18:42



Sie sollten stattdessen scaleY verwenden.

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 eine Hersteller-Version des obigen Codes auf jsfiddle gemacht, http://jsfiddle.net/dotnetCarpenter/PhyQc/9/ und änderte deine jsfiddle, um scaleY anstelle von Höhe zu verwenden, http://jsfiddle.net/dotnetCarpenter/7cnfc/206/.


228
2018-06-23 10:57



Sie können derzeit nicht auf Höhe animieren, wenn eine der Höhen betroffen ist auto, müssen Sie zwei explizite Höhen setzen.


164
2017-08-18 12:46



Die Lösung, die ich immer benutzt habe, war zuerst auszublenden und dann zu verkleinern font-size, padding und margin Werte. Es sieht nicht wie ein Wipe aus, aber es funktioniert ohne eine statische height oder max-height.

/* 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;
}

Arbeitsbeispiel:

/* 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>

Spacing.


81
2018-05-29 14:05



Sie können, mit ein bisschen nicht-semantischer Jiggery-pokery. Mein üblicher Ansatz besteht darin, die Höhe eines äußeren DIV zu animieren, der ein einzelnes Kind hat, welches ein stilloses DIV ist, das nur zum Messen 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 möchte nur auf das verzichten können .measuringWrapper und setze einfach die Höhe des DIV auf automatisch und animiere das, aber das scheint nicht zu funktionieren (die Höhe wird eingestellt, aber es findet keine Animation statt).

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, damit die Animation läuft. Sie können keine Animation für die Höhe erhalten, wenn die Höhe (Anfangs- oder Endhöhe) angegeben ist auto.


64
2018-06-30 13:32



Ich weiß, das ist die dreißigste Antwort auf diese Frage, aber ich denke, es ist es wert, also hier. Das ist ein Nur CSS Lösung mit folgenden Eigenschaften:

  • Es gibt keine Verzögerung am Anfang, und der Übergang hört nicht früh auf. Wenn Sie in Ihrem CSS eine Übergangsdauer von 300 ms angeben, dauert der Übergang in beiden Richtungen (Expandieren und Minimieren) 300 ms.
  • Es verändert die tatsächliche Höhe (im Gegensatz zu transform: scaleY(0)), so tut es das Richtige, wenn nach dem kollabierbaren Element Inhalt vorhanden ist.
  • Während (wie in anderen Lösungen) gibt es sind magische Zahlen (wie "wähle eine Länge, die höher ist als deine Box jemals sein wird"), ist es nicht fatal, wenn deine Annahme falsch ist. Der Übergang sieht in diesem Fall vielleicht nicht toll aus, aber vor und nach dem Übergang ist das kein Problem: Im erweiterten (height: auto) state, der gesamte Inhalt hat immer die richtige Höhe (anders als z. B. wenn Sie eine auswählen max-heightdas erweist sich als zu niedrig). Und im zusammengeklappten Zustand ist die Höhe gleich Null.

Demo

Hier ist eine Demo mit drei zusammenklappbaren Elementen, alle in verschiedenen Höhen, die alle das gleiche CSS verwenden. Sie können nach dem Klicken auf "run snippet" auf "Ganze Seite" klicken. Beachten Sie, dass das JavaScript nur die Option wechselt collapsed CSS-Klasse, es gibt keine Messung beteiligt. (Sie könnten diese exakte Demo ohne JavaScript ausführen, indem Sie ein Kontrollkästchen verwenden oder :target). Beachten Sie auch, dass der Teil des CSS, der für den Übergang verantwortlich ist, ziemlich kurz ist und der HTML-Code nur ein zusätzliches Wrapper-Element benötigt.

$(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 gibt tatsächlich zwei Übergänge, die dazu beitragen, dass dies geschieht. Einer von ihnen übergeht die margin-bottom von 0px (im expandierten Zustand) nach -2000px im kollabierten Zustand (ähnlich wie diese Antwort). Das 2000 hier ist die erste magische Zahl, es basiert auf der Annahme, dass Ihre Box nicht höher sein wird (2000 Pixel scheint eine vernünftige Wahl zu sein).

Verwendung der margin-bottom Übergang allein hat zwei Probleme:

  • Wenn Sie eine Box haben, die höher als 2000 Pixel ist, dann a margin-bottom: -2000px wird nicht alles verstecken - es wird sichtbares Zeug geben, sogar im zusammengebrochenen Fall. Dies ist eine kleine Korrektur, die wir später machen werden.
  • Wenn die tatsächliche Box beispielsweise 1000 Pixel hoch ist und Ihr Übergang 300 ms lang ist, dann wird die sichtbar Der Übergang ist nach ca. 150ms bereits beendet (oder in umgekehrter Richtung 150ms später).

Das zweite Problem wird behoben, wenn der zweite Übergang eintritt und dieser Übergang konzeptionell auf die Wrapper abzielt Minimum Höhe ("konzeptuell", weil wir nicht die min-height Eigentum dafür; mehr dazu später).

Hier ist eine Animation, die zeigt, wie die Kombination des Überganges am unteren Rand mit dem Übergang mit minimaler Höhe, die beide gleich lang sind, einen kombinierten Übergang von voller Höhe zu Höhe null mit der gleichen Dauer ergibt.

animation as described above

Der linke Balken zeigt, wie der negative untere Rand den Boden nach oben drückt, wodurch die sichtbare Höhe reduziert wird. Der mittlere Balken zeigt, wie die minimale Höhe sicherstellt, dass der Übergang im zusammenbrechenden Fall nicht früh endet und im expandierenden Fall der Übergang nicht zu spät beginnt. Der rechte Balken zeigt, wie die Kombination der beiden bewirkt, dass die Box in der richtigen Zeit von der vollen Höhe auf die Höhe Null übergeht.

Für meine Demo habe ich 50px als oberen Mindestwert festgelegt. Dies ist die zweite magische Zahl, und sie sollte niedriger sein als die Höhe der Box. 50px scheint auch vernünftig; Es ist unwahrscheinlich, dass Sie sehr oft ein Element zusammenklappen möchten, das nicht einmal 50 Pixel hoch ist.

Wie Sie in der Animation sehen können, ist der resultierende Übergang kontinuierlich, aber nicht differenzierbar - in dem Moment, in dem die minimale Höhe der vollen Höhe entspricht, die durch den unteren Rand eingestellt wird, kommt es zu einer plötzlichen Änderung der Geschwindigkeit. Dies ist in der Animation sehr auffällig, da für beide Übergänge eine lineare Timing-Funktion verwendet wird und der gesamte Übergang sehr langsam ist. Im tatsächlichen Fall (meine Demo oben) dauert der Übergang nur 300 ms und der Übergang zum unteren Rand ist nicht linear. Ich habe mit vielen verschiedenen Timing-Funktionen für beide Übergänge herumgespielt und die, mit denen ich am Ende war, fühlten sich an, als ob sie für die verschiedensten Fälle am besten funktionierten.

Zwei Probleme bleiben zu beheben:

  1. der Punkt von oben, wo Boxen mit mehr als 2000 Pixel Höhe im zusammengelegten Zustand nicht vollständig versteckt sind,
  2. und das umgekehrte Problem, wo im nicht verborgenen Fall Boxen mit einer Höhe von weniger als 50 Pixeln zu hoch sind, selbst wenn der Übergang nicht läuft, weil die minimale Höhe sie bei 50 Pixeln hält.

Wir lösen das erste Problem, indem wir dem Containerelement a max-height: 0 im zusammengebrochenen Fall mit a 0s 0.3s Übergang. Dies bedeutet, dass es nicht wirklich ein Übergang ist, sondern der max-height wird mit einer Verzögerung angewendet; Es gilt nur, wenn der Übergang beendet ist. Damit dies richtig funktioniert, müssen wir auch eine Zahl auswählen max-height für das Gegenteil, nicht kollabiert, Staat. Aber anders als im 2000px-Fall, bei dem die Wahl einer zu großen Zahl die Qualität des Übergangs beeinflusst, spielt es in diesem Fall keine Rolle. Wir können also eine Zahl auswählen, die so hoch ist, dass wir kennt dass keine Höhe jemals näher kommt. Ich habe eine Million Pixel ausgewählt. Wenn Sie der Meinung sind, dass Sie Inhalte mit einer Höhe von mehr als einer Million Pixel unterstützen müssen, dann 1) tut mir leid, und 2) fügen Sie einfach ein paar Nullen hinzu.

Das zweite Problem ist der Grund, warum wir nicht wirklich verwenden min-height für den minimalen Höhenübergang. Stattdessen gibt es ein ::after Pseudo-Element im Container mit a height das geht von 50px auf null über. Dies hat die gleiche Wirkung wie a min-height: Der Container wird nicht kleiner als die Höhe des Pseudoelements. Aber weil wir es benutzen heightnicht min-heightkönnen wir jetzt verwenden max-height (erneut mit einer Verzögerung angewendet), um die tatsächliche Höhe des Pseudoelements auf Null zu setzen, sobald der Übergang vorbei ist, um sicherzustellen, dass zumindest kleine Elemente außerhalb des Übergangs die richtige Höhe haben. weil min-height ist stärker als max-height, das würde nicht funktionieren, wenn wir den Container benutzen würden min-height anstelle der Pseudo-Elemente height. Genau wie die max-height im vorherigen Absatz, dies max-height benötigt auch einen Wert für das andere Ende des Übergangs. Aber in diesem Fall können wir nur die 50px auswählen.

Getestet in Chrome (Win, Mac, Android, iOS), Firefox (Win, Mac, Android), Edge, IE11 (abgesehen von einem Flexbox-Layout-Problem mit meiner Demo, die ich nicht störte) und Safari (Mac, iOS ). Apropos Flexbox: Es sollte möglich sein, das ohne Flexbox zu machen; in der Tat denke ich, dass Sie fast alles in IE7 arbeiten können - abgesehen von der Tatsache, dass Sie keine CSS-Übergänge haben werden, was es zu einer sinnlosen Übung macht.


45
2018-05-14 14:33



Eine visuelle Problemumgehung zum Animieren der Höhe mithilfe von CSS3-Übergängen besteht darin, das Padding stattdessen zu animieren.

Du bekommst nicht den vollständigen Wischeffekt, aber wenn du mit den Werten für die Übergangsdauer und den Abstand herumspielst, solltest du nahe genug dran sein. Wenn Sie die Höhe / Max-Höhe nicht explizit festlegen möchten, sollte dies das sein, wonach Sie suchen.

div {
    height: 0;
    overflow: hidden;
    padding: 0 18px;
    -webkit-transition: all .5s ease;
       -moz-transition: all .5s ease;
            transition: all .5s ease;
}
div.animated {
    height: auto;
    padding: 24px 18px;
}

http://jsfiddle.net/catharsis/n5XfG/17/ (riffed off stepband's oben jsFiddle)


44
2018-06-26 19:05



Meine Problemumgehung besteht darin, die maximale Höhe für eine schöne glatte Animation auf die exakte Höhe des Inhalts zu stellen und dann mit einem transitionEnd-Callback die maximale Höhe auf 9999 px einzustellen, damit der Inhalt frei skaliert werden 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>


43
2018-03-19 00:44



Die angenommene Antwort funktioniert in den meisten Fällen, aber es funktioniert nicht gut, wenn Sie div kann in der Höhe stark variieren - die Animationsgeschwindigkeit hängt nicht von der tatsächlichen Höhe des Inhalts ab, und es kann abgehackt aussehen.

Sie können die eigentliche Animation immer noch mit CSS ausführen, aber Sie müssen JavaScript verwenden, um die Höhe der Elemente zu berechnen, anstatt zu versuchen, sie zu verwenden auto. Kein jQuery ist erforderlich, obwohl Sie dies möglicherweise ein wenig ändern müssen, wenn Sie Kompatibilität wünschen (funktioniert in der neuesten Version von Chrome :)).

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>


31
2017-10-20 22:57



Benutzen max-height mit verschiedenen Übergangsbeschleunigung 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/


23
2017-12-16 23:35



Keine fest codierten Werte.

Kein JavaScript.

Keine Näherungen.

Der Trick besteht darin, eine versteckte und duplizierte zu verwenden div um den Browser zu verstehen, was 100% bedeutet.

Diese Methode ist immer dann geeignet, wenn Sie das DOM des Elements, das Sie animieren möchten, duplizieren können.

.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>


21
2018-02-26 17:19