Как я могу перейти высоту: 0;по высоте: авто;используя CSS? - PullRequest
1874 голосов
/ 18 августа 2010

Я пытаюсь заставить <ul> скользить вниз, используя CSS-переходы.

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

Ответы [ 45 ]

6 голосов
/ 09 июля 2013

Расширяя ответ @ jake, переход будет проходить до максимального значения высоты, вызывая очень быструю анимацию - если вы установите переходы для обоих: hover и off, вы можете затем контролировать сумасшедшую скорость немного больше.

Таким образом, li: hover - это когда мышь входит в состояние, а затем переходом к свойству non-hovered будет уход мыши.

Надеюсь, это поможет.

например:

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

5 голосов
/ 14 марта 2014

Я смог это сделать. У меня есть .child & .parent 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, когда он скользит вниз.

5 голосов
/ 27 мая 2011

Я понимаю, что этот поток стареет, но он занимает высокие позиции в определенных поисках Google, поэтому я думаю, что стоит обновить.

Вы также просто получаете / устанавливаете собственную высоту элемента:

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

Вы должны сбросить этот Javascript сразу после закрывающего тега target_box во встроенном теге скрипта.

4 голосов
/ 03 ноября 2011

Вот решение, которое я только что использовал в сочетании с 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 }
4 голосов
/ 13 мая 2014

Я недавно перенес 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

3 голосов
/ 07 марта 2013

Я не прочитал все подробно, но у меня недавно была эта проблема, и я сделал следующее:

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 не становится 3000px, но 3000px - это предел, который я навязываю.Убедитесь, что у вас есть переход на non: hover, иначе вы можете получить странный рендеринг.Таким образом,: hover наследуется от non: hover.

Переход не работает с px на% или на авто.Вам нужно использовать ту же единицу измерения.Это прекрасно работает для меня.Использование HTML5 делает его идеальным ....

Помните, что всегда есть обходной путь ...;)

Надеюсь, кто-нибудь найдет это полезным

3 голосов
/ 15 февраля 2019

Я понимаю, что вопрос требует решения без JavaScript. Но для тех, кто заинтересован, вот мое решение, использующее немного 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>
3 голосов
/ 12 октября 2016

Это не совсем «решение» проблемы, а скорее обходной путь.Он работает только так, как написано с текстом, но может быть изменен для работы с другими элементами по мере необходимости.

.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 и измените его вместо высоты, или максимальной высоты, или масштаба Y () и т. д. в достаточно быстром темпе, чтобы высота трансформировалась в то, что вы хотите.Преобразовать фактическую высоту с помощью CSS в автоматический в настоящее время невозможно, но преобразование содержимого внутри, следовательно, означает переход размера шрифта.

  • Примечание. В коде есть IS javascript, но это толькоЦель состоит в том, чтобы добавить / удалить классы CSS по клику для аккордеона.Это можно сделать с помощью скрытых переключателей, но я не сосредоточился на этом, только на преобразовании высоты.
2 голосов
/ 24 марта 2017

Кажется, нет правильного решения.Подход max-height довольно хорош, но не подходит для фазы скрытия - будет заметная задержка, если вы не знаете высоту содержимого.

Я думаю, что лучше всего использовать max-height, но только для фазы показа .И не использовать никакой анимации при сокрытии.Для большинства случаев это не должно быть решающим.

max-height должно быть установлено на довольно большое значение, чтобы обеспечить любой контент подходит.Скорость анимации можно регулировать с помощью transition duration (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>
2 голосов
/ 08 августа 2014

Максимальная высота решения от Джейка работает хорошо, если жестко значение максимальной высоты не намного больше реальной высоты (потому что в противном случае возникают нежелательные задержки и проблемы со временем). С другой стороны, если жестко закодированное значение случайно не больше реальной высоты, элемент не открывается полностью.

Следующее решение только для CSS также требует жесткого размера, который должно быть больше, чем большинство реальных размеров. Однако это Решение также работает, если реальный размер в некоторых ситуациях превышает жестко закодированный размер. В этом случае переход может немного подскочить, но он никогда не оставит частично видимый элемент. Таким образом, это решение также может быть использовано для неизвестного контента, например, от база данных, где вы просто знаете, что контент обычно не больше чем х пикселей, но есть исключения.

Идея состоит в том, чтобы использовать отрицательное значение для поля на полях (или поле на полях для слегка отличная анимация) и поместить элемент содержимого в средний элемент с переполнением: скрытый. Отрицательное поле контента элемент так уменьшает высоту среднего элемента.

В следующем коде используется переход на полях с -150px на 0px. Это само по себе работает нормально, пока элемент содержимого не выше 150px. Кроме того, он использует переход на максимальную высоту для средний элемент от 0px до 100%. Это, наконец, скрывает средний элемент если элемент содержимого выше 150px. Для максимальной высоты переход используется только для отсрочки его применения. на секунду при закрытии, не для плавного визуального эффекта ( и поэтому он может работать от 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>

Значение для нижнего поля должно быть отрицательным и как можно ближе возможно до реальной высоты элемента содержимого. Если оно (абсолютное значение) больше, есть такие же проблемы с задержкой и временем решения максимальной высоты, которые, однако, могут быть ограничены до тех пор, пока жестко закодированный размер не намного больше реального. Если абсолют значение для поля-дна меньше, чем реальная высота переход немного подпрыгивает. В любом случае после перехода элемент содержимого либо полностью отображается, либо полностью удален.

Подробнее см. В моем блоге http://www.taccgl.org/blog/css_transition_display.html#combined_height

...