Питання Як я можу перейти на висоту: 0; до висоти: авто; використовуючи CSS?


Я намагаюся зробити <ul> ковзати вниз за допомогою CSS-переходів.

The <ul> починається з height: 0;. На навігації встановлено висоту height:auto;. Однак це викликає просто виникнення ні перехід

Якщо я це роблю height: 40px; до height: auto;, то він буде ковзати до height: 0;, а потім раптово перестрибнути до правильної висоти.

Як ще я можу це зробити без використання 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>


1602
2017-08-18 02:50


походження


Я вірю в це height:auto/max-height рішення буде працювати тільки якщо ви розширюєте область більше, ніж height ви хочете обмежити Якщо у вас є max-height від 300px, але спадне меню комбінації, яке може повернутись 50px, потім max-height не допоможе тобі, 50px змінна залежно від кількості елементів, ви можете прийти до неможливої ​​ситуації, коли я не можу це виправити через те, що height не фіксується height:auto це рішення, але я не можу використовувати переходи з цим. - Christopher Thomas
OP намагається використовувати рішення css, а не js, інакше вони можуть просто використовувати переповнення та анімацію - Toni Leigh
@ ToniLeigh або jQuery.slideToggle (); - mopo922
Всі ці відповіді не зовсім "правильні" .... У мене є рішення (додано відповідь сьогодні) лише з двома деклараціями CSS. Макс-висота не використовується. Це чистий CSS і надзвичайно простий в налаштуванні. Працює на відносному позиціонуванні. Ось скрипка jsfiddle.net/n5XfG/2596 - VIDesignz
@ VIDesignz: Але внутрішній div's -100% маржа-топ отримує ширина обгортки div не висота Отже, це рішення має таку ж проблему, що рішення максимального рівня. Крім того, якщо ширина менша за висоту вмісту, не весь вміст приховано на -100% маржі-вершини. Отже, це неправильне рішення. - GregTom


Відповіді:


Використовуйте max-height в перетворенні і ні height. І встановити значення на max-height до чогось більшого, ніж твій ящик.

Побачити JSFiddle демо наданий Крісом Джорданом в іншому відповісти тут

#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



це чудово працює! за винятком є ​​затримка, коли вона починається, тому що вона починається з max-height, яка спочатку дуже висока..мм, я думаю, це трохи дратує - vsync
+1 Відмінне рішення! Швидкість переходу обчислюється як час, який ви вказали для переходу до значення максимального значення ... але оскільки висота буде меншою за макс-висоту, перехід до фактичної висоти буде відбуватися швидше (часто значно), ніж вказаний час - kingjeffrey
Зауважте, що це може призвести до закінчення негарного переходу, коли вам потрібно використовувати значення, які значно перевищують фактичне обчислене значення. Я помітив це, намагаючись зробити роздільну здатність зростати з 0 висоти до висоти вмісту, що сильно відрізняється за різними розмірами екрана (2 рядки на моєму 2560x1440 моніторі та> 10 рядків на смартфоні). Для цього я в кінцевому підсумку йду з JS. - jpeltoniemi
Велика робота - не рішення;) - acSlater
Це досить ліниве рішення. Я припускаю, що OP хоче використовувати висоту: автоматично, тому що розширена висота контейнера є дещо непередбачуваною. Це рішення призведе до затримки, перш ніж анімація стане видимою. Крім того, видима тривалість анімації буде непередбачуваною. Ви отримаєте набагато більш прогнозовані (і, імовірно, гладкіші) результати, обчисливши об'єднану висоту кожного з контейнерів дочірніх вузлів, а потім зменшивши їх до точного значення висоти. - Shawn Whinnery


Замість цього слід використовувати масштаб.

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, http://jsfiddle.net/dotnetCarpenter/PhyQc/9/ і змінив jsfiddle, щоб використовувати масштаб, а не висоту, http://jsfiddle.net/dotnetCarpenter/7cnfc/206/.


228
2018-06-23 10:57



Я оновлюю цю відповідь, оскільки вона добре працює в браузерах із підтримкою CSS3, але слід зазначити, що це не буде працювати зовсім в IE <9, і Не буде анімований (це буде просто стрибати) в IE <10 - Hailwood
Цей метод лише частково досягає бажаного ефекту, але насправді це не робить видалити простір. Трансформована коробка діє як відносно розташований елемент - простір береться незалежно від того, як він масштабується. Перевірити це jsFiddle який приймає ваш перший і просто додає деякі фальшиві тексти внизу. Зверніть увагу, як текст під ним не рухається вгору, коли висота вікна масштабується до нуля. - animuson♦
Тепер це: jsfiddle.net/gNDX3/1 У принципі, ви повинні стилісти свої елементи відповідно до того, що вам потрібно. Немає срібної кулі чи віджету, як поведінка в CSS / HTML. - dotnetCarpenter
Хоча я аплодую когось, хто намагається використовувати різні підходи, ефект реального життя та ускладнення, яке це рішення приносить, є набагато гіршим, ніж той, що вже зненацька зламав максимально висоту. Будь ласка, не використовуйте. - mystrdat
Відстань між пробілами jsfiddle.net/PhyQc/336 - e-info128


Ви не можете нарешті анімувати на висоті, якщо на ньому є одна з висот auto, ви повинні встановити дві явні висоти.


164
2017-08-18 12:46



Зазвичай існує декілька способів вирішення проблеми, і не всі вони є доцільними або можливими. Я не знаю чому @ JedidiahHurt та Ryan Ore намагаються обмежити можливі відповіді на Q & A сайті. Особливо враховуючи, що ця відповідь була тут першою. Узагальнено, тому що прийнята відповідь - це шлях до вирішення проблеми. - Hooray Im Helping
Відповідь від @jake не є ні елегантною, ні правильною. Відповідна відповідь тут набагато краще. Він працює правильно і обробляє всі випадкові розміри - також не можна сказати про прийняту відповідь. - GraphicsMuncher
Чи змінилося це? У завантажувачі менше для руйнувань, я бачу, що вони явно переміщують висоту, і, наскільки я знаю, вона пристосовується до будь-якої висоти: .collapsing { position: relative; height: 0; overflow: hidden; .transition-property(~"height, visibility"); .transition-duration(.35s); .transition-timing-function(ease); } - Andy
О, ви знаєте, я впевюю, що завантажувальний стовпець просто обчислює і встановлює висоту вмісту прямо перед активацією анімації CSS ... - Andy
Так: це робить this.$element[dimension](this.$element[dimension]())[0].offsetHeight - Andy


Рішення, яке я завжди використовував, було спочатку зникати, а потім скоротити його 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;
}

Робочий приклад:

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



Працював акуратно для мене. Не зовсім подобається jQuery slideUp / Down. Ви можете бачити різницю лише з слабким центральним процесором, наприклад старими комп'ютерами або мобільними пристроями, і відкриваючи та закриваючи багато з них одночасно. - Cruz Nunez
Якщо у вас є кнопки або будь-які інші нетекстові елементи, ви потрапляєте в небажаний пробіл, поки не зависне. - Dennis W
Ви можете покращити його, вибравши всі дочірні елементи з * та застосування інших змін. Кнопки повинні були вплинути на мій вище код, однак, якщо вони були правильно стилізовані em. - Steven Vachon
У моєму випадку мені також потрібно було додати line-height: 0; і border-width: 0; - Andrey Shatilov
Вам не треба пристосовуватися line-height якщо ви правильно уникаєте одиниць вартості: developer.mozilla.org/en-US/docs/Web/CSS/... - Steven Vachon


Ви можете, з трохи несемантичного джиггер-покер. Мій звичайний підхід - це анімувати висоту зовнішнього 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 на авто і мати цей анімаційний, але це, здається, не працює (висота встановлюється, але анімація не відбувається).

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.


64
2018-06-30 13:32



Оскільки це покладається на JavaScript, ви також можете легко додати вимірювальний верстат за допомогою javascript теж! - Quickredfox
Ви можете зробити це без обгортки. Просто: функція growDiv () {var growDiv = document.getElementById ('grow'); якщо (growDiv.clientHeight) {growDiv.style.height = 0; } else {growDiv.style.height = growDiv.scrollHeight + 'px'; }} - user1742529
Перевірте це ... поговоримо про просту відповідь jsfiddle.net/n5XfG/2596 ... Ваша відповідь безглуздо складна без вагомих причин. Не потрібно max-height, не потрібно auto, і особливо немає потреби в Javascript !! Лише дві прості декларації - VIDesignz
@VIDesignz Ви анімуєте над маржі: 100%. Це 100% від ширина елемента, а не його висота! Це означає, що якщо у вас є елемент із шириною більшого, це не приховує його. Крім того, фактичний Швидкість анімації абсолютно відрізняється від того, що визначено. - Timo Türschmann
Я був в захваті від відповіді VIDesignz, поки не прочитав більше про коментар Тимо. так, margin-top (і margin-bottom) відносяться до ширини, коли вони визначаються у відсотках, так, це нерозумно, але це також пояснює, чому відкриті та закриті синхронізації анімації абсолютно різні - це те ж саме, що ви бачите у найвищому рейтингу, вказавши жорстко закодований макс. висота Чому так важко правильно робити? - Coderer


Я знаю, що це тридцять-тотонна відповідь на це питання, але я думаю, що це варто, так що тут іде. Це CSS-only рішення з наступними властивостями:

  • На початку немає затримки, і перехід не зупиняється рано. У обох напрямках (розгортання та згортання), якщо ви вкажете тривалість переходу в CSS у 300мс, то перехід займає 300мс, період.
  • Це перехід фактичної висоти (на відміну від transform: scaleY(0)), тому він робить правильну дію, якщо є вміст після розбірного елемента.
  • Хоча (як і в інших рішеннях) є є магічні цифри (наприклад, "вибрати довжину, яка вище, ніж ваша коробка, коли-небудь буде"), це не є фатальним, якщо ваше припущення закінчиться неправильним. Перехід може виглядати незрозумілим у цьому випадку, але до і після переходу це не проблема: у розширеному (height: auto) стан, весь зміст завжди має правильний висоту (на відміну від, наприклад, якщо вибрати max-heightщо виявиться занадто низьким). І в обваленому стані, висота дорівнює нулю, як треба.

Демонстрація

Ось демонстрація з трьома складними елементами, різними висотами, які використовують однакові CSS. Можна натиснути кнопку "повна сторінка" після натискання "запустити фрагмент". Зверніть увагу, що 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 від 0 пікселів (у розширеному стані) до -2000px в обваленому стані (схоже на ця відповідь) У 2000 році це перший магічний номер, він грунтується на припущенні, що ваша коробка не буде вищою за цей (2000 пікселів, здається, як розумний вибір).

Використовуючи margin-bottom Перехід сам по собі має два питання:

  • Якщо у вас дійсно є коробка, яка перевищує 2000 пікселів, то а margin-bottom: -2000px не сховатиме все - там буде видимий матеріал навіть у згорнутому випадку. Це невеликий виправлення, яке ми зробимо пізніше.
  • Якщо фактична коробка є, скажімо, висотою 1000 пікселів, і ваш перехід триває 300 мс, то видимий перехід вже закінчився після приблизно 150 мс (або, у зворотному напрямку, починається 150 мс пізно).

Виправлення цієї другої проблеми полягає в тому, де відбувається другий перехід, і цей перехід концептуально націлений на обгортку мінімум висота ("концептуально", тому що ми насправді не використовуємо min-height майно для цього; детальніше про це пізніше).

Ось анімація, яка показує, як поєднання переходу нижнього краю з мінімальним переміщенням висоти, обидва однакової тривалості, дає нам комбінований перехід від повної висоти до нульової висоти, що має однакову тривалість.

animation as described above

Лівий стовпчик показує, як негативний край нижньої частини натискає нижню частину вгору, зменшуючи видиму висоту. Середній рядок показує, як мінімальна висота гарантує, що в випадку згортання перехід не закінчується рано, а в розширеному випадку перехід не починається пізно. На правій панелі показано, як комбінація двох причин перемикає поле з повної висоти до нульової висоти у правильному обсязі часу.

Для моєї демонстрації я встановив значення 50 пікселів як мінімальне значення висоти. Це другий магічний номер, і воно повинно бути нижчим, ніж висота вікна. 50px видається розумним; вам здається малоймовірним, що ви дуже часто хочете скласти складений елемент, який, по-перше, навіть не перевищує 50 пікселів.

Як ви бачите в анімації, перехід, що виникає, є безперервним, але він не є диференційованим - у той момент, коли мінімальна висота дорівнює повній висоті, налаштованій на нижній край, відбувається раптова зміна швидкості. Це дуже помітно в анімації, оскільки він використовує лінійну функцію синхронізації для обох переходів, а також весь перехід дуже повільний. У фактичному випадку (моя демонстрація у верхній частині), перехід займає всього 300 мс, а перехід нижнього поля не є лінійним. Я грав навколо з великою кількістю різних функцій синхронізації для обох переходів, і ті, які я опинився, відчували, що вони найкраще працюють для найрізноманітніших випадків.

Два проблеми залишаються для вирішення:

  1. точка згори, де коробки висотою більше 2000 пікселів не повністю приховані в згорнутому стані,
  2. і зворотна проблема, де в невикритому випадку коробки розміром менше 50 пікселів занадто високі, навіть коли перехід не працює, оскільки мінімальний висота зберігає їх у 50 пікселів.

Ми вирішили першу проблему, вказавши контейнерний елемент a max-height: 0 в обваленій справі, з a 0s 0.3s перехід Це означає, що це не дійсно перехід, але max-height застосовується з затримкою; це застосовується лише після завершення переходу. Щоб це правильно працювало, нам також потрібно вибрати числовий max-height для протилежного, не руйнується, держава. Але на відміну від випадку 2000px, коли збирання занадто великої кількості впливає на якість переходу, у цьому випадку воно насправді не має значення. Таким чином, ми можемо просто вибрати номер, який настільки високий, що ми знати що висота ніколи не наблизиться до цього. Я вибрав мільйон пікселів. Якщо ви відчуваєте, що вам може знадобитися підтримка вмісту висоти більше мільйона пікселів, тоді 1) вибачте, а 2) просто додайте кілька нулів.

Друга проблема - це причина, чому ми насправді не використовуємо min-height для мінімального перемикання висоти. Замість цього існує ::after псевдоелемент у контейнері з a 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 переходів, що робить це досить безглуздою фізичною активністю.


45
2018-05-14 14:33



Бажаю, щоб ви могли скоротити (спростити) ваше рішення або, принаймні, приклад коду - схоже, що 90% прикладу коду не стосується вашої відповіді. - Gil Epshtain


Візуальний шлях до анімації висоти з використанням 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/ (з рифленою зіркою вище jsFiddle)


44
2018-06-26 19:05



Я думаю, що це найкраща відповідь. Ця методика може поширюватися і на регулювання подушек у дітей. У моєму випадку я зміг поєднати його з явними перемиканнями висот на деякий вміст, який виявляється, і загальний ефект набагато успішніший, ніж робота навколо максимуму висоти, що добре для виявлення, але вносить незручний момент затримати ховатися. Я б раніше не анімувати, аніж додавати безглузду затримку, що змушує моє додаток не реагувати. Я здивований тим, що багато людей думають, що це прийнятно. - Semicolon
Крім того, тут ви не анімуєте висоту взагалі. Ви анімуєте заповнення ... він може зникнути просто добре, тому що він може анімувати з поточного стану до 0, але якщо ви уважно стежите, коли він розширюється, він відкривається разом з текстом, а потім заповнення тільки анімується .. тому що це не Не знаю, як анімувати від 0 до автоматичного .... йому потрібен числовий діапазон ... ось як працює tweening. - Rob R
Це хороший шлях, який не є нерозумним. Це не найкраща відповідь це Питання, але це альтернатива, яка працювала для мене. Іноді ви просто потребуєте ефекту деякої анімації висоти, а не повної анімації :) - Ivan Durst
Таке рішення також не працює, якщо використовується затримка переходу. - Michel Joanisse
Я також погоджуюсь з тим, що це рішення є чистим рішенням, яке забезпечує досить перемінні переходи, якщо ваша анімація досить швидко (у моєму випадку для аккордеону з переходами з 0.1 с, це ідеально!). Хоча це не призведе до великої кількості додатків, але й інші сторони цього питання не зможуть! - Remi D


Моїм рішенням є перехід максимального висоти до точної висоти вмісту для гарної гладкої анімації, а потім використовуйте функцію зворотного виклику переходу End, щоб встановити максимальну висоту до 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>


43
2018-03-19 00:44



@ Derija93 Використовується звичайна стара анімація часу очікування JavaScript. Завдання полягає в тому, щоб використовувати переходи CSS3. - Adam
Ну, так. Але чому б ви використали "переходи CSS3" замість цього? Якщо ви вже у своєму прикладі вже використовуєте jQuery, бібліотеку, яка в будь-якому випадку забезпечує багато коду "писати менше, робити більше"? Я хотів би зазначити, що ваша версія може виглядати набагато краще, хоча і складнішою, якщо вона не використовує jQuery, тож вона може працювати практично на будь-якому веб-сайті. Я здогадуюсь, що я так сильно не правильно написав. Вибачте, що так. ;) - Kiruse
@ Derija93 Можливо, тому що переходи CSS3 мають (за даними всіх джерел я можу знайти) набагато кращу продуктивність, ніж анімації jQuery. (Насправді має величезне значення для мого поточного випадку використання, яке привело мене сюди.) - Mark Amery
@ Derija93 '. Через те, що анімації Javascript працюють повільно, порівняно з переходами CSS3, і з анімацією jQuery ви повинні турбуватися про цикл анімації. Анімовай щось натисканням, потім швидко натисніть і подивіться, як анімації повторюються. Це обробляється CSS3. - Dropped.on.Caprica
@ Dropped.on.Caprica Це трохи старе зараз. Я вже сказав, що я неправильно зрозумів концепцію, яку він намагався продемонструвати. У будь-якому випадку, для простої анімації .stop робить трюк для досить складної задачі циклу анімації. Тепер, коли ви анімуєте висоту і колір, але хочете перервати лише анімацію висоти, речі стають трохи складніше ... Я ваша точка зору. - Kiruse