CSS3 equivalente a jQuery slideUp y slideDown?


88

Mi aplicación funciona mal con slideDown y slideUp de jQuery. Estoy buscando usar un equivalente CSS3 en los navegadores que lo admitan.

¿Es posible, usando transiciones CSS3, cambiar un elemento de display: none;a display: block;mientras se desliza hacia abajo o hacia arriba?


Creo que mantendría la pantalla: block, pero simplemente ajuste el ancho de la cantidad deseada a 0.
Dunhamzzz

Respuestas:


37

Podrías hacer algo como esto:

#youritem .fade.in {
    animation-name: fadeIn;
}

#youritem .fade.out {
    animation-name: fadeOut;
}

@keyframes fadeIn {
    0% {
        opacity: 0;
        transform: translateY(startYposition);
    } 
    100% {
        opacity: 1;
        transform: translateY(endYposition);
    }
}

@keyframes fadeOut {
    0% {
        opacity: 1;
        transform: translateY(startYposition);
    } 
    100% {
        opacity: 0;
        transform: translateY(endYposition);
    }
}

Ejemplo: deslizarse y fundirse:

Esto desliza y anima la opacidad, no en función de la altura del contenedor, sino en la parte superior / coordenada. Ver ejemplo

Ejemplo: altura automática / sin Javascript: aquí hay una muestra en vivo, sin necesidad de altura, que se ocupa de la altura automática y sin javascript.
Ver ejemplo


¿Puedes hacer una demostración en jsFiddle?
Šime Vidas

@ Šime Desde mi primer vistazo, yo diría que solo le da a su elemento class = "fade" y agrega clase cuando quiera un fundido de entrada, y salga cuando quiera un fundido de salida.
lsuarez

@ Šime - He incluido dos muestras para que las use
TNC

Vsync: mire a continuación y siga el hilo antes de publicar comentarios como este
TNC

3
Modifiqué el segundo ejemplo (altura automática / sin JavaScript) para que solo estuvieran en su lugar los estilos barebones para obtener el efecto. jsfiddle.net/OlsonDev/nB5Du/251
Olson.dev

14

Cambié su solución para que funcione en todos los navegadores modernos:

fragmento de CSS:

-webkit-transition: height 1s ease-in-out;
-moz-transition: height 1s ease-in-out;
-ms-transition: height 1s ease-in-out;
-o-transition: height 1s ease-in-out;
transition: height 1s ease-in-out;

fragmento de js:

    var clone = $('#this').clone()
                .css({'position':'absolute','visibility':'hidden','height':'auto'})
                .addClass('slideClone')
                .appendTo('body');

    var newHeight = $(".slideClone").height();
    $(".slideClone").remove();
    $('#this').css('height',newHeight + 'px');

aquí está el ejemplo completo http://jsfiddle.net/RHPQd/


9

Así que seguí adelante y respondí mi propia pregunta :)

La respuesta de @ True consideró la transformación de un elemento a una altura específica. El problema con esto es que no sé la altura del elemento (puede fluctuar).

Encontré otras soluciones en las que se usaba la altura máxima como transición, pero esto me produjo una animación muy entrecortada.

Mi solución a continuación funciona solo en navegadores WebKit.

Aunque no es puramente CSS, implica la transición de la altura, que está determinada por algunos JS.

$('#click-me').click(function() {
  var height = $("#this").height();
  if (height > 0) {
    $('#this').css('height', '0');
  } else {
    $("#this").css({
      'position': 'absolute',
      'visibility': 'hidden',
      'height': 'auto'
    });
    var newHeight = $("#this").height();
    $("#this").css({
      'position': 'static',
      'visibility': 'visible',
      'height': '0'
    });
    $('#this').css('height', newHeight + 'px');
  }
});
#this {
  width: 500px;
  height: 0;
  max-height: 9999px;
  overflow: hidden;
  background: #BBBBBB;
  -webkit-transition: height 1s ease-in-out;
}

#click-me {
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>

<p id="click-me">click me</p>
<div id="this">here<br />is<br />a<br />bunch<br />of<br />content<br />sdf</div>
<div>always shows</div>

Ver en JSFiddle


Sí, mi código a continuación no requiere altura, ya que usa la coordenada y. Pero no mencionaste que necesitabas algo con una dependencia de altura :) Siempre puedes hacer una transición de margen, etc. Pero parece que tienes lo que estás buscando, ¿no?
TNC

@Verdadero, ¿cree que podría explicar lo que quiere decir con una transición de margen?
Mike

Muestra agregada para posicionamiento, agregará el margen
TNC

También se agregó un ejemplo de margen / no javsacript
TNC

8

¿Por qué no aprovechar la transición css de los navegadores modernos y hacer las cosas más simples y rápidas usando más css y menos jquery?

Aquí está el código para deslizarse hacia arriba y hacia abajo

Aquí está el código para deslizar de izquierda a derecha

De manera similar, podemos cambiar el deslizamiento de arriba a abajo o de derecha a izquierda cambiando transform-origin y transform: scaleX (0) o transform: scaleY (0) de manera apropiada.


1
Sé que estas respuestas se colocaron en 2014, pero no puedo recomendar el uso de esta respuesta si desea empujar elementos debajo de ella hacia abajo o hacia arriba, ya que el contenedor principal marcará la altura en el navegador
Ellisan

6

Hacer que las transiciones de altura funcionen puede ser un poco complicado, principalmente porque debes saber la altura para la que animar. Esto se complica aún más con el relleno en el elemento que se va a animar.

Esto es lo que se me ocurrió:

usa un estilo como este:

    .slideup, .slidedown {
        max-height: 0;            
        overflow-y: hidden;
        -webkit-transition: max-height 0.8s ease-in-out;
        -moz-transition: max-height 0.8s ease-in-out;
        -o-transition: max-height 0.8s ease-in-out;
        transition: max-height 0.8s ease-in-out;
    }
    .slidedown {            
        max-height: 60px ;  // fixed width                  
    }

Envuelva su contenido en otro contenedor para que el contenedor que está deslizando no tenga relleno / márgenes / bordes:

  <div id="Slider" class="slideup">
    <!-- content has to be wrapped so that the padding and
            margins don't effect the transition's height -->
    <div id="Actual">
            Hello World Text
        </div>
  </div>

Luego use algún script (o marcado declarativo en marcos vinculantes) para activar las clases CSS.

  $("#Trigger").click(function () {
    $("#Slider").toggleClass("slidedown slideup");
  });

Ejemplo aquí: http://plnkr.co/edit/uhChl94nLhrWCYVhRBUF?p=preview

Esto funciona bien para contenido de tamaño fijo. Para una solución más genérica, puede usar código para calcular el tamaño del elemento cuando se activa la transición. El siguiente es un complemento de jQuery que hace precisamente eso:

$.fn.slideUpTransition = function() {
    return this.each(function() {
        var $el = $(this);
        $el.css("max-height", "0");
        $el.addClass("height-transition-hidden");
    });
};

$.fn.slideDownTransition = function() {
    return this.each(function() {
        var $el = $(this);
        $el.removeClass("height-transition-hidden");

        // temporarily make visible to get the size
        $el.css("max-height", "none");
        var height = $el.outerHeight();

        // reset to 0 then animate with small delay
        $el.css("max-height", "0");

        setTimeout(function() {
            $el.css({
                "max-height": height
            });
        }, 1);
    });
};

que se puede activar así:

$ ("# Trigger"). Haga clic en (function () {

    if ($("#SlideWrapper").hasClass("height-transition-hidden"))
        $("#SlideWrapper").slideDownTransition();
    else
        $("#SlideWrapper").slideUpTransition();
});

contra el marcado como este:

<style>
#Actual {
    background: silver;
    color: White;
    padding: 20px;
}

.height-transition {
    -webkit-transition: max-height 0.5s ease-in-out;
    -moz-transition: max-height 0.5s ease-in-out;
    -o-transition: max-height 0.5s ease-in-out;
    transition: max-height 0.5s ease-in-out;
    overflow-y: hidden;            
}
.height-transition-hidden {            
    max-height: 0;            
}
</style>
<div id="SlideWrapper" class="height-transition height-transition-hidden">
    <!-- content has to be wrapped so that the padding and
        margins don't effect the transition's height -->
    <div id="Actual">
     Your actual content to slide down goes here.
    </div>
</div>

Ejemplo: http://plnkr.co/edit/Wpcgjs3FS4ryrhQUAOcU?p=preview

Escribí esto recientemente en una publicación de blog si está interesado en más detalles:

http://weblog.west-wind.com/posts/2014/Feb/22/Using-CSS-Transitions-to-SlideUp-and-SlideDown


Esta es la solución más elegante para mí. Y si es necesario, jQuery se puede eliminar fácilmente. Uno puede alternar una clase en vanila JS como:document.getElementById("Slider").classList.toggle("slidedown");
hypers

5

Recomendaría usar el complemento jQuery Transit que usa la propiedad de transformación CSS3, que funciona muy bien en dispositivos móviles debido al hecho de que la mayoría admite la aceleración de hardware para dar esa apariencia nativa.

Ejemplo de JS Fiddle

HTML:

<div class="moveMe">
    <button class="moveUp">Move Me Up</button>
    <button class="moveDown">Move Me Down</button>
    <button class="setUp">Set Me Up</button>
    <button class="setDown">Set Me Down</button>
 </div>

Javascript:

$(".moveUp").on("click", function() {
    $(".moveMe").transition({ y: '-=5' });
});

$(".moveDown").on("click", function() {
    $(".moveMe").transition({ y: '+=5' });
});

$(".setUp").on("click", function() {
    $(".moveMe").transition({ y: '0px' });
});

$(".setDown").on("click", function() {
    $(".moveMe").transition({ y: '200px' });
});

¿Esto le permite hacer la transición a la altura natural de un elemento usando auto? p.ej. $ (". moveMe"). transición ({altura: 'auto'})
monkeyboy

2
Desearía que anularan los métodos slideUp()y slideDown()con este complemento. Eso sería realmente bueno
steve

Esto es increíble por cierto. ¡Gracias por agregar esta respuesta!
steve

2

Bueno, familia, después de investigar un poco y experimentar, creo que el mejor enfoque es tener la altura de la cosa 0pxy dejar que pase a una altura exacta. Obtienes la altura exacta con JavaScript. JavaScript no está haciendo la animación, solo está cambiando el valor de altura. Revisalo:

function setInfoHeight() {
  $(window).on('load resize', function() {
    $('.info').each(function () {
      var current = $(this);
      var closed = $(this).height() == 0;
      current.show().height('auto').attr('h', current.height() );
      current.height(closed ? '0' : current.height());
    });
  });

Siempre que la página se cargue o cambie de tamaño, el elemento con clase infoobtendrá su hatributo actualizado. Luego, podría hacer que un botón active el style="height: __"para configurarlo en ese hvalor establecido previamente .

function moreInformation() {
  $('.icon-container').click(function() {
    var info = $(this).closest('.dish-header').next('.info'); // Just the one info
    var icon = $(this).children('.info-btn'); // Select the logo

    // Stop any ongoing animation loops. Without this, you could click button 10
    // times real fast, and watch an animation of the info showing and closing
    // for a few seconds after
    icon.stop();
    info.stop();

    // Flip icon and hide/show info
    icon.toggleClass('flip');

    // Metnod 1, animation handled by JS
    // info.slideToggle('slow');

    // Method 2, animation handled by CSS, use with setInfoheight function
    info.toggleClass('active').height(icon.is('.flip') ? info.attr('h') : '0');

  });
};

Aquí está el estilo de la infoclase.

.info {
  display: inline-block;
  height: 0px;
  line-height: 1.5em;
  overflow: hidden;
  padding: 0 1em;
  transition: height 0.6s, padding 0.6s;
  &.active {
    border-bottom: $thin-line;
    padding: 1em;
  }
}

Usé esto en uno de mis proyectos, por lo que los nombres de las clases son específicos. Puedes cambiarlos como quieras.

Es posible que el estilo no sea compatible con varios navegadores. Funciona bien en cromo.

A continuación se muestra el ejemplo en vivo de este código. Simplemente haga clic en el ?icono para iniciar la animación.

CodePen


1

Variante sin JavaScript. Solo CSS.

CSS:

.toggle_block {
    border: 1px solid #ccc;
    text-align: left;
    background: #fff;
    overflow: hidden;
}
.toggle_block .toggle_flag {
    display: block;
    width: 1px;
    height: 1px;
    position: absolute;
    z-index: 0;
    left: -1000px;
}
.toggle_block .toggle_key {
    font-size: 16px;
    padding: 10px;
    cursor: pointer;
    -webkit-transition: all 300ms ease;
       -moz-transition: all 300ms ease;
        -ms-transition: all 300ms ease;
         -o-transition: all 300ms ease;
            transition: all 300ms ease;
}
.toggle_block .content {
    padding: 0 10px;
    overflow: hidden;
    max-height: 0;
    -webkit-transition: all 300ms ease;
       -moz-transition: all 300ms ease;
        -ms-transition: all 300ms ease;
         -o-transition: all 300ms ease;
            transition: all 300ms ease;
}
.toggle_block .content .toggle_close {
    cursor: pointer;
    font-size: 12px;
}
.toggle_block .toggle_flag:checked ~ .toggle_key {
    background: #dfd;
}
.toggle_block .toggle_flag:checked ~ .content {
    max-height: 1000px;
    padding: 10px 10px;
}

HTML:

<div class="toggle_block">
    <input type="checkbox" id="toggle_1" class="toggle_flag">
    <label for="toggle_1" class="toggle_key">clicker</label>
    <div class="content">
        Text 1<br>
        Text 2<br>
        <label for="toggle_1" class="toggle_close">close</label>
    </div>
</div>

Para el siguiente bloque, solo cambie los atributos ID y FOR en html.


0

no se puede hacer fácilmente un slideup slidedown con css3, por eso convertí el script JensT en un complemento con respaldo y devolución de llamada de javascript.

de esta manera, si tiene un brwowser moderno, puede usar css3 csstransition. Si su navegador no lo admite, use correctamente el antiguo slideUp slideDown.

 /* css */
.csstransitions .mosneslide {
  -webkit-transition: height .4s ease-in-out;
  -moz-transition: height .4s ease-in-out;
  -ms-transition: height .4s ease-in-out;
  -o-transition: height .4s ease-in-out;
  transition: height .4s ease-in-out;
  max-height: 9999px;
  overflow: hidden;
  height: 0;
}

el complemento

(function ($) {
$.fn.mosne_slide = function (
    options) {
    // set default option values
    defaults = {
        delay: 750,
        before: function () {}, // before  callback
        after: function () {} // after callback;
    }
    // Extend default settings
    var settings = $.extend({},
        defaults, options);
    return this.each(function () {
        var $this = $(this);
        //on after
        settings.before.apply(
            $this);
        var height = $this.height();
        var width = $this.width();
        if (Modernizr.csstransitions) {
            // modern browsers
            if (height > 0) {
                $this.css(
                    'height',
                    '0')
                    .addClass(
                        "mosne_hidden"
                );
            } else {
                var clone =
                    $this.clone()
                    .css({
                        'position': 'absolute',
                        'visibility': 'hidden',
                        'height': 'auto',
                        'width': width
                    })
                    .addClass(
                        'mosne_slideClone'
                )
                    .appendTo(
                        'body'
                );
                var newHeight =
                    $(
                        ".mosne_slideClone"
                )
                    .height();
                $(
                    ".mosne_slideClone"
                )
                    .remove();
                $this.css(
                    'height',
                    newHeight +
                    'px')
                    .removeClass(
                        "mosne_hidden"
                );
            }
        } else {
            //fallback
            if ($this.is(
                ":visible"
            )) {
                $this.slideUp()
                    .addClass(
                        "mosne_hidden"
                );
            } else {
                $this.hide()
                    .slideDown()
                    .removeClass(
                        "mosne_hidden"
                );
            }
        }
        //on after
        setTimeout(function () {
            settings.after
                .apply(
                    $this
            );
        }, settings.delay);
    });
}
})(jQuery);;

cómo usarlo

/* jQuery */
$(".mosneslide").mosne_slide({
    delay:400,
    before:function(){console.log("start");},
    after:function(){console.log("done");}
});

puedes encontrar una página de demostración aquí http://www.mosne.it/playground/mosne_slide_up_down/


Esta no es una respuesta, una respuesta contiene más que un enlace.
Máximo

Esto no proporciona una respuesta a la pregunta. Para criticar o solicitar una aclaración de un autor, deje un comentario debajo de su publicación; siempre puede comentar sus propias publicaciones y, una vez que tenga suficiente reputación , podrá comentar cualquier publicación .
4 de

Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden dejar de ser válidas si cambia la página enlazada.
sashkello

0
    try this for slide up slide down with animation 
give your **height

        @keyframes slide_up{
            from{
                min-height: 0;
                height: 0px;
                opacity: 0;
            }
            to{
                height: 560px;
                opacity: 1;
            }
        }

        @keyframes slide_down{
            from{
                height: 560px;
                opacity: 1;
            }
            to{
                min-height: 0;
                height: 0px;
                opacity: 0;
            } 
        }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.