Soru Yüksekliğe nasıl geçebilirim: 0; yüksekliğe: otomatik; CSS kullanarak?


Ben yapmaya çalışıyorum <ul> CSS geçişlerini kullanarak aşağı kaydırın.

<ul> yola çıkmak height: 0;. Vurgulu olarak, yükseklik height:auto;. Ancak, bu sadece görünmesini neden oluyor, değil geçiş,

Eğer ben yaparsam height: 40px; için height: auto;, sonra o kadar kayar height: 0;ve sonra aniden doğru yüksekliğe atlayın.

JavaScript kullanmadan bunu başka nasıl yapabilirim?

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


1602
2017-08-18 02:50


Menşei


İnanıyorum height:auto/max-height çözüm sadece genişleyen alan iseniz height kısıtlamak istiyorsun. Eğer bir max-height arasında 300pxama açılan bir açılan kutu açılır. 50px, sonra max-height sana yardım etmeyecek 50px eleman sayısına bağlı olarak değişkendir, düzeltemediğim imkansız bir duruma ulaşabilirsiniz çünkü height sabit değil height:auto çözümdü, ama bununla geçişleri kullanamıyorum. - Christopher Thomas
OP, css çözümünü deniyor, js değil, aksi halde sadece taşma ve canlandırma kullanabiliyorlar - Toni Leigh
@ToniLeigh veya jQuery.slideToggle (); - mopo922
Tüm bu cevaplar tam olarak doğru değil. Sadece iki CSS bildirimi ile bir çözüm (bugün cevap ekledim) var. Maksimum yükseklik kullanmaz. Bu saf CSS ve kurulumu çok basit. Göreceli konumlandırma üzerinde çalışır. İşte bir keman jsfiddle.net/n5XfG/2596 - VIDesignz
@VIDesignz: Ama iç div -100% margin-top alır Genişlik sarıcı div yükseklik değil. Yani bu çözüm aynı tür bir soruna, maksimum yükseklik çözümüne sahip. Ayrıca, genişlik içeriğin yüksekliğinden daha küçük olduğunda, tüm içerik% -100 oranında kenar boşluğu tarafından gizlenmez. Yani bu yanlış bir çözüm. - GregTom


Cevaplar:


kullanım max-height dönüşümde ve değil height. Ve üzerinde bir değer ayarla max-height Kutusundan daha büyük bir şeye ulaşacaksın.

Görmek JSFiddle demosu Chris Jordan tarafından başka bir Cevap İşte.

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


2161
2017-11-30 18:42



Bu harika çalışıyor! Başladığı zaman bir gecikme var, çünkü başlangıçta çok yüksek olan max-yükseklik için başlar çünkü .hmm, sanırım bu biraz sinir bozucu - vsync
+1 Harika çözüm! Geçişin hızı hesaplanır, maksimum yükseklik değerine geçiş için belirttiğiniz süre olarak hesaplanır ... ancak yükseklik maksimum yükseklikten daha az olacağından, gerçek yüksekliğe geçiş daha hızlı (genellikle önemli ölçüde) daha hızlı gerçekleşir. belirtilen süre. - kingjeffrey
Gerçek hesaplanmış değerden çok daha büyük değerler kullanmanız gerektiğinde, bu durumun çirkin geçişin sona ermesine neden olabileceğini unutmayın. Bunu farkettim ki, bir ekran farkl 1s 1ndan, farkl ekran boyutlarna (2560x1440 monitörde 2 hat, bir akıllı telefon üzerindeki> 10 hat) büyük ölçüde farkl olan içerik yüksekli ine yükseliyor. Bunun için js ile devam ettim. - jpeltoniemi
Etrafında büyük iş - değil çözüm;) - acSlater
Bu oldukça tembel bir çözüm. OP'nin yüksekliği kullanmak istediğini varsayıyorum: auto, kabın genişletilmiş yüksekliği biraz öngörülemez. Bu çözüm, animasyon görünür hale gelmeden önce bir gecikmeye neden olur. Ek olarak, animasyonun görünür süresi tahmin edilemez. Kapların her bir çocuk düğümünün birleşik yüksekliğini hesaplayarak ve ardından tam bir yükseklik değerine ulaşarak çok daha öngörülebilir (ve muhtemelen daha yumuşak) sonuçlar elde edersiniz. - Shawn Whinnery


Bunun yerine scaleY kullanmalısınız.

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

Jsfiddle'da yukarıdaki kodun bir satıcı öneki sürümünü yaptım, http://jsfiddle.net/dotnetCarpenter/PhyQc/9/ ve jsfiddle'ınızı yükseklik yerine scaleY kullanacak şekilde değiştirdiler. http://jsfiddle.net/dotnetCarpenter/7cnfc/206/.


228
2018-06-23 10:57



Bu cevabı kaldırıyorum çünkü css3 geçişli yetenekli tarayıcılarda iyi çalışıyor, ancak bunun dikkate alınması gerekiyor. IE'de hiç çalışmayacak <9, ve IE'de animasyonlu olmayacak (sadece atlayacaktır) <10 - Hailwood
Bu yöntem, yalnızca istenen etkiyi kısmen elde eder ancak aslında olmaz Kaldır boşluk. Dönüştürülmüş kutu nispeten konumlandırılmış bir eleman gibi davranır - alan nasıl ölçeklendirilirse alınsın. Çıkış yapmak bu jsFiddle İlkini alır ve sadece aşağıdan bazı sahte metin ekler. Kutu yüksekliği sıfıra ölçeklendiğinde aşağıdaki metnin nasıl yukarı çıkmadığını not alın. - animuson♦
Şimdi yapar: jsfiddle.net/gNDX3/1 Temel olarak, elemanlarınızı ihtiyacınız olan şeylere göre şekillendirmeniz gerekir. CSS / HTML'de gümüş mermi veya widget benzeri bir davranış yoktur. - dotnetCarpenter
Farklı yaklaşımları deneyen birisini alkışlarken, bu çözümün getirdiği gerçek dünya etkisi ve komplikasyonlar zaten berbat olan max-height hack'ten çok daha kötüdür. Kullanmayın lütfen. - mystrdat
Boşluk başarısız jsfiddle.net/PhyQc/336 - e-info128


İlgili yüksekliklerden biri olduğunda, şu anda yükseklikte animasyon yapamazsınız autoİki açık yükseklik ayarlamalısınız.


164
2017-08-18 12:46



Bir sorunu çözmek için genellikle birden fazla yol vardır ve bunların hepsi uygun veya mümkün değildir. @JedidiahHurt ve Ryan Ore neden bir Soru-Cevap sitesindeki olası cevapları sınırlamaya çalıştıklarını bilmiyorum. Özellikle bu cevabı göz önünde bulundurarak önce buradaydı. İki kez kabul edilen cevap bir geçici çözüm olduğundan. - Hooray Im Helping
@Jake'den gelen cevap ne zarif ne de doğru. Buradaki bağlantılı cevap çok daha iyi. Doğru çalışır ve tüm büyüklükteki durumları ele alır - kabul edilen cevaptan da söylenemez. - GraphicsMuncher
Bu değişti mi? Önyükleme için daha az önyükleme düzeninde, onları açıkça yükseklik geçişini görüyorum ve bildiğim kadarıyla her hangi bir yüksekliğe uyum sağlıyor: .collapsing { position: relative; height: 0; overflow: hidden; .transition-property(~"height, visibility"); .transition-duration(.35s); .transition-timing-function(ease); } - Andy
Oh, bilirsin, önyükleme komutunun sadece CSS animasyonunu tetiklemeden hemen önce içeriğin yüksekliğini hesaplar ve ayarlar. - Andy
Yup: öyle this.$element[dimension](this.$element[dimension]())[0].offsetHeight - Andy


Her zaman kullandığım çözüm ilk önce sönüp, ardından da küçültmek oldu. font-size, padding ve margin değerler. Silme ile aynı görünmüyor, ancak statiksiz çalışıyor height veya 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;
}

Çalışma örneği:

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



Benim için düzgünce çalıştı. JQuery slideUp / Down gibi değil. Eski bilgisayar veya mobil gibi zayıf CPU'larla sadece bir fark görebilir ve birçoğunu aynı anda açıp kapatabilirsiniz. - Cruz Nunez
Düğmeleriniz veya başka metin olmayan öğeleriniz varsa, gezinirken değilken istenmeyen boşluklarla sonlanacaksınız. - Dennis W
İle tüm alt öğeleri seçerek daha da hassaslaştırabilirsiniz. * ve diğer değişiklikleri uygulamak. Düğmeler, yukarıdaki kodumdan etkilenmiş olmalıydı, ancak, em. - Steven Vachon
Benim durumumda da eklemem gerekiyordu line-height: 0; ve border-width: 0; - Andrey Shatilov
Ayarlamaya gerek yok. line-height Değer üzerindeki birimlerden doğru bir şekilde kaçarsanız: developer.mozilla.org/en-US/docs/Web/CSS/... - Steven Vachon


Semantik olmayan jiggery-pokery ile biraz yapabilirsiniz. Her zamanki yaklaşımım, sadece içeriğin yüksekliğini ölçmek için kullanılan, stilsiz bir DIV olan tek bir çocuğa sahip olan bir DIV'nin yüksekliğini canlandırmaktır.

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>

Birisi sadece ile dağıtmak istiyorum .measuringWrapper ve DIV'nin yüksekliğini otomatik olarak ayarlayın ve bu özelliği canlandırın, ancak bu işe yaramaz (yükseklik ayarlanır, ancak animasyon olmaz).

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>

Benim yorumum, animasyonun çalışması için açık bir yüksekliğe ihtiyaç duyuyor. Yükseklik (başlangıç ​​veya bitiş yüksekliği) ne zaman yüksekse bir animasyon alamazsınız auto.


64
2018-06-30 13:32



Bu javascript'e dayandığından, javascript'i kullanarak kolayca ölçüm tutacağını da ekleyebilirsiniz! - Quickredfox
Sarıcı olmadan yapabilirsiniz. Sadece: function growDiv () {var growDiv = document.getElementById ('büyümeye'); if (growDiv.clientHeight) {growDiv.style.height = 0; } else {growDiv.style.height = growDiv.scrollHeight + 'px'; }} - user1742529
Şuna bak ... basit bir cevap hakkında konuş jsfiddle.net/n5XfG/2596 ... Cevabınız iyi bir sebepten dolayı delice karmaşıktır. İhtiyaç yok max-height, ihtiyaç yok autove özellikle Javascript için gerek yok! Sadece iki basit beyanname - VIDesignz
@VIDesignz Marjın üzerinde animasyon uygulayabilirsiniz:% 100. Bu% 100 Genişlik elemanın yüksekliği değil! Bu, genişliğinden daha büyük bir boyuta sahipseniz, bunun gizlenmeyeceği anlamına gelir. Ayrıca gerçek Animasyon hızı tanımlanmış olandan tamamen farklı. - Timo Türschmann
Timo'nun yorumu hakkında daha fazla bilgi alana kadar VIDesignz'in cevabı konusunda heyecanlandım. Evet, margin-top (ve margin-bottom) yüzde olarak tanımlandığında genişliğe göreli, evet bu aptalca, ama aynı zamanda açık ve yakın animasyon zamanlamalarının neden tamamen farklı olduğunu açıklıyor - en yüksek puanlı cevapta gördüğünüz aynı şey, kodlanmış bir maks. yükseklik. Neden bu kadar doğru yapmak zor? - Coderer


Biliyorum, bu sorunun otuzbeş yanıtı, ama bence buna değdi, işte burada. Bu bir CSS okunur aşağıdaki özelliklere sahip çözüm:

  • Başlangıçta gecikme yok ve geçiş erken durmuyor. Her iki yönde de (genişletme ve daraltma), CSS'nizde 300 ms'lik bir geçiş süresi belirtirseniz, geçiş 300 ms sürer.
  • Gerçek yüksekliği değiştiriyor (aksine transform: scaleY(0)), böylece katlanabilir elemandan sonra içerik varsa doğru olanı yapar.
  • (Diğer çözümlerde olduğu gibi) Hangi sihirli numaralar ("kutununkinden daha uzun bir uzunluk seç" gibi), varsayım yanlış olsaydı ölümcül değildir. Geçiş bu durumda şaşırtıcı görünmeyebilir, ancak geçişten önce ve sonra, bu bir sorun değildir:height: auto) durumu, tüm içerik her zaman doğru yüksekliğe sahiptir (örneğin, max-heightBu çok düşük olduğu ortaya çıkıyor). Ve daraltılmış durumda, yükseklik gerektiği kadar sıfırdır.

gösteri

İşte hepsi aynı CSS kullanan üç farklı katlanabilir, farklı yüksekliklere sahip bir demo. "Snippet'i çalıştır" ı tıkladıktan sonra "tam sayfa" tıklamak isteyebilirsiniz. JavaScript’in yalnızca collapsed CSS sınıfı, hiçbir ölçüm dahil değildir. (Bu tam demoyu herhangi bir JavaScript kullanmadan bir onay kutusunu kullanarak veya :target). Ayrıca, geçişten sorumlu olan CSS'nin bölümünün oldukça kısa olduğunu ve HTML'nin yalnızca tek bir ek sarmalayıcı öğesi gerektirdiğini unutmayın.

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

O nasıl çalışır?

Aslında var iki Bunun gerçekleşmesiyle ilgili geçişler. Bunlardan biri geçiş yapar margin-bottom 0px'ten (genişletilmiş durumda) -2000px daraltılmış durumda bu cevap). Buradaki 2000 ilk sihirli sayıdır, kutunuzun bundan daha yüksek olmayacağı varsayımına dayanır (2000 piksel, makul bir seçim gibi görünür).

Kullanmak margin-bottom tek başına geçiş iki konuya sahiptir:

  • Aslında 2000 pikselden daha yüksek bir kutunuz varsa, o zaman margin-bottom: -2000px her şeyi saklamıyor - daraltılmış durumda bile görünür şeyler olacak. Bu daha sonra yapacağımız küçük bir düzeltmedir.
  • Eğer gerçek kutu 1000 piksel yüksekse ve geçişiniz 300 ms uzunsa, o zaman gözle görülür geçiş yaklaşık 150 ms sonra (veya ters yönde, 150ms geç başlar) sonra zaten bitti.

Bu ikinci konuyu düzeltmek, ikinci geçişin gerçekleştiği yerdir ve bu geçiş, ambalajcıyı kavramsal olarak hedefler. asgari yükseklik ("kavramsal olarak" çünkü aslında min-height bunun için mülkiyet; daha sonra bunun üzerine).

Alt kenar boşluğu geçişini, her iki eşit süre ile minimum yükseklik geçişiyle birleştirmenin, bize, aynı yüksekliğe sahip tam yükseklikte sıfır yüksekliğe kadar birleşik geçişi nasıl sağlayacağını gösteren bir animasyon.

animation as described above

Sol çubuk, negatif alt kenar boşluğunun alt kısmı yukarı doğru iterek nasıl görünür yüksekliğini azalttığını gösterir. Orta çubuk, asgari yüksekliğin, daraltma durumunda geçişin erken bitmemesini ve genişleyen durumda geçişin geç başlamadığını garanti eder. Sağ çubuk, ikisinin kombinasyonunun doğru zaman aralığında kutunun tam yükseklikte sıfır yüksekliğe nasıl geçtiğini gösterir.

Benim demo için 50px'e üst minimum yükseklik değeri olarak karar verdim. Bu, ikinci sihirli sayıdır ve kutunun yüksekliğinden daha düşük olmalıdır. 50px de makul görünüyor; Çok sık, ilk etapta 50 piksel bile yüksek olmayan katlanabilir bir öğe yapmak isteyebilirsiniz.

Animasyonda gördüğünüz gibi, sonuçta oluşan geçiş süreklidir, ancak ayırt edilemez - minimum yükseklik, alt kenar boşluğu tarafından ayarlanan tam yüksekliğe eşit olduğu anda, hızda ani bir değişim olur. Bu, animasyonda çok fark edilir çünkü her iki geçiş için de doğrusal bir zamanlama işlevi kullanıyor ve tüm geçiş çok yavaş olduğu için. Gerçek durumda (üstte benim demo) geçiş sadece 300 ms alır ve alt kenar geçişi doğrusal değildir. Her iki geçiş için de pek çok farklı zamanlama fonksiyonu ile oynadım ve en geniş çeşitlilikteki vakalar için en iyi şekilde çalıştıklarını hissettim.

Düzeltmek için iki sorun devam ediyor:

  1. yukarıdan bakıldığında, 2000 pikselden daha fazla olan kutuların daraltılmış durumda tamamen gizlenmediği nokta,
  2. ve gizli olmayan durumda, geçişin çalışmadığı zamanlarda bile 50 pikselden daha az olan kutular çok yüksek olduğu için ters sorun, çünkü minimum yükseklik onları 50 pikselde tutar.

İlk problemi konteyner elemanına vererek çözüyoruz. max-height: 0 daraltılmış durumda 0s 0.3s geçiş. Bu gerçekten bir geçiş değil, ama max-height bir gecikme ile uygulanır; Sadece geçiş bittiğinde uygulanır. Bunun doğru çalışması için, sayısal olarak da seçmemiz gerekiyor max-height karşıt, çökmeyen, devlet için. Fakat 2000px örneğinden farklı olarak, bir sayının çok büyük olması geçişin kalitesini etkiler, bu durumda gerçekten önemli değil. Yani biz o kadar yüksek bir sayı seçebiliriz ki bilmek hiçbir yükseklik buna yakın gelmeyecek. Bir milyon piksel seçtim. Bir milyondan fazla piksel yüksekliğinde bir içeriği desteklemeniz gerektiğini düşünüyorsanız, 1) Üzgünüm ve 2) sadece birkaç tane sıfır ekleyin.

İkinci sorun aslında neden kullanmadığımızın sebebidir. min-height Minimum yükseklik geçişi için. Bunun yerine, bir ::after kapsayıcıda sözde öğe height bu 50px'den sıfıra geçiş yapar. Bu aynı etkiye sahiptir min-height: Konteynerin, sözde-elementin halihazırda sahip olduğu yüksekliğin altında küçülmesine izin vermeyecektir. Ama kullandığımız için height, değil min-heightşimdi kullanabiliriz max-height Geçiş bittiğinde sözde elemanın gerçek yüksekliğini sıfırlamak için bir kez daha (gecikmeli olarak uygulanır), geçişin en azından dışında, küçük öğelerin bile doğru yüksekliğe sahip olmasını sağlayın. Çünkü min-height olduğu güçlü göre max-heightBu, biz kullanıldıysa, bu işe yaramaz min-height sözde elemanın yerine height. Tıpkı max-height önceki paragrafta, bu max-height ayrıca geçişin karşı ucu için bir değere ihtiyaç duyar. Ama bu durumda sadece 50px'i seçebiliriz.

Chrome (Win, Mac, Android, iOS), Firefox (Win, Mac, Android), Edge, IE11 (testumda hata ayıklama yapmadığım bir esnek kutu düzeni sorunu hariç) ve Safari (Mac, iOS) test edildi ). Esnek kutudan bahsetmişken, bu işi herhangi bir esnek kutu kullanmadan yapmak mümkün olmalıdır; Aslında, IE7'de neredeyse her şeyi çalıştırabileceğinizi düşünüyorum - CSS geçişlerine sahip olmamanız ve bunun anlamsız bir egzersiz yapması dışında.


45
2018-05-14 14:33



Çözümünüzü kısaltabilir (basitleştirebilir) ya da en azından kod örneği - kod örneğinin% 90’ının cevabınızla alakalı olmadığı anlaşılıyor. - Gil Epshtain


CSS3 geçişlerini kullanarak hareketli yüksekliğe görsel bir çözüm, bunun yerine dolguyu canlandırmaktır.

Tam silme etkisini tam olarak almazsınız, ancak geçiş süresi ve dolgu değerleri ile oynamak sizi yeterince yakınlaştırmalıdır. Yüksekliği / maks-yüksekliğini açıkça ayarlamak istemiyorsanız, aradığınız şey bu olmalıdır.

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/ (stephband'ın jsFiddle'ın üstünde riffed)


44
2018-06-26 19:05



Bence bu en iyi cevap. Bu teknik, çocuklarda da dolgu maddesinin ayarlanmasına kadar uzanabilir. Benim durumumda, ortaya çıkarılan içeriklerin bazılarında açık yükseklik geçişleri ile birleştirebildim ve toplam etki, maksimum yükseklikteki çalışmadan çok daha başarılıydı, bu da ortaya çıkacak kadar iyi değil, ama garip bir anı getiriyor. saklanma gecikmesi. Uygulamamın tepkisiz görünmesini sağlayan anlamsız bir gecikme sunmaktan ziyade, hiç canlandırmam. Bu kadar çok insanın kabul edilebilir olduğunu düşündüğüne şaşırdım. - Semicolon
Bunun dışında, yüksekliği hiç eğmezsin. Dolguyu canlandırıyorsunuz ... sadece iyi görünebilir, çünkü mevcut durumdan 0'a kadar canlandırılabilir, ancak genişlediğinde yakından izlerseniz metin açılır ve sonra sadece animasyonlar açılır. 0'dan auto'a nasıl canlandırılacağını bilmiyorum .... sayısal bir aralığa ihtiyacı var. - Rob R
Bu, hacky olmayan iyi bir çözümdür. Bu en iyi cevap değil bu soru, ama benim için çalışan bir alternatif. Bazen sadece tam animasyon değil, bazı yükseklik animasyonunun etkisine ihtiyacın var :) - Ivan Durst
Bu çözüm, bir geçiş gecikmesi kullanıldığında da başarısız olur. - Michel Joanisse
Ayrıca, bu çözümün, animasyonunuz yeterince hızlı olduğunda (akışkanlar için 0.1s'lik bir akordeon için mükemmeldir) oldukça akışkan geçişler sağlayan temiz bir çözüm olduğunu kabul ediyorum. Yine de bir çok uygulama paketi olmayacak, ama bu soruya diğer anatörler de girmeyecek! - Remi D


Benim geçici çözümüm, güzel bir yumuşak animasyon için maksimum yüksekliğe tam içerik yüksekliğine geçmek, daha sonra içeriğin serbestçe yeniden boyutlandırılabilmesi için maksimum yüksekliği 9999px değerine ayarlamak için bir geçiş ve geri çağırma kullanın.

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



@ Derija93 Düz eski javascript zaman aşımı animasyonları kullanıyor. Zorluk yerine CSS3 geçişlerini kullanmaktır. - Adam
İyi evet. Ancak, örneğinizde, jQuery'yi zaten kullandığınız bir kütüphane olan "daha azını yaz, daha fazlasını yap" koduna sahip olursan niçin "CSS3 geçişleri yerine" kullanırsın? Sürümünüzün çok daha iyi görünebileceğine işaret etmek istedim, daha karmaşık olsa da, jQuery kullanmıyor olsaydı, sanal olarak herhangi bir web sitesinde çalışabilseydi. Sanırım onu ​​yanlış anladım. Üzgünüm, bunu. ;) - Kiruse
@ Derija93 Belki de CSS3 geçişleri (bulabildiğim tüm kaynaklara göre) jQuery animasyonlarından çok daha iyi bir performansa sahiptir. (Aslında beni buraya getiren mevcut kullanım durumum için çok önemli.) - Mark Amery
@ Derija93 'Neden Javascript animasyonlar yavaş yavaş CSS3 geçişler ile karşılaştırıldığında, jQuery animasyonları ile animasyon döngüsü hakkında endişelenmeniz gerekir. Tıklamada bir şeyleri canlandırın, ardından hızlıca tıklayın ve animasyonların kendilerini tekrarladığını izleyin. Bu CSS3 ile ele alınır. - Dropped.on.Caprica
@ Dropped.on.Caprica Şimdi biraz eski. Göstermeye çalıştığı kavramı yanlış anladım. Her neyse, basit animasyonlar için, .stop oldukça karmaşık bir animasyon döngüsü sorunu için hile yapar. Şimdi, yükseklik ve rengi canlandırdığın zaman sadece yükseklik animasyonunu kesmek istediğin zaman, işler biraz daha zorlaşır ... Senin dikkatini çekerim. - Kiruse