Pregunta ¿Cómo puedo hacer una transición de altura? 0; a la altura: auto; usando CSS?


Estoy tratando de hacer un <ul> deslice hacia abajo usando transiciones de CSS.

los <ul> comienza en height: 0;. En vuelo estacionario, la altura está configurada para height:auto;. Sin embargo, esto está causando que simplemente aparezca, no transición,

Si lo hago desde height: 40px; a height: auto;, luego se deslizará hacia arriba height: 0;, y luego saltar de repente a la altura correcta.

¿De qué otra manera podría hacer esto sin usar 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>


1594
2017-08-18 02:50


origen


Respuestas:


Utilizar max-height en la transformación y no height. Y establecer un valor en max-height a algo más grande que tu caja alguna vez llegue.

Ver Demostración de JSFiddle proporcionado por Chris Jordan en otro responder aquí.

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


2157
2017-11-30 18:42



Deberías usar scaleY en su lugar.

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

He hecho una versión prefijada del proveedor del código anterior en jsfiddle, http://jsfiddle.net/dotnetCarpenter/PhyQc/9/ y cambió su jsfiddle para usar scaleY en lugar de height, http://jsfiddle.net/dotnetCarpenter/7cnfc/206/.


228
2018-06-23 10:57



Actualmente no puede animar en altura cuando una de las alturas involucradas es auto, debes establecer dos alturas explícitas.


164
2017-08-18 12:46



La solución que siempre he usado fue primero desvanecerse, luego reducir el tamaño font-size, padding y margin valores. No se ve igual que una toallita, pero funciona sin una estática height o 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;
}

Ejemplo de trabajo:

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



Puedes, con un poco de jiggery-pokery no semántico. Mi enfoque habitual es animar la altura de un DIV externo que tiene un solo hijo que es un DIV sin estilo utilizado solo para medir la altura del contenido.

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>

A uno le gustaría simplemente poder prescindir del .measuringWrapper y simplemente configure la altura del DIV en automático y tenga esa animación, pero eso no parece funcionar (la altura se establece, pero no se produce animación).

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>

Mi interpretación es que se necesita una altura explícita para que se ejecute la animación. No puede obtener una animación de altura cuando cualquiera de las alturas (la altura inicial o final) es auto.


64
2018-06-30 13:32



Sé que esta es la respuesta trigésima a esta pregunta, pero creo que vale la pena, así que aquí va. Esto es un Solo CSS solución con las siguientes propiedades:

  • No hay demora al principio, y la transición no termina temprano. En ambas direcciones (expandiéndose y contrayéndose), si especifica una duración de transición de 300ms en su CSS, la transición tarda 300ms, punto.
  • Está en transición la altura real (a diferencia transform: scaleY(0)), por lo que hace lo correcto si hay contenido después del elemento colapsable.
  • Mientras (como en otras soluciones) hay son los números mágicos (como "elegir una longitud que sea superior a la que su caja alguna vez va a tener"), no es fatal si su suposición termina siendo incorrecta. La transición puede no parecer increíble en ese caso, pero antes y después de la transición, esto no es un problema: en el expandido (height: auto) state, todo el contenido siempre tiene la altura correcta (a diferencia, por ejemplo, si elige un max-heightque resulta ser demasiado bajo). Y en el estado colapsado, la altura es cero como debería.

Manifestación

Aquí hay una demostración con tres elementos plegables, todos de diferentes alturas, que usan el mismo CSS. Es posible que desee hacer clic en "página completa" después de hacer clic en "ejecutar fragmento". Tenga en cuenta que el JavaScript solo cambia el collapsed Clase CSS, no hay medida involucrada. (Puede hacer esta demostración exacta sin ningún JavaScript utilizando una casilla de verificación o :target) También tenga en cuenta que la parte del CSS que es responsable de la transición es bastante corta, y el HTML solo requiere un único elemento contenedor adicional.

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

¿Como funciona?

De hecho, hay dos transiciones involucradas en hacer que esto suceda. Una de ellas hace la transición margin-bottom de 0px (en el estado expandido) a -2000px en el estado colapsado (similar a esta respuesta) El 2000 aquí es el primer número mágico, se basa en la suposición de que su caja no será más alta que esta (2000 píxeles parece una opción razonable).

Utilizando el margin-bottom la transición sola tiene dos problemas:

  • Si realmente tiene una caja que es más de 2000 píxeles, entonces una margin-bottom: -2000px no ocultará todo: habrá cosas visibles incluso en el caso colapsado. Esta es una solución menor que haremos más tarde.
  • Si el cuadro real es, por ejemplo, 1000 píxeles de alto, y su transición es 300ms de largo, entonces el visible la transición ya ha terminado después de aproximadamente 150 ms (o, en la dirección opuesta, comienza 150 ms tarde).

La solución a este segundo problema es donde entra la segunda transición, y esta transición se enfoca conceptualmente en el envoltorio mínimo altura ("conceptualmente" porque en realidad no estamos usando el min-height propiedad para esto; más sobre eso más tarde).

Aquí hay una animación que muestra cómo la combinación de la transición del margen inferior con la transición de altura mínima, ambas de igual duración, nos da una transición combinada de altura completa a altura cero que tiene la misma duración.

animation as described above

La barra izquierda muestra cómo el margen inferior negativo empuja la parte inferior hacia arriba, reduciendo la altura visible. La barra del medio muestra cómo la altura mínima asegura que en el caso colapsante, la transición no termina temprano, y en el caso de expansión, la transición no comienza tarde. La barra derecha muestra cómo la combinación de los dos hace que la caja pase de una altura completa a una altura cero en la cantidad de tiempo correcta.

Para mi demostración, me he establecido en 50px como el valor de altura mínima superior. Este es el segundo número mágico, y debería ser más bajo que la altura de la caja. 50px parece razonable también; parece poco probable que, en primer lugar, desee convertir un elemento colapsible que no tenga siquiera 50 píxeles de altura.

Como puede ver en la animación, la transición resultante es continua, pero no es derivable: en el momento en que la altura mínima es igual a la altura completa ajustada por el margen inferior, se produce un cambio repentino en la velocidad. Esto es muy notable en la animación porque usa una función de tiempo lineal para ambas transiciones, y porque la transición completa es muy lenta. En el caso real (mi demo en la parte superior), la transición solo tarda 300 ms, y la transición del margen inferior no es lineal. He jugado con muchas funciones de sincronización diferentes para ambas transiciones, y las que terminaron parecían funcionar mejor para la más amplia variedad de casos.

Quedan dos problemas por resolver:

  1. el punto desde arriba, donde los cuadros de más de 2000 píxeles de altura no están completamente ocultos en el estado colapsado,
  2. y el problema inverso, donde en el caso no oculto, los cuadros de menos de 50 píxeles de altura son demasiado altos incluso cuando la transición no se está ejecutando, porque la altura mínima los mantiene en 50 píxeles.

Resolvemos el primer problema dando al elemento contenedor un max-height: 0 en el caso colapsado, con un 0s 0.3s transición. Esto significa que no es realmente una transición, pero el max-height se aplica con un retraso; solo se aplica una vez que la transición ha terminado. Para que esto funcione correctamente, también debemos elegir un número max-height para el estado opuesto, no colapsado. Pero a diferencia del caso 2000px, donde elegir un número demasiado grande afecta la calidad de la transición, en este caso, realmente no importa. Entonces podemos elegir un número tan alto que saber que ninguna altura se acercará a esto. Escogí un millón de píxeles. Si cree que puede necesitar contenido de más de un millón de píxeles, entonces 1) Lo siento, y 2) simplemente agregue un par de ceros.

El segundo problema es la razón por la cual no estamos realmente usando min-height para la transición de altura mínima. En cambio, hay un ::after pseudo-elemento en el contenedor con un height que transiciones de 50px a cero. Esto tiene el mismo efecto que un min-height: No permitirá que el contenedor se contraiga por debajo de la altura que tenga actualmente el pseudo-elemento. Pero debido a que estamos usando heightno min-height, ahora podemos usar max-height (una vez más aplicado con un retraso) para establecer la altura real del pseudo-elemento a cero una vez que la transición haya finalizado, asegurando que al menos fuera de la transición, incluso los elementos pequeños tienen la altura correcta. Porque min-height es más fuerte que max-height, esto no funcionaría si usáramos el contenedor min-height en lugar de los pseudo-elementos height. Al igual que el max-height en el párrafo anterior, esto max-height también necesita un valor para el extremo opuesto de la transición. Pero en este caso solo podemos elegir 50px.

Probado en Chrome (Win, Mac, Android, iOS), Firefox (Win, Mac, Android), Edge, IE11 (a excepción de un problema de diseño de flexbox con mi demo que no molesté en la depuración) y Safari (Mac, iOS) ) Hablando de flexbox, debería ser posible hacer que esto funcione sin usar ningún flexbox; de hecho, creo que podrías hacer que casi todo funcione en IE7, excepto por el hecho de que no tendrás transiciones de CSS, por lo que es un ejercicio bastante inútil.


45
2018-05-14 14:33



Una solución visual para animar la altura mediante el uso de transiciones CSS3 es animar el relleno en su lugar.

No se obtiene el efecto de borrado completo, pero jugar con los valores de duración de transición y relleno debería acercarlo lo suficiente. Si no desea establecer explícitamente altura / altura máxima, esto debería ser lo que está buscando.

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/ (riffed de stephband's arriba jsFiddle)


44
2018-06-26 19:05



Mi solución es hacer una transición de la altura máxima a la altura exacta del contenido para una animación suave y agradable, luego usar una devolución de llamada transitionEnd para establecer la altura máxima en 9999px para que el contenido pueda cambiar de tamaño libremente.

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



La respuesta aceptada funciona para la mayoría de los casos, pero no funciona bien cuando su div puede variar mucho en altura: la velocidad de animación no depende de la altura real del contenido, y puede verse entrecortada.

Todavía puede realizar la animación real con CSS, pero necesita usar JavaScript para calcular la altura de los elementos, en lugar de intentar usarla auto. No se requiere jQuery, aunque es posible que deba modificarlo un poco si desea compatibilidad (funciona en la última versión de 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>


31
2017-10-20 22:57



Utilizar max-height con diferentes tiempos de transición y demora para cada estado.

HTML:

<a href="#" id="trigger">Hover</a>
<ul id="toggled">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
<ul>

CSS:

#toggled{
    max-height: 0px;
    transition: max-height .8s cubic-bezier(0, 1, 0, 1) -.1s;
}

#trigger:hover + #toggled{
    max-height: 9999px;
    transition-timing-function: cubic-bezier(0.5, 0, 1, 0); 
    transition-delay: 0s;
}

Ver ejemplo: http://jsfiddle.net/0hnjehjc/1/


23
2017-12-16 23:35



Sin valores codificados.

Sin JavaScript

Sin aproximaciones.

El truco es usar un escondido y duplicado div para que el navegador entienda lo que significa 100%.

Este método es adecuado siempre que pueda duplicar el DOM del elemento que desea animar.

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


21
2018-02-26 17:19