Saya mencoba untuk membuat <ul>
geser ke bawah menggunakan CSS transisi.
The <ul>
dimulai pada height: 0;
. Di hover, tinggi diatur ke height:auto;
. Namun, hal ini menyebabkan ia hanya muncul, tidak transisi,
Jika saya melakukannya dari height: 40px;
untuk height: auto;
, maka itu akan meluncur hingga height: 0;
, dan kemudian tiba-tiba melompat ke ketinggian yang benar.
Bagaimana lagi aku 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>
Gunakan max-height
dalam transisi dan tidak tinggi
. Dan menetapkan nilai max-height
untuk sesuatu yang lebih besar dari kotak anda akan pernah mendapatkan.
Lihat [demo JSFiddle](
) yang disediakan oleh Chris Jordan di lain jawaban berikut ini.#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>
Anda harus menggunakan scaleY sebaliknya.
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);
}
I've membuat vendor diawali versi dari kode di atas di jsfiddle,
dan berubah anda jsfiddle untuk menggunakan scaleY bukan dari ketinggian, http://jsfiddle.net/dotnetCarpenter/7cnfc/206/.Solusi yang saya've selalu digunakan adalah untuk pertama fade out, kemudian menyusut font-size
, padding
dan margin
nilai-nilai. Itu doesn't terlihat sama seperti lap, tetapi ia bekerja tanpa statis tinggi
atau max-tinggi
.
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>
<p>Another paragraph...</p>
Saya tahu ini adalah tiga puluh somethingth jawaban untuk pertanyaan ini, tetapi saya pikir itu's worth it, jadi di sini anda pergi. Ini adalah CSS-hanya solusi dengan sifat sebagai berikut:
transform: scaleY(0)
), sehingga tidak benar jika ada's konten setelah dilipat elemen. height: auto
) menyatakan, seluruh isi selalu memiliki ketinggian yang benar (seperti misalnya jika anda memilih max-height
yang ternyata menjadi terlalu rendah). Dan dalam keadaan runtuh, ketinggian nol sebagaimana mestinya. Berikut ini's demo dengan tiga elemen dilipat, semua dari ketinggian yang berbeda, bahwa semua sama-sama menggunakan CSS. Anda mungkin ingin untuk mengklik "halaman penuh" setelah mengklik "menjalankan cuplikan". Perhatikan bahwa JavaScript hanya matikan runtuh
kelas CSS, ada's tidak ada pengukuran yang terlibat. (Anda dapat melakukan ini tepat demo tanpa JavaScript sama sekali dengan menggunakan kotak centang atau :target
). Juga perhatikan bahwa bagian dari CSS yang's yang bertanggung jawab untuk transisi ini cukup singkat, dan HTML hanya membutuhkan satu tambahan pembungkus elemen.
$(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>
Sebenarnya ada dua * transisi yang terlibat dalam membuat ini terjadi. Salah satu dari mereka transisi margin-bottom
dari 0px (di negara berkembang) untuk -2000px
dalam keadaan runtuh (mirip dengan jawaban). 2000 berikut ini adalah yang pertama magic number, it's didasarkan pada asumsi bahwa anda memenangkan't menjadi lebih tinggi dari ini (2000 piksel tampaknya seperti pilihan yang wajar).
Menggunakan margin-bottom
transisi sendiri memiliki dua masalah:
margin-bottom: -2000px
tidak't menyembunyikan segala sesuatu yang-ada'akan terlihat hal-hal yang bahkan di runtuh kasus. Ini adalah minor memperbaiki kesalahan yang kita'll lakukan nanti. min-height
properti untuk ini; lebih pada nanti).
Berikut ini's sebuah animasi yang menunjukkan cara menggabungkan margin bawah transisi dengan ketinggian minimum transisi, keduanya sama durasi, memberi kita gabungan transisi dari tinggi ke nol tinggi yang memiliki durasi yang sama.
Panel kiri menunjukkan berapa negatif margin bawah mendorong bagian bawah ke atas, mengurangi terlihat tinggi. Tengah bar yang menunjukkan berapa ketinggian minimum memastikan bahwa dalam runtuh kasus, transisi doesn't end awal, dan dalam kasus berkembang, transisi doesn't mulai terlambat. Hak bar menunjukkan bagaimana kombinasi dari dua penyebab kotak untuk transisi dari tinggi ke nol tinggi dalam jumlah yang tepat waktu.
Untuk demo saya saya've menetap di 50px sebagai atas ketinggian minimum nilai. Ini adalah kedua angka ajaib, dan itu harus lebih rendah dari kotak' tinggi akan pernah sama. 50px tampaknya masuk akal juga, tampaknya tidak mungkin bahwa anda'd sangat sering ingin membuat sebuah elemen yang dilipat isn't bahkan 50 piksel yang tinggi di tempat pertama.
Seperti yang anda lihat dalam animasi, yang dihasilkan transisi terus-menerus, tetapi hal ini tidak terdiferensiasi -- pada saat ketinggian minimum sama dengan tinggi disesuaikan dengan margin bawah, tiba-tiba ada perubahan kecepatan. Ini sangat terlihat dalam animasi karena menggunakan linear fungsi waktu untuk transisi, dan karena seluruh transisi sangat lambat. Dalam kasus yang sebenarnya (demo saya di atas), transisi hanya membutuhkan waktu 300ms, dan margin bawah transisi adalah tidak linear. I've bermain-main dengan banyak fungsi waktu untuk transisi, dan orang-orang yang saya berakhir dengan merasa seperti mereka bekerja terbaik untuk berbagai kasus.
Dua masalah tetap untuk memperbaiki: max-height: 0
di runtuh kasus, dengan 0s 0.3 s
transisi. Ini berarti bahwa itu's tidak benar-benar transisi, tapi max-height
diterapkan dengan penundaan; itu hanya berlaku setelah masa transisi berakhir. Untuk ini untuk bekerja dengan benar, kita juga perlu memilih numerik max-height
untuk sebaliknya, non-runtuh, negara. Tapi tidak seperti di 2000px kasus, mana yang terlalu besar dari sejumlah mempengaruhi kualitas transisi, dalam hal ini, itu benar-benar doesn't peduli. Jadi kita hanya bisa memilih jumlah yang sangat tinggi sehingga kita tahu ** yang tidak tinggi akan pernah datang dekat ini. Aku mengambil satu juta piksel. Jika anda merasa anda mungkin perlu untuk mendukung isi dari ketinggian lebih dari satu juta piksel, maka 1) I'm maaf, dan 2) hanya menambahkan beberapa angka nol.
Masalah kedua adalah alasan mengapa kita're tidak benar-benar menggunakan min-height
untuk ketinggian minimum transisi. Sebaliknya, ada sebuah ::setelah
pseudo-elemen dalam wadah dengan tinggi
bahwa transisi dari 50px ke nol. Ini memiliki efek yang sama sebagai min-height
: tidak't membiarkan wadah menyusut di bawah ini dengan ketinggian pseudo-elemen yang saat ini telah. Tapi karena kami're menggunakan tinggi
, bukan min-height
, sekarang kita dapat menggunakan max-height
(sekali lagi diterapkan dengan penundaan) untuk mengatur pseudo-element's aktual tinggi ke nol setelah masa transisi berakhir, memastikan bahwa setidaknya luar transisi, bahkan unsur-unsur kecil yang memiliki ketinggian yang benar. Karena min-height
adalah kuat dari max-height
, ini tidak't bekerja jika kita menggunakan wadah's min-height
bukan pseudo-element's tinggi
. Seperti max-tinggi
di paragraf sebelumnya, ini max-height
juga membutuhkan nilai untuk ujung transisi. Tapi dalam hal ini kita hanya dapat memilih 50px.
Diuji di Chrome (Win, Mac, Android, iOS), Firefox (Win, Mac, Android), Edge, IE11 (kecuali untuk flexbox masalah tata letak dengan demo saya bahwa saya tidak't repot-repot debugging), dan Safari (Mac, iOS). Berbicara tentang flexbox, itu harus mungkin untuk membuat ini bekerja tanpa menggunakan flexbox; pada kenyataannya, saya pikir anda bisa membuat hampir semua yang bekerja di IE7 – kecuali untuk fakta bahwa anda memenangkan't memiliki CSS transisi, sehingga agak sia-sia. Anda bisa, dengan sedikit non-semantik intrik. Saya biasa pendekatan adalah untuk menghidupkan tinggi dari luar DIV yang memiliki anak tunggal yang merupakan gaya-kurang DIV digunakan hanya untuk mengukur kadar tinggi.
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 dapat membuang .measuringWrapper
dan hanya mengatur DIV's tinggi untuk auto dan memiliki yang bernyawa, tapi itu doesn't tampaknya bekerja (ketinggian akan diatur, tapi tidak ada animasi yang terjadi).
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 eksplisit tinggi diperlukan untuk animasi untuk menjalankan. Anda dapat't mendapatkan animasi pada ketinggian ketika salah ketinggian (awal atau akhir tinggi) adalah auto
.
Visual solusi untuk menghidupkan tinggi menggunakan CSS3 transisi adalah untuk menghidupkan padding sebaliknya.
Anda don't cukup mendapatkan penuh menghapus efek, tapi bermain-main dengan transisi-süre dan padding nilai-nilai yang harus mendapatkan cukup dekat. Jika anda don't ingin secara eksplisit diatur tinggi/max-tinggi, ini harus menjadi apa yang anda're looking for.
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;
}
Solusi saya adalah untuk transisi max-height tepat konten tinggi badan untuk animasi yang halus, kemudian gunakan transitionEnd callback untuk mengatur max-tinggi untuk 9999px sehingga konten dapat mengubah ukuran 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>
Jawaban yang diterima bekerja untuk sebagian besar kasus, tapi itu doesn't bekerja dengan baik ketika anda div
dapat sangat bervariasi di ketinggian — kecepatan animasi tidak tergantung pada ketinggian sebenarnya dari konten, dan hal ini dapat terlihat berombak.
Anda masih dapat melakukan animasi yang sebenarnya dengan CSS, tapi anda perlu menggunakan JavaScript untuk menghitung ketinggian item, bukannya mencoba untuk menggunakan auto
. Tidak ada jQuery diperlukan, meskipun anda mungkin harus memodifikasi sedikit jika anda ingin kompatibilitas (bekerja di Chrome versi terbaru :)).
jendela.toggleExpand = function(elemen) { jika (!elemen.gaya.tinggi badan || elemen.gaya.height == '0px') { elemen.gaya.tinggi = Array.prototipe.mengurangi.panggilan(elemen.childNodes, function(p, c) {return p + (c.offsetHeight|| 0);}, 0) + 'px'; } else { elemen.gaya.tinggi = '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>
Ada sedikit menyebutkan dari Elemen.scrollHeight
properti yang dapat berguna di sini dan masih dapat digunakan dengan CSS murni transisi. Properti selalu berisi "full" tinggi dari sebuah elemen, terlepas dari apakah dan bagaimana isinya melimpah sebagai hasil dari runtuh tinggi (misalnya tinggi: 0
).
Dengan demikian, untuk tinggi: 0
(efektif sepenuhnya runtuh) unsur, "normal" atau "full" tinggi masih tersedia melalui scrollHeight
nilai (selalu pixel panjang).
Untuk elemen seperti itu, asumsi itu sudah memiliki transisi set up seperti misalnya (menggunakan ul
sesuai pertanyaan awal):
ul {
height: 0;
transition: height 1s; /* An example transition. */
}
Kita dapat memicu diinginkan animasi "ekspansi" dari ketinggian, dengan menggunakan CSS saja, dengan sesuatu seperti berikut (di sini dengan asumsi ul
variabel mengacu pada daftar):
ul.style.height = ul.scrollHeight + "px";
Yang's ini. Jika anda perlu untuk menutup daftar, salah satu dari dua pernyataan berikut akan dilakukan:
ul.style.height = "0";
ul.style.removeProperty("height");
Saya kasus penggunaan tertentu berkisar menghidupkan daftar dari tidak diketahui dan sering cukup panjang, jadi saya tidak nyaman menetap di sewenang-wenang "cukup besar" tinggi
atau max-height
spesifikasi dan mempertaruhkan cut-off isi atau konten yang anda tiba-tiba perlu gulir (jika overflow: auto
, misalnya). Selain itu, pelonggaran dan waktu rusak dengan max-height
berbasis solusi, karena digunakan tinggi dapat mencapai nilai maksimum jauh lebih cepat dari itu akan mengambil untuk max-height
untuk mencapai 9999px
. Dan seperti resolusi layar yang tumbuh, pixel panjang seperti 9999px
meninggalkan rasa tidak enak di mulut saya. Ini khusus solusi memecahkan masalah dengan cara yang elegan, dalam pendapat saya.
Akhirnya, di sini adalah berharap bahwa revisi masa depan CSS alamat penulis' perlu melakukan hal-hal semacam ini bahkan lebih elegan -- kembali gagasan "computed" lebih "digunakan" dan "diselesaikan" nilai-nilai, dan mempertimbangkan apakah transisi harus berlaku untuk dihitung nilai-nilai, termasuk transisi dengan width
dan height
(yang saat ini mendapatkan sedikit perlakuan khusus).
Gunakan max-height
dengan transisi yang berbeda mengurangi dan menunda untuk masing-masing negara.
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;
}
Lihat contoh:
Tidak sulit dikodekan nilai-nilai.
Tidak Ada JavaScript.
Tidak ada perkiraan.
Caranya adalah dengan menggunakan tersembunyi & digandakan div
untuk mendapatkan browser untuk memahami apa yang 100% berarti.
Metode ini cocok bila anda're mampu menduplikasi DOM elemen yang ingin anda animasikan.
.outer { perbatasan: putus-putus merah 1px; position: relative; }
.dummy { visibility: hidden; }
.real { position: absolute; latar belakang: kuning; tinggi: 0; transisi: tinggi 0.5 s; overflow: hidden; }
.luar:hover>.real { tinggi: 100%; }
Arahkan kursor pada kotak di bawah ini:
Seperti yang saya posting ini ada lebih dari 30 jawaban sudah, tapi aku merasa jawaban saya meningkatkan pada yang sudah jawaban yang diterima oleh jake.
Saya tidak puas dengan masalah-masalah yang timbul dari hanya menggunakan max-height
dan CSS3 transisi, karena banyak komentator mencatat, anda harus mengatur max-height
nilai yang sangat dekat dengan ketinggian yang sebenarnya atau anda'll mendapatkan penundaan. Melihat ini [JSFiddle](
Untuk mendapatkan sekitar ini (sementara masih menggunakan JavaScript), saya menambahkan satu elemen HTML yang transisi transform: translateY
nilai CSS.
Ini berarti kedua max-tinggi
dan translateY
yang digunakan: max-height
memungkinkan elemen untuk mendorong ke bawah unsur-unsur di bawah ini, sementara translateY
memberikan "instan" efek yang kita inginkan. Masalah dengan max-height
masih ada, tapi efeknya berkurang.
Ini berarti anda dapat mengatur banyak ketinggian yang lebih besar untuk max-height
nilai dan khawatir tentang hal itu kurang.
Manfaat keseluruhan adalah bahwa pada transisi kembali (keruntuhan), pengguna melihat translateY
animasi dengan segera, sehingga tidak't benar-benar peduli berapa lama max-height
mengambil.
[Solusi seperti Biola](https://jsfiddle.net/ajo89vmg/)
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, jadi saya pikir saya datang dengan super jawaban sederhana...
tidak ada max-height
, menggunakan relatif
positioning, bekerja pada li
elemen, & adalah CSS murni.
Saya belum diuji pada apa-apa tapi Firefox, meskipun dilihat oleh CSS, ini harus bekerja pada semua browser.
BIOLA:
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: Gulir ke bawah untuk diperbarui jawaban
Saya membuat daftar drop-down dan melihat Posting ini ... banyak jawaban yang berbeda tapi aku memutuskan untuk berbagi daftar drop-down terlalu, ... Itu's tidak sempurna tapi setidaknya itu akan hanya menggunakan css untuk drop-down! I've telah menggunakan transform:translateY(y) untuk mengubah klik disini untuk melihat ...
Anda dapat melihat lebih banyak di tes
#menu div {
transition: 0.5s 1s;
z-index:-1;
-webkit-transform:translateY(-100%);
-webkit-transform-origin: top;
}
dan melayang-layang adalah :
#menu > li:hover div {
transition: 0.5s;
-webkit-transform:translateY(0);
}
dan karena ul tinggi diatur ke konten itu bisa mendapatkan lebih dari tubuh anda konten yang's mengapa saya melakukan ini untuk ul:
#menu ul {
transition: 0s 1.5s;
visibility:hidden;
overflow:hidden;
}
dan hover:
#menu > li:hover ul {
transition:none;
visibility:visible;
}
kedua kalinya setelah transisi adalah penundaan dan akan mendapatkan tersembunyi setelah saya daftar drop-down telah ditutup animately ...
Berharap nanti seseorang mendapatkan manfaat dari yang satu ini.
EDIT: aku hanya bisa't percaya ppl benar-benar menggunakan prototipe ini! ini menu drop down ini hanya untuk satu sub menu dan yang's semua!!
I've diperbarui lebih baik salah satu yang dapat memiliki dua sub menu untuk investasi dan rtl ltr arah dengan IE 8 dukungan.
[Biola untuk LTR][1]
[Biola untuk RTL][2]
mudah-mudahan seseorang menemukan ini berguna di masa depan.
Anda dapat transisi dari ketinggian:0-height:auto menyediakan bahwa anda juga memberikan menit-tinggi dan max-tinggi.
div.stretchy{
transition: 1s linear;
}
div.stretchy.hidden{
height: 0;
}
div.stretchy.visible{
height: auto;
min-height:40px;
max-height:400px;
}
Flexbox Solusi
Pro:
Cons:
Cara kerjanya adalah dengan selalu memiliki flex-dasar: auto pada elemen dengan konten, dan transisi flex-tumbuh dan flex-mengecilkan sebaliknya.
Edit: Peningkatan JS Fiddle terinspirasi oleh Xbox Satu antarmuka.
* {
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][1]
Aku pikir aku datang dengan benar-benar solid solution
OK! Aku tahu masalah ini adalah sebagai tua sebagai internet tapi saya pikir saya memiliki solusi yang saya berubah menjadi plugin yang disebut mutan-transisi. Solusi saya set style=","
atribut untuk dilacak unsur-unsur setiap kali ada perubahan dalam DOM. hasil akhirnya adalah bahwa anda dapat menggunakan baik ole CSS untuk transisi dan tidak menggunakan hacky perbaikan atau javascript khusus. Satu-satunya hal yang harus anda lakukan adalah menetapkan apa yang ingin anda lacak pada elemen menggunakan pertanyaan data-mutant-atribut="X"
.
<div data-mutant-attributes="height">
This is an example with mutant-transition
</div>
Thats it! Solusi ini menggunakan MutationObserver untuk mengikuti perubahan dalam DOM. Karena ini, anda don't benar-benar harus mengatur apa-apa atau menggunakan javascript untuk secara manual menghidupkan hal-hal. Perubahan dilacak secara otomatis. Namun, karena menggunakan MutationObserver, ini hanya akan transisi di IE11+. <IE11 akan melihat snap-perubahan (transisi).
Biola!
height: auto
untuk height: 100%
][3]height: auto
ketika menambahkan anak-anak][4]Jake's jawaban untuk menghidupkan max-height besar, tapi saya menemukan keterlambatan yang disebabkan oleh pengaturan yang besar max-height mengganggu.
Salah satu yang bisa bergerak disempitkan konten ke dalam div dan menghitung ketinggian max dengan mendapatkan ketinggian batin div (via JQuery itu'd menjadi outerHeight()).
$('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');
});
Berikut ini's jsfiddle link:
/embedded/result,js,html,css/">Berikut ini's jsfiddle dengan mutlak minimal jumlah kode yang dibutuhkan: http://jsfiddle.net/8ncjjxh8/
Memperluas @jake's jawaban, transisi akan pergi semua jalan ke max nilai tinggi, menyebabkan sangat cepat animasi - jika anda mengatur transisi untuk investasi :hover dan off maka anda dapat mengontrol kecepatan gila sedikit lebih.
Jadi li:hover adalah ketika tikus masuk ke negara dan kemudian transisi pada non-melayang properti akan mouse pergi.
Mudah-mudahan ini akan membantu.
e.g:
.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 */
Berikut ini's biola: