Pertanyaan Bagaimana saya bisa melakukan transisi ketinggian: 0; ke tinggi: otomatis; menggunakan CSS?


Saya mencoba membuat <ul> geser ke bawah menggunakan transisi CSS.

Itu <ul> dimulai pada height: 0;. Saat melayang, ketinggian diatur ke height:auto;. Namun, ini menyebabkannya muncul begitu saja, tidak transisi,

Jika saya melakukannya height: 40px; untuk height: auto;, maka akan meluncur ke atas height: 0;, dan kemudian tiba-tiba melompat ke ketinggian yang tepat.

Bagaimana lagi saya bisa melakukan ini tanpa menggunakan 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>


1594
2017-08-18 02:50


asal


Jawaban:


Menggunakan max-height dalam transformasi dan tidak height. Dan tetapkan nilainya max-height ke sesuatu yang lebih besar dari kotak Anda.

Lihat Demo JSFiddle disediakan oleh Chris Jordan di negara lain menjawab sini.

#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



Anda harus menggunakan scaleY sebagai gantinya.

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);
}

Saya telah membuat vendor versi awalan kode di atas pada jsfiddle, http://jsfiddle.net/dotnetCarpenter/PhyQc/9/ dan ubah jsfiddle Anda untuk menggunakan scaleY bukan tinggi, http://jsfiddle.net/dotnetCarpenter/7cnfc/206/.


228
2018-06-23 10:57



Anda saat ini tidak dapat bergerak pada ketinggian ketika salah satu ketinggian terlibat auto, Anda harus menetapkan dua ketinggian eksplisit.


164
2017-08-18 12:46



Solusi yang selalu saya gunakan adalah memudar terlebih dahulu, lalu mengecilkan font-size, padding dan margin nilai-nilai. Itu tidak terlihat sama dengan lap, tetapi bekerja tanpa statis height atau 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;
}

Contoh kerja:

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



Anda bisa, dengan sedikit jiggery-pokery non-semantis. Pendekatan yang biasa saya lakukan adalah menganimasikan tinggi DIV luar yang memiliki anak tunggal yang merupakan DIV tanpa gaya yang hanya digunakan untuk mengukur tinggi konten.

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>

Satu ingin hanya bisa membuang .measuringWrapper dan setel tinggi DIV ke otomatis dan buat animasi, tetapi itu tidak berfungsi (tinggi diatur, tetapi tidak ada animasi).

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>

Interpretasi saya adalah bahwa tinggi eksplisit diperlukan agar animasi dapat berjalan. Anda tidak bisa mendapatkan animasi pada ketinggian ketika tinggi (tinggi awal atau akhir) auto.


64
2018-06-30 13:32



Saya tahu ini adalah jawaban ketiga puluh untuk pertanyaan ini, tapi saya pikir itu sepadan, jadi begini. Ini adalah sebuah Hanya-CSS solusi dengan properti berikut:

  • Tidak ada penundaan di awal, dan transisi tidak berhenti lebih awal. Di kedua arah (meluas dan runtuh), jika Anda menetapkan durasi transisi 300ms dalam CSS Anda, transisi membutuhkan waktu 300ms, titik.
  • Ini transisi ketinggian sebenarnya (tidak seperti transform: scaleY(0)), jadi itu melakukan hal yang benar jika ada konten setelah elemen yang dapat diciutkan.
  • Sementara (seperti di solusi lain) di sana adalah angka ajaib (seperti "pilih panjang yang lebih tinggi dari kotak Anda"), itu tidak fatal jika asumsi Anda berakhir dengan salah. Transisi mungkin tidak terlihat luar biasa dalam kasus itu, tetapi sebelum dan sesudah transisi, ini bukan masalah: Dalam perluasan (height: auto) sebutkan, seluruh konten selalu memiliki tinggi yang tepat (tidak seperti misalnya jika Anda memilih a max-heightyang ternyata terlalu rendah). Dan dalam keadaan runtuh, tingginya nol seperti seharusnya.

Demo

Berikut adalah demo dengan tiga elemen yang dapat diciutkan, semua ketinggian yang berbeda, yang semuanya menggunakan CSS yang sama. Anda mungkin ingin mengklik "halaman penuh" setelah mengklik "run snippet". Perhatikan bahwa JavaScript hanya mengaktifkan collapsed Kelas CSS, tidak ada pengukuran yang terlibat. (Anda dapat melakukan demo ini tanpa JavaScript sama sekali dengan menggunakan kotak centang atau :target). Perhatikan juga bahwa bagian dari CSS yang bertanggung jawab untuk transisi cukup singkat, dan HTML hanya membutuhkan satu elemen pembungkus tambahan.

$(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>

Bagaimana cara kerjanya?

Sebenarnya ada dua transisi yang terlibat dalam pembuatan ini terjadi. Salah satunya transisi margin-bottom dari 0px (dalam keadaan diperluas) ke -2000px dalam keadaan diciutkan (mirip dengan jawaban ini). 2000 di sini adalah angka ajaib pertama, ini didasarkan pada asumsi bahwa kotak Anda tidak akan lebih tinggi dari ini (2000 piksel sepertinya pilihan yang masuk akal).

Menggunakan margin-bottom transisi sendirian dengan sendirinya memiliki dua masalah:

  • Jika Anda benar-benar memiliki kotak yang lebih tinggi dari 2000 piksel, maka a margin-bottom: -2000px tidak akan menyembunyikan segalanya - akan ada hal-hal yang terlihat bahkan dalam kasus yang diciutkan. Ini adalah perbaikan kecil yang akan kami lakukan nanti.
  • Jika kotak yang sebenarnya, katakanlah, 1000 piksel tinggi, dan transisi Anda adalah 300ms, maka terlihat transisi sudah berakhir setelah sekitar 150ms (atau, dalam arah yang berlawanan, mulai 150ms terlambat).

Memperbaiki masalah kedua ini adalah di mana transisi kedua terjadi, dan transisi ini secara konseptual menargetkan pembungkus minimum tinggi ("secara konseptual" karena kita sebenarnya tidak menggunakan min-height properti untuk ini; lebih lanjut tentang itu nanti).

Berikut adalah animasi yang menunjukkan bagaimana menggabungkan transisi margin bawah dengan transisi tinggi minimum, keduanya dengan durasi yang sama, memberi kita transisi gabungan dari ketinggian penuh ke nol tinggi yang memiliki durasi yang sama.

animation as described above

Bilah kiri menunjukkan bagaimana margin bawah negatif mendorong bagian bawah ke atas, mengurangi tinggi yang terlihat. Bilah tengah menunjukkan bagaimana tinggi minimum memastikan bahwa dalam kasus yang runtuh, transisi tidak berakhir lebih awal, dan dalam kasus yang meluas, transisi tidak akan terlambat. Bilah kanan menunjukkan bagaimana kombinasi keduanya menyebabkan kotak bertransisi dari ketinggian penuh ke nol tinggi dalam jumlah waktu yang tepat.

Untuk demo saya, saya telah menetapkan 50px sebagai nilai tinggi minimum atas. Ini adalah angka ajaib kedua, dan seharusnya lebih rendah dari tinggi kotak yang ada. 50px tampaknya masuk akal juga; tampaknya tidak mungkin Anda akan sangat sering ingin membuat elemen dilipat yang bahkan tidak sampai 50 piksel di tempat pertama.

Seperti yang Anda lihat dalam animasi, transisi yang dihasilkan bersifat kontinu, tetapi tidak terdiferensiasi - pada saat ketika ketinggian minimum sama dengan tinggi penuh yang disesuaikan dengan margin bawah, ada perubahan kecepatan yang tiba-tiba. Ini sangat terlihat dalam animasi karena menggunakan fungsi waktu linear untuk kedua transisi, dan karena seluruh transisi sangat lambat. Dalam kasus aktual (demo saya di atas), transisi hanya membutuhkan waktu 300ms, dan transisi margin bawah tidak linear. Saya telah bermain-main dengan banyak fungsi waktu yang berbeda untuk kedua transisi, dan yang saya akhirnya merasa seperti mereka bekerja paling baik untuk berbagai macam kasus.

Dua masalah tetap diperbaiki:

  1. titik dari atas, di mana kotak dengan tinggi lebih dari 2000 piksel tidak sepenuhnya tersembunyi dalam keadaan diciutkan,
  2. dan masalah sebaliknya, di mana dalam kasus yang tidak tersembunyi, kotak dengan tinggi kurang dari 50 piksel terlalu tinggi bahkan ketika transisi tidak berjalan, karena ketinggian minimum membuatnya tetap pada 50 piksel.

Kami memecahkan masalah pertama dengan memberikan elemen kontainer a max-height: 0 dalam kasus yang diciutkan, dengan a 0s 0.3s transisi. Ini berarti bahwa ini bukan benar-benar transisi, tetapi max-height diterapkan dengan penundaan; ini hanya berlaku setelah transisi selesai. Agar ini berfungsi dengan benar, kita juga perlu memilih angka max-height untuk kebalikannya, negara yang tidak runtuh. Tapi tidak seperti dalam kasus 2000px, di mana memilih terlalu banyak nomor mempengaruhi kualitas transisi, dalam hal ini, itu tidak masalah. Jadi kita bisa memilih angka yang sangat tinggi sehingga kita tahu bahwa tidak ada ketinggian yang akan mendekati ini. Saya memilih satu juta piksel. Jika Anda merasa Anda mungkin perlu mendukung konten dengan tinggi lebih dari satu juta piksel, maka 1) Saya minta maaf, dan 2) tambahkan saja beberapa angka nol.

Masalah kedua adalah alasan mengapa kami tidak benar-benar menggunakannya min-height untuk transisi ketinggian minimum. Sebaliknya, ada sebuah ::after pseudo-element dalam penampung dengan height transisi dari 50px ke nol. Ini memiliki efek yang sama dengan min-height: Ini tidak akan membiarkan wadah menyusut di bawah ketinggian apa pun yang saat ini dimiliki oleh elemen pseudo. Tetapi karena kami menggunakan heighttidak min-height, sekarang bisa kita gunakan max-height (sekali lagi diterapkan dengan penundaan) untuk mengatur tinggi aktual pseudo-element menjadi nol setelah transisi berakhir, memastikan bahwa setidaknya di luar transisi, bahkan elemen-elemen kecil memiliki ketinggian yang tepat. Karena min-height aku s lebih kuat dari max-height, ini tidak akan berhasil jika kita menggunakan wadahnya min-height bukannya elemen pseudo height. Sama seperti max-height di paragraf sebelumnya, ini max-height juga membutuhkan nilai untuk ujung transisi. Namun dalam hal ini kita bisa memilih 50px.

Diuji di Chrome (Win, Mac, Android, iOS), Firefox (Win, Mac, Android), Edge, IE11 (kecuali untuk masalah layout flexbox dengan demo saya yang tidak mengganggu debugging), dan Safari (Mac, iOS ). Berbicara tentang flexbox, seharusnya memungkinkan untuk membuat ini bekerja tanpa menggunakan flexbox apa pun; sebenarnya saya pikir Anda bisa membuat hampir semuanya bekerja di IE7 - kecuali kenyataan bahwa Anda tidak akan memiliki transisi CSS, menjadikannya sebagai latihan yang tidak berguna.


45
2018-05-14 14:33



Sebuah solusi visual untuk menganimasi tinggi menggunakan transisi CSS3 adalah menganimasikan padding sebagai gantinya.

Anda tidak cukup mendapatkan efek penghapusan penuh, tetapi bermain-main dengan durasi transisi dan nilai-nilai padding harus membuat Anda cukup dekat. Jika Anda tidak ingin menetapkan tinggi / tinggi maksimal secara eksplisit, ini harus menjadi apa yang Anda cari.

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 jsFiddle js stephband ini)


44
2018-06-26 19:05



Solusi saya adalah untuk transisi max-height ke ketinggian konten yang tepat untuk animasi halus yang bagus, kemudian gunakan callback transisiEnd untuk mengatur max-height ke 9999px sehingga konten dapat mengubah ukuran dengan bebas.

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



Jawaban diterima bekerja untuk sebagian besar kasus, tetapi tidak berfungsi dengan baik ketika Anda div dapat sangat bervariasi - kecepatan animasi tidak bergantung pada tinggi konten sebenarnya, dan dapat terlihat berombak.

Anda masih dapat melakukan animasi sebenarnya dengan CSS, tetapi Anda perlu menggunakan JavaScript untuk menghitung tinggi item, daripada mencoba menggunakan auto. Tidak diperlukan jQuery, meskipun Anda mungkin harus memodifikasi ini sedikit jika Anda menginginkan kompatibilitas (berfungsi di versi terbaru 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