كيف يمكنني الانتقال الارتفاع:0;إلى الارتفاع:السيارات ؛ باستخدام CSS ؟

StackOverflow https://stackoverflow.com/questions/3508605

  •  29-09-2019
  •  | 
  •  

سؤال

أنا في محاولة لجعل <ul> تنزلق باستخدام CSS التحولات.

على <ul> يبدأ في height: 0;.على تحوم, ارتفاع تعيين height:auto;.ومع ذلك ، فإن هذا يسبب ذلك ببساطة تظهر ، لا الانتقال ،

إذا كنت تفعل ذلك من height: 40px; إلى height: auto;, بعد ذلك سوف تصل إلى الشريحة height: 0;, ثم فجأة يقفز إلى الارتفاع الصحيح.

وإلا كيف يمكن أن أفعل هذا دون استخدام جافا سكريبت ؟

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

هل كانت مفيدة؟

المحلول

يستخدم max-height في التحول وليس height. وتعيين قيمة على max-height إلى شيء أكبر من صندوقك سيحصل عليه.

نرى JSfiddle Demo قدمه كريس جوردان في آخر إجابه هنا.

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

نصائح أخرى

يجب عليك استخدام Scaley بدلاً من ذلك.

لغة البرمجة:

<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 ، http://jsfiddle.net/dotnetcarpenter/phyqc/9/ وتغيير JSFiddle لاستخدام Scaley بدلاً من الارتفاع ، http://jsfiddle.net/dotnetcarpenter/7cnfc/206/.

لا يمكنك حاليًا تحريك الارتفاع عندما يكون أحد المرتفعات المعنية auto, ، عليك وضع ارتفاعات صريحة.

كان الحل الذي استخدمته دائمًا هو التلاشي أولاً ، ثم تقليص font-size, padding و margin القيم. لا يبدو مثل المسح ، لكنه يعمل بدون ثابت height أو 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;
}
<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>

أعلم أن هذا هو الإجابة الثلاثين على هذا السؤال ، لكنني أعتقد أن الأمر يستحق ذلك ، لذلك هنا يذهب. هذا ال CSS فقط الحل مع الخصائص التالية:

  • لا يوجد تأخير في البداية ، والانتقال لا يتوقف مبكرًا. في كلا الاتجاهين (التوسع والانهيار) ، إذا حددت مدة انتقال قدرها 300 مللي ثانية في CSS ، فإن الانتقال يستغرق 300 مللي ثانية ، الفترة.
  • إنه ينقل الارتفاع الفعلي (على عكس transform: scaleY(0)) ، لذلك يفعل الشيء الصحيح إذا كان هناك محتوى بعد العنصر القابل للطي.
  • بينما (مثل في الحلول الأخرى) هناك نكون الأرقام السحرية (مثل "اختيار طول أعلى من صندوقك سيكون من أي وقت مضى") ، ليس من المميت إذا كان افتراضك خاطئًا. قد لا يبدو الانتقال مدهشًا في هذه الحالة ، ولكن قبل الانتقال وبعده ، فإن هذه ليست مشكلة: في الموسع (الموسع (height: auto) الحالة ، المحتوى بالكامل لديه دائمًا الارتفاع الصحيح (على عكس EG إذا اخترت أ max-height تبين أن يكون منخفضًا جدًا). وفي الحالة المنهارة ، يكون الارتفاع صفرًا كما ينبغي.

العرض التوضيحي

إليك عرضًا تجريبيًا مع ثلاثة عناصر قابلة للطي ، جميعها من المرتفعات المختلفة ، التي تستخدم جميعها نفس CSS. قد ترغب في النقر فوق "صفحة كاملة" بعد النقر فوق "Run Snippet". لاحظ أن JavaScript يتبديل فقط collapsed فئة CSS ، لا يوجد قياس. (يمكنك القيام بهذا العرض التوضيحي الدقيق دون أي JavaScript على الإطلاق باستخدام مربع اختيار أو :target). لاحظ أيضًا أن جزء CSS المسؤول عن الانتقال قصير جدًا ، وأن HTML لا يتطلب سوى عنصر غلاف إضافي واحد.

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

كيف يعمل؟

في الواقع اثنين التحولات المشاركة في تحقيق هذا. واحد منهم ينتقل margin-bottom من 0px (في الحالة الموسعة) إلى -2000px في الحالة المنهارة (على غرار هذا الجواب). 2000 هنا هو الرقم السحري الأول ، ويستند إلى افتراض أن صندوقك لن يكون أعلى من هذا (يبدو 2000 بكسل اختيارًا معقولًا).

باستخدام margin-bottom الانتقال بمفرده به قضيتان:

  • إذا كان لديك بالفعل صندوق أعلى من 2000 بكسل ، ثم أ margin-bottom: -2000px لن تخفي كل شيء - ستكون هناك أشياء مرئية حتى في الحالة المنهارة. هذا إصلاح بسيط سنفعله لاحقًا.
  • إذا كان المربع الفعلي ، على سبيل المثال ، ارتفاع 1000 بكسل ، ويبلغ انتقالك 300 مللي ثانية ، ثم مرئي انتهى الانتقال بالفعل بعد حوالي 150 مللي ثانية (أو ، في الاتجاه المعاكس ، يبدأ 150 مللي ثانية في وقت متأخر).

إصلاح هذه العدد الثاني هو المكان الذي يأتي فيه الانتقال الثاني ، ويستهدف هذا الانتقال من الناحية النظرية المجمع الحد الأدنى الارتفاع ("من الناحية المفاهيمية" لأننا لا نستخدم فعليًا min-height خاصية لهذا ؛ المزيد عن ذلك لاحقًا).

فيما يلي الرسوم المتحركة التي توضح كيف يعطينا الجمع بين انتقال الهامش السفلي مع انتقال الحد الأدنى للارتفاع ، وكلاهما على قدم المساواة ، انتقالًا مشتركًا من الارتفاع الكامل إلى الارتفاع الصفر الذي له نفس المدة.

animation as described above

يوضح الشريط الأيسر كيف يدفع الهامش السفلي السلبي إلى الأعلى إلى الأعلى ، مما يقلل من الارتفاع المرئي. يوضح الشريط الأوسط كيف يضمن الحد الأدنى للارتفاع أنه في حالة الانهيار ، لا ينتهي الانتقال مبكرًا ، وفي حالة التوسع ، لا يبدأ الانتقال في وقت متأخر. يوضح الشريط الأيمن كيف يتسبب الجمع بين الاثنين في انتقال المربع من الارتفاع الكامل إلى ارتفاع الصفر في مقدار الوقت الصحيح.

بالنسبة إلى العرض التجريبي ، استقرت على 50 بكسل كقيمة الارتفاع الدنيا العليا. هذا هو الرقم السحري الثاني ، ويجب أن يكون أقل من ارتفاع المربع. 50 بكسل يبدو معقولًا أيضًا ؛ يبدو من غير المحتمل أن ترغب غالبًا في جعل عنصرًا قابلاً للطي لا يصل إلى 50 بكسل في المقام الأول.

كما ترون في الرسوم المتحركة ، فإن الانتقال الناتج مستمر ، لكنه غير قابل للتمييز - في الوقت الذي يكون فيه الحد الأدنى للارتفاع يساوي الارتفاع الكامل المعدل بالهامش السفلي ، هناك تغيير مفاجئ في السرعة. هذا ملحوظ للغاية في الرسوم المتحركة لأنه يستخدم وظيفة توقيت خطي لكلا التحولات ، ولأن الانتقال كله بطيء للغاية. في الحالة الفعلية (العرض التوضيحي الخاص بي في الأعلى) ، يستغرق الانتقال 300 مللي ثانية فقط ، والانتقال الهامش السفلي ليس خطيًا. لقد لعبت مع الكثير من وظائف التوقيت المختلفة لكلا التحولات ، وتلك التي انتهيت معها شعرت أنها عملت بشكل أفضل لأوسع مجموعة متنوعة من الحالات.

تبقى مشكلتان لإصلاح:

  1. النقطة من الأعلى ، حيث لا يتم إخفاء صناديق أكثر من 2000 بكسل بالكامل في الحالة المنهارة ،
  2. والمشكلة العكسية ، حيث في الحالة غير المخفية ، تكون صناديق أقل من 50 بكسل عالية جدًا حتى عندما لا يكون الانتقال قيد التشغيل ، لأن الحد الأدنى يحتفظ بها في 50 بكسل.

نحل المشكلة الأولى من خلال إعطاء عنصر الحاوية أ max-height: 0 في الحالة المنهارة ، مع أ 0s 0.3s انتقال. هذا يعني أنه ليس حقًا انتقالًا ، ولكن max-height يتم تطبيقه مع تأخير. ينطبق فقط بمجرد انتهاء الانتقال. لكي يعمل هذا بشكل صحيح ، نحتاج أيضًا إلى اختيار عددي max-height بالنسبة للعكس ، غير ملتزم ، الدولة. ولكن على عكس علبة 2000 بكسل ، حيث يؤثر اختيار عدد كبير جدًا على جودة الانتقال ، في هذه الحالة ، لا يهم حقًا. لذلك يمكننا فقط اختيار رقم مرتفع لدرجة أننا أعرف لن يقترب هذا الارتفاع من هذا. اخترت مليون بكسل. إذا كنت تشعر أنك قد تحتاج إلى دعم محتوى يبلغ ارتفاعه أكثر من مليون بكسل ، ثم 1) أنا آسف ، و 2) فقط إضافة اثنين من الأصفار.

المشكلة الثانية هي السبب وراء عدم استخدامنا بالفعل min-height للحصول على الحد الأدنى لانتقال الارتفاع. بدلا من ذلك ، هناك ::after العنصر الزائف في الحاوية مع أ height أن ينتقل من 50 بكسل إلى صفر. هذا له نفس تأثير أ min-height: لن يدع الحاوية تتقلص أقل من ارتفاع العناصر الزائفة حاليًا. ولكن لأننا نستخدم height, ، ليس min-height, ، يمكننا الآن استخدام max-height (تم تطبيقه مرة أخرى مع تأخير) لتعيين الارتفاع الفعلي للعنصر الزائف إلى الصفر بمجرد انتهاء الانتقال ، مما يضمن على الأقل خارج الانتقال ، حتى العناصر الصغيرة لها الارتفاع الصحيح. لان min-height هو أقوى من max-height, ، هذا لن يعمل إذا استخدمنا الحاوية min-height بدلا من العناصر الزائفة height. مثل max-height في الفقرة السابقة ، هذا max-height يحتاج أيضا إلى قيمة للطرف الآخر من الانتقال. ولكن في هذه الحالة يمكننا فقط اختيار 50 بكسل.

تم اختباره في Chrome (Win ، Mac ، Android ، iOS) ، Firefox (Win ، Mac ، Android) ، Edge ، IE11 (باستثناء مشكلة تخطيط Flexbox مع العرض التوضيحي الخاص بي لم أزعج تصحيح الأخطاء) ، و Safari (Mac ، iOS ). الحديث عن FlexBox ، يجب أن يكون من الممكن جعل هذا العمل دون استخدام أي FlexBox ؛ في الواقع ، أعتقد أنه يمكنك جعل كل شيء تقريبًا يعمل في IE7 - باستثناء حقيقة أنك لن يكون لديك انتقالات CSS ، مما يجعله تمرينًا لا طائل منه.

يمكنك ، مع القليل من jiggery pokery غير الدلالية. تتمثل مقاربي المعتادة في تحريك ارتفاع Div الخارجي الذي لديه طفل واحد وهو Div بدون نمط يستخدم فقط لقياس ارتفاع المحتوى.

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>

يود المرء أن يكون قادرًا على الاستغناء عن .measuringWrapper وقم فقط بتعيين ارتفاع Div على Auto ولديه هذا التحريك ، ولكن يبدو أن هذا لا يعمل (يتم تعيين الارتفاع ، ولكن لا يحدث أي رسوم متحركة).

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>

تفسيري هو أن هناك حاجة إلى ارتفاع واضح للرسوم المتحركة. لا يمكنك الحصول على رسوم متحركة على الارتفاع عندما يكون الطول (ارتفاع أو نهاية الطرف) auto.

يتمثل حل البديل المرئي في ارتفاع الارتفاع باستخدام التحولات CSS3 في تحريك الحشو بدلاً من ذلك.

لا تحصل على التأثير الكامل للمسح ، ولكن يجب أن تتجول لك قيم المدة والانتقال في المدة والانتقال. إذا كنت لا ترغب في ضبط الارتفاع/الارتفاع بشكل صريح ، فيجب أن يكون هذا ما تبحث عنه.

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 فوق JSfiddle)

يتمثل الحل البديل في انتقال أقصى درجة إلى ارتفاع المحتوى الدقيق للرسوم المتحركة اللطيفة اللطيفة ، ثم استخدم رد اتصال انتقالي لضبط الحد الأقصى إلى 9999 بكسل حتى يتمكن المحتوى من تغيير حجمه بحرية.

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>

تعمل الإجابة المقبولة في معظم الحالات ، لكنها لا تعمل بشكل جيد عندما تكون div يمكن أن تختلف اختلافًا كبيرًا في الارتفاع - لا تعتمد سرعة الرسوم المتحركة على الارتفاع الفعلي للمحتوى ، ويمكن أن تبدو متقلبة.

لا يزال بإمكانك إجراء الرسوم المتحركة الفعلية مع CSS ، ولكن تحتاج إلى استخدام JavaScript لحساب ارتفاع العناصر ، بدلاً من محاولة الاستخدام auto. لا يلزم وجود jQuery ، على الرغم من أنك قد تضطر إلى تعديل هذا قليلاً إذا كنت تريد التوافق (يعمل في أحدث إصدار من 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>

يستخدم max-height مع تخفيف انتقال مختلف وتأخير لكل ولاية.

لغة البرمجة:

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

انظر مثال: http://jsfiddle.net/0hnjehjc/1/

لا توجد قيم مشفرة صلبة.

لا جافا سكريبت.

لا تقارب.

الحيلة هي استخدام مخفي ومكرر div للحصول على المتصفح لفهم معنى 100 ٪.

هذه الطريقة مناسبة كلما تمكنت من تكرار DOM للعنصر الذي ترغب في تحريكه.

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

كان هناك القليل من ذكر Element.scrollHeight الخاصية التي يمكن أن تكون مفيدة هنا ويمكن استخدامها مع انتقال CSS النقي. يحتوي الخاصية دائمًا على الارتفاع "الكامل" لعنصر ما ، بغض النظر عما إذا كان محتوىه يفيض نتيجة لارتفاعه المنهار (على سبيل المثال height: 0).

على هذا النحو ، ل height: 0 العنصر (المنهار بالكامل بشكل فعال) ، لا يزال ارتفاعه "الطبيعي" أو "الكامل" متاحًا بسهولة من خلال scrollHeight القيمة (دائما أ بكسل الطول).

لمثل هذا العنصر ، على افتراض أنه قد تم إعداده بالفعل مثل EG (باستخدام ul حسب السؤال الأصلي):

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

يمكننا تشغيل "التوسع" المرغوب في الارتفاع ، باستخدام CSS فقط ، مع شيء مثل ما يلي (هنا على افتراض ul يشير المتغير إلى القائمة):

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

هذا هو. إذا كنت بحاجة إلى انهيار القائمة ، فسيقوم أي من البيانين التاليين:

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

تدور حالتي الاستخدام الخاصة حول قوائم الرسوم المتحركة بأطوال غير معروفة وغالبًا ما تكون كبيرة ، لذلك لم أكن مرتاحًا للاستقرار على "كبير بما يكفي" height أو max-height المواصفات والمخاطرة بمحتوى أو محتوى قطع أو محتوى تحتاج فجأة إلى التمرير (إذا overflow: auto, ، فمثلا). بالإضافة إلى ذلك ، تم كسر التخفيف والتوقيت مع max-heightحلول قائمة على ذلك ، لأن الارتفاع المستخدم قد يصل إلى الحد الأقصى لقيمته في وقت أقرب بكثير مما قد يستغرقه max-height للوصول 9999px. ومع نمو قرارات الشاشة ، مثل الأطوال البكسل مثل 9999px اترك طعمًا سيئًا في فمي. هذا الحل الخاص يحل المشكلة بطريقة أنيقة ، في رأيي.

أخيرًا ، نأمل هنا في حاجة المؤلفين المستقبليين لـ CSS إلى القيام بهذا النوع من الأشياء بشكل أكثر أناقة - إعادة النظر في فكرة القيم "المحسوبة" مقابل "المستخدم" و "الحل" ، والنظر في ما إذا كان يجب أن تنطبق التحولات على المحسوبة على القيم ، بما في ذلك التحولات مع width و height (الذي يحصل حاليًا على بعض المعاملة الخاصة).

أثناء نشر هذا ، هناك أكثر من 30 إجابة بالفعل ، لكنني أشعر أن إجابتي تتحسن بالفعل إجابة مقبولة بقلم جيك.

لم أكن راضيا عن المشكلة التي تنشأ من مجرد استخدام max-height و CSS3 التحولات ، نظرًا لأن العديد من المعلقين لاحظوا ، يجب عليك تعيينك max-height قيمة قريبة جدًا من الارتفاع الفعلي أو ستحصل على تأخير. انظر الى هذا JSfiddle للحصول على مثال على هذه المشكلة.

للالتفاف حول هذا (مع الاستمرار في استخدام أي جافا سكريبت) ، أضفت عنصر HTML آخر ينتقل transform: translateY قيمة CSS.

هذا يعني كلاهما max-height و translateY يستخدم: max-height يسمح للعنصر بدفع العناصر أسفله translateY يعطي التأثير "الفوري" الذي نريده. القضية مع max-height لا يزال موجودًا ، لكن تأثيره يقلل. هذا يعني أنه يمكنك ضبط ارتفاع أكبر بكثير لك max-height القيمة والقلق بشأن ذلك أقل.

الفائدة الكلية هي أنه عند الانتقال مرة أخرى (الانهيار) ، يرى المستخدم translateY الرسوم المتحركة على الفور ، لذلك لا يهم حقًا كم من الوقت max-height يأخذ.

الحل كما كمان

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>

حسنًا ، لذلك أعتقد أنني توصلت إلى إجابة بسيطة للغاية ... لا max-height, ، الاستخدامات relative تحديد المواقع ، يعمل على li عناصر ، و CSS نقية. لم أختبر أي شيء سوى Firefox ، على الرغم من الحكم من قبل CSS ، يجب أن تعمل على جميع المتصفحات.

كمان: http://jsfiddle.net/n5xfg/2596/

CSS

.wrap { overflow:hidden; }

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

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

لغة البرمجة

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

تحرير: قم بالتمرير لأسفل للحصول على إجابة محدثة
كنت أقوم بإجراء قائمة منسدلة ورأيت هذا المنشور ... العديد من الإجابات المختلفة ، لكنني قررت مشاركة قائمة المنسدلة أيضًا ، ... إنها ليست مثالية ولكن على الأقل ستستخدم CSS فقط للمنزل! لقد كنت أستخدم Transform: Translatey (y) لتحويل القائمة إلى العرض ...
يمكنك رؤية المزيد في الاختبار
http://jsfiddle.net/bvepc/4/
لقد وضعت Div خلف كل li لأن قائمة المنسدلة الخاصة بي قادمة من أعلى وإظهار ذلك بشكل صحيح ، كان هذا مطلوبًا ، رمز Div الخاص بي هو:

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

وتحوم:

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

ولأن ارتفاع UL يتم ضبطه على المحتوى ، يمكن أن يتغلب على محتوى جسمك ، ولهذا السبب فعلت هذا مقابل UL:

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

والحرم:

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

المرة الثانية بعد الانتقال هي التأخير وسيتم إخفاءها بعد إغلاق قائمة المنسدلة الخاصة بي ...
آمل لاحقًا أن يستفيد شخص ما من هذا.

تحرير: لا أستطيع أن أصدق PPL بالفعل باستخدام هذا النموذج الأولي! هذه القائمة المنسدلة هي فقط لقائمة فرعية واحدة وهذا كل شيء !! لقد قمت بتحديث قائمة أفضل يمكن أن تحتوي على قائمة فرعية لكل من اتجاه LTR و RTL مع دعم IE 8.
كمان لـ LTR
كمان لـ RTL
نأمل أن يجد شخص ما هذا مفيدًا في المستقبل.

يمكنك الانتقال من الارتفاع: 0 إلى الارتفاع: تلقائيًا شريطة أن تقدم أيضًا ذروتها وارتفاعها.

div.stretchy{
    transition: 1s linear;
}

div.stretchy.hidden{
    height: 0;
}

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

حل Flexbox

الايجابيات:

  • بسيط
  • لا ي
  • الانتقال السلس

سلبيات:

  • يجب وضع العنصر في حاوية مرنة ذات ارتفاع ثابت

الطريقة التي تعمل بها هي دائمًا وجود فليزة: تلقائيًا على العنصر مع المحتوى ، ونمو المرن والرواية المرنة بدلاً من ذلك.

تحرير: تحسين JS Fiddle مستوحى من واجهة Xbox One.

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

أعتقد أنني توصلت إلى حل قوي حقًا

نعم! أعلم أن هذه المشكلة قديمة قدم الإنترنت ، لكنني أعتقد أن لديّ حل تحولت إلى أ البرنامج المساعد يسمى التحول المتحول. الحل الخاص بي يعين style="" سمات للعناصر التي تم تتبعها كلما كان هناك تغيير في DOM. والنتيجة النهائية هي أنه يمكنك استخدام Ole CSS الجيدة للتحولات الخاصة بك وعدم استخدام إصلاحات الاختراق أو JavaScript الخاصة. الشيء الوحيد الذي عليك القيام به هو تعيين ما تريد تتبعه على العنصر المعني باستخدام data-mutant-attributes="X".

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

هذا هو! يستخدم هذا الحل MutationObserver لمتابعة التغييرات في DOM. لهذا السبب ، ليس عليك حقًا إعداد أي شيء أو استخدام JavaScript لتحريك الأشياء يدويًا. يتم تتبع التغييرات تلقائيا. ومع ذلك ، نظرًا لأنه يستخدم MutationObserver ، فإن هذا لن ينتقل إلا في IE11+.

عجلات!

فيما يلي طريقة للانتقال من أي ارتفاع لبدء ، بما في ذلك 0 ، إلى تلقائي (الحجم الكامل ومرن) دون الحاجة إلى رمز ثابت على أساس كل عقدة أو أي رمز مستخدم للتهيئة: https://github.com/csuwildcat/transition-auto. هذا هو في الأساس الكأس المقدسة لما تريد ، على ما أظن -> http://codepen.io/csuwldcat/pen/kwsdf. ما عليك سوى صفع ملف JS التالي في صفحتك ، وكل ما عليك القيام به بعد ذلك هو إضافة/إزالة سمة منطقية واحدة - reveal="" - من العقد التي تريد توسيعها والتعاقد.

إليك كل ما تحتاج إلى القيام به كمستخدم ، بمجرد تضمين كتلة التعليمات البرمجية الموجودة أدناه رمز المثال:

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

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

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

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

إليك كتلة الكود لتضمينها في صفحتك ، بعد ذلك ، كل شيء مرق:

قم بإسقاط ملف JS هذا في صفحتك - كل شيء يعمل فقط ™

/* رمز للارتفاع: السيارات ؛ الانتقال */

(function(doc){

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

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

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

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

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

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

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

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

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

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

})(document);

/* رمز للعروض التجريبية */

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

إجابة جيك على تحريك الذروة القصوى رائعة ، لكنني وجدت التأخير الناجم عن وضع غاية كبيرة في الاضطراب.

يمكن للمرء أن يحرك المحتوى القابل للطي إلى div داخلي وحساب ارتفاع الحد الأقصى عن طريق الحصول على ارتفاع Div الداخلي (عبر jQuery سيكون 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');
});

إليك رابط JSfiddle: http://jsfiddle.net/pbatey/duzpt

إليك JSFIDDLE مع الحد الأدنى المطلق من الكود المطلوب: http://jsfiddle.net/8ncjjxh8/

التوسع في إجابة @Jake ، سوف ينتقل الانتقال إلى قيمة الارتفاع الأقصى ، مما تسبب في رسوم متحركة سريعة للغاية - إذا قمت بتعيين التحولات لكلا: Hover و Off ، يمكنك بعد ذلك التحكم في السرعة المجنونة أكثر قليلاً.

لذا فإن LI: التحوم هو عندما يدخل الماوس إلى الدولة ثم الانتقال على العقار غير المحط سيكون إجازة الماوس.

نأمل أن يكون هذا من بعض المساعدة.

على سبيل المثال:

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

هذا كمان: http://jsfiddle.net/bukwj/

أدرك أن هذا الموضوع أصبح قديمًا ، لكنه يحتل المرتبة العالية في بعض عمليات البحث عن Google ، لذا فأنا أظن أنه يستحق التحديث.

يمكنك أيضًا الحصول على/ضبط ارتفاع العنصر:

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

يجب عليك تفريغ JavaScript هذه مباشرة بعد علامة الإغلاق الخاصة بـ Target_box في علامة نصية مضمنة.

كنت قادرا على القيام بذلك. انا املك .child & أ .parent div. يتلاءم Div الطفل تمامًا ضمن عرض/ارتفاع الوالد مع absolute التمركز. ثم أقوم بتحريك translate خاصية لدفعها Y القيمة لأسفل 100%. الرسوم المتحركة السلسة للغاية ، لا توجد مواطن الخلل أو الجوانب لأسفل مثل أي حل آخر هنا.

شيء من هذا القبيل ، رمز الزائفة

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

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

ستحدد أ height على .parent, ، في px, %, ، أو اترك auto. هذا div ثم يحجب .child DIV عندما تنزلق لأسفل.

إليك الحل الذي استخدمته للتو مع jQuery. هذا يعمل من أجل بنية HTML التالية:

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

والوظيفة:

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

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

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

يمكنك بعد ذلك استخدام وظيفة النقر لتعيين وإزالة الارتفاع باستخدام css()

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

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

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

CSS:

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

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

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

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

لقد قمت مؤخرًا بنقل max-height على ال li عناصر بدلاً من الالتفاف ul.

المنطق هو أن التأخير للشكل الصغير max-heights هو أقل وضوحا بكثير (إن وجدت) مقارنة بالكبير max-heights, ، ويمكنني أيضًا ضبط بلدي max-height القيمة بالنسبة إلى font-size التابع li بدلا من عدد ضخم تعسفي باستخدام ems أو rems.

إذا كان حجم الخط الخاص بي 1rem, ، سأقوم بتعيين بلدي max-height لشيء مثل 3rem (لاستيعاب النص ملفوف). يمكنك الاطلاع على مثال هنا:

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

لم أقرأ كل شيء بالتفصيل ، لكنني واجهت هذه المشكلة مؤخرًا وفعلت ما يلي:

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

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

يتيح لك ذلك أن يكون لديك div يظهر في البداية محتوى يصل إلى 200 بكسل ، وعلى حومه ، يصبح حجمه على الأقل مثل المحتوى الكامل لـ Div. لا يصبح DIV 3000 بكسل ولكن 3000 بكسل هو الحد الذي فرضه. تأكد من الانتقال إلى Non: Hover ، وإلا فقد تحصل على بعض التقديم الغريب. وبهذه الطريقة: يرث التحوم من غير: تحوم.

الانتقال لا يعمل شكل px إلى ٪ أو إلى Auto. تحتاج إلى استخدام نفس وحدة القياس. هذا يفي بالغرض بالنسبة لي. باستخدام HTML5 يجعلها مثالية ....

تذكر أن هناك دائمًا عمل حول ... ؛ )

أملي أن يجد هذا نفعا

هذا ليس بالضبط "حل" للمشكلة ، ولكن أكثر من الحل البديل. إنه يعمل فقط على النحو المكتوب بنص ، ولكن يمكن تغييره للعمل مع عناصر أخرى حسب الحاجة ، أنا متأكد.

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

هنا مثال: http://codepen.io/overthemike/pen/wzjrka

في الأساس ، قمت بتعيين حجم الخط على 0 والانتقال أنه بدلاً من الارتفاع ، أو الحد الأقصى ، أو Scaleyy () وما إلى ذلك بوتيرة سريعة بما فيه الكفاية للحصول على الارتفاع لتحويل إلى ما تريد. لتحويل الارتفاع الفعلي باستخدام CSS إلى Auto غير ممكن حاليًا ، ولكن تحويل المحتوى داخل هو ، وبالتالي انتقال حجم الخط.

  • ملاحظة - هناك javaScript في CodePen ، ولكن الغرض فقط هو إضافة/إزالة فئات CSS عند النقر على الأكورديون. يمكن القيام بذلك باستخدام أزرار الراديو المخفية ، لكنني لم أركز على ذلك ، فقط تحول الارتفاع.

أنا أفهم السؤال يسأل عن حل بدون جافا سكريبت. ولكن بالنسبة لأولئك المهتمين هنا ، فإن الحل الخاص بي باستخدام القليل من JS.

حسنًا ، لذلك يتم تعيين CSS للعنصر الذي سيتغير ارتفاعه افتراضيًا height: 0; وعندما تفتح height: auto;. لديها أيضا transition: height .25s ease-out;. لكن المشكلة بالطبع هي أنها لن تنتقل إلى أو من height: auto;

إذن ما فعلته هو عند فتح أو إغلاق ضبط الارتفاع على scrollHeight خاصية العنصر. سيكون لهذا النمط المضمن الجديد خصوصية أعلى وتجاوز كليهما height: auto; و height: 0; والانتقال يعمل.

عند فتح أضف أ transitionend مستمع الحدث الذي سيتم تشغيله مرة واحدة فقط ثم قم بإزالة النمط المضمن الذي يعيده إلى height: auto; مما سيسمح للعنصر بتغيير حجمه إذا لزم الأمر ، كما هو الحال في هذا المثال الأكثر تعقيدًا مع القوائم الفرعية https://codepen.io/ninjabonsai/pen/gzyyve

عند الإغلاق ، أقوم بإزالة النمط المضمّن مباشرة بعد التالي حلقة الحدث دورة باستخدام setTimeout مع عدم وجود تأخير. هذا يعنى height: auto; يتم تجاوزه مؤقتًا والذي يسمح بالعودة إلى height 0;

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

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

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

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

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

Max-height الحل من جيك يعمل بشكل جيد ، إذا كان الثابت تلوينها أقصى ارتفاع قيمة الموردة ليست أكبر بكثير من الارتفاع الحقيقي (لأن خلاف ذلك هناك غير مرغوب فيه تأخير توقيت مشاكل).من ناحية أخرى إذا كان الثابت تلوينها قيمة accidentially هو ليس أكبر من الارتفاع الحقيقي عنصر لن تفتح تماما.

التالية CSS فقط الحل يتطلب أيضا الثابت تلوينها حجم يجب أن يكون أكبر من معظم من تحدث الحقيقي الأحجام.ومع ذلك هذا الحل يعمل أيضا إذا كان الحجم الحقيقي هو في بعض الحالات أكبر من الثابت تلوينها الحجم.في هذا الحدث الانتقال قد القفز قليلا ، لكنها لن تترك مرئية جزئيا عنصر.حتى هذا الحل يمكن أن تستخدم أيضا مجهولة المحتوى ، مثلمن قاعدة البيانات, حيث أنك تعرف أن المحتوى هو عادة ليست أكبر من x بكسل ، ولكن هناك استثناءات.

الفكرة هو استخدام سلبي قيمة الهامش السفلي (أو هامش قمة لمجموعة قليلا diffenrent الرسوم المتحركة) ووضع عنصر المحتوى في وسط عنصر مع overflow:hidden.السلبية هامش المحتوى عنصر حتى يقلل من ارتفاع عنصر الوسط.

التعليمة البرمجية التالية يستخدم الانتقال على الهامش السفلي من 150px إلى 0px.هذا وحده يعمل بشكل جيد طالما أن عنصر المحتوى لا أعلى من 150px.وبالإضافة إلى ذلك فإنه يستخدم الانتقال على ماكس-ارتفاع وسط عنصر من 0px إلى 100%.هذا أخيرا يخفي عنصر الوسط إذا كان المحتوى عنصر أعلى من 150px.أقصى ارتفاع الانتقال إلى تأخير تطبيقه قبل الثانية عندما الختام لا السلس visiual تأثير ( وبالتالي فإنه يمكن تشغيلها من 0px إلى 100%).

CSS:

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

HTML:

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

قيمة الهامش السفلي يجب أن تكون سلبية و أقرب ممكن الحقيقي ارتفاع عنصر المحتوى.إذا كان('s absoute القيمة) هو أكبر هناك مماثلة تأخير توقيت مشاكل مع max-height الحلول التي يمكن أن تكون محدودة طالما الثابت ترميز حجم أكبر بكثير من واحد حقيقي.إذا كان المطلق قيمة الهامش السفلي أصغر من الحقيقي ارتفاع tansition يقفز قليلا.في أي حال بعد انتقال عنصر المحتوى إما عرض كامل أو إزالتها تماما.

لمزيد من التفاصيل انظر بلدي بلوق وظيفة http://www.taccgl.org/blog/css_transition_display.html#combined_height

يبدو أنه لا يوجد حل مناسب. max-height النهج جيد جدًا ولكنه لا يعمل بشكل جيد في مرحلة الاختباء - سيكون هناك تأخير ملحوظ إلا إذا كنت تعرف ارتفاع المحتوى.

أعتقد أن أفضل طريقة هي الاستخدام max-height لكن فقط لمرحلة العرض. وليس لاستخدام أي رسوم متحركة على الاختباء. بالنسبة لمعظم الحالات ، لا ينبغي أن تكون حاسمة.

max-height يجب ضبطها على قيمة ضخمة لضمان تناسب أي محتوى. يمكن التحكم في سرعة الرسوم المتحركة باستخدام transition المدة الزمنية (speed = max-height / duration). لا تعتمد السرعة على حجم المحتوى. يعتمد الوقت الذي يستغرقه إظهار المحتوى بالكامل على حجمه.

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

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top