web-dev-qa-db-fra.com

Équivalent CSS3 pour jQuery slideUp et slideDown?

Mon application fonctionne mal avec slideDown et slideUp de jQuery. Je cherche à utiliser un équivalent CSS3 dans les navigateurs qui le prennent en charge.

Est-il possible, en utilisant les transitions CSS3, de changer un élément de display: none; à display: block; en faisant glisser l’article vers le bas ou vers le haut?

74
Mike

Vous pouvez faire quelque chose comme ça:

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

Exemple - Slide et Fade:

Cela fait glisser et anime l'opacité - non pas en fonction de la hauteur du conteneur, mais en haut/coordonnée. Voir l'exemple

Exemple - Hauteur automatique/Pas de Javascript: Voici un échantillon live ne nécessitant pas de hauteur - traitant de la hauteur automatique et de l'absence de javascript.
Voir l'exemple

32
TNC

J'ai changé votre solution pour qu'elle fonctionne dans tous les navigateurs modernes:

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

js snippet:

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

voici l'exemple complet http://jsfiddle.net/RHPQd/

14
JensT

Donc, je suis allé de l'avant et a répondu à ma propre question :)

La réponse de @ True considérait la transformation d'un élément à une hauteur spécifique. Le problème, c'est que je ne connais pas la hauteur de l'élément (il peut fluctuer).

J'ai trouvé d'autres solutions autour desquelles max-height était utilisée comme transition, mais cela produisait une animation très saccadée.

Ma solution ci-dessous ne fonctionne que dans les navigateurs WebKit.

Bien que n'étant pas purement CSS, cela implique une transition de la hauteur, qui est déterminée par certains 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>

Voir sur JSFiddle

9
Mike

pourquoi ne pas profiter de la transition css des navigateurs modernes et simplifier les choses rapidement en utilisant plus de css et moins de jquery

Voici le code pour glisser de haut en bas

Voici le code pour glisser de gauche à droite

De même, nous pouvons changer le glissement de haut en bas ou de droite à gauche en modifiant transform-Origin et transform: scaleX (0) ou transform: scaleY (0) de manière appropriée.

8
manas

Obtenir des transitions de hauteur au travail peut être un peu délicat, principalement parce que vous devez connaître la hauteur pour animer. Ceci est encore compliqué par le remplissage de l'élément à animer.

Voici ce que je suis venu avec:

utilisez un style comme celui-ci:

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

Enveloppez votre contenu dans un autre conteneur afin que le conteneur que vous faites glisser ne comporte pas de marges/marges/bordures:

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

Utilisez ensuite un script (ou un balisage déclaratif dans les frameworks de liaison) pour déclencher les classes CSS.

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

Exemple ici: http://plnkr.co/edit/uhChl94nLhrWCYVhRBUF?p=preview

Cela fonctionne très bien pour le contenu de taille fixe. Pour une solution plus générique, vous pouvez utiliser du code pour déterminer la taille de l'élément lorsque la transition est activée. Voici un plug-in jQuery qui fait exactement cela:

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

qui peut être déclenché comme ceci:

$ ("# Trigger"). Click (function () {

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

contre le balisage comme ceci:

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

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

J'ai récemment écrit ceci dans un article de blog si vous souhaitez plus de détails:

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

5
Rick Strahl

Je recommanderais d'utiliser jQuery Transit Plugin , qui utilise la propriété de transformation CSS3, qui fonctionne très bien sur les appareils mobiles en raison du fait que la plupart prennent en charge l'accélération matérielle pour lui donner cet aspect natif.

JS Fiddle Exemple

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' });
});
5
ROFLwTIME

Après quelques recherches et expériences, je pense que la meilleure approche consiste à avoir la hauteur de la chose à 0px Et à la laisser passer à une hauteur exacte. Vous obtenez la hauteur exacte avec JavaScript. Le JavaScript ne fait pas l'animation, il se contente de changer la valeur de la hauteur. Vérifie ça:

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

Chaque fois que la page est chargée ou redimensionnée, l'élément de classe info obtiendra son attribut h mis à jour. Ensuite, vous pourriez avoir un bouton qui déclenche style="height: __" Pour le régler sur la valeur précédemment définie h.

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

  });
};

Voici le style de la classe info.

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

Je l'ai utilisé sur l'un de mes projets, donc les noms de classe sont spécifiques. Vous pouvez les changer comme bon vous semble.

Le style peut ne pas être pris en charge sur plusieurs navigateurs. Fonctionne bien en chrome.

Vous trouverez ci-dessous l'exemple en direct de ce code. Cliquez simplement sur l'icône ? Pour lancer l'animation.

CodePen

2
Cruz Nunez

vous ne pouvez pas faire facilement une glissade vers le bas avec CSS3 c'est pourquoi j'ai transformé le script JensT en un plugin avec le repli et le rappel javascript.

de cette façon, si vous avez un navigateur moderne, vous pouvez utiliser le cssstransition css3. si votre navigateur ne le prend pas en charge, utilisez l’ancien 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;
}

le plugin

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

comment l'utiliser

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

vous pouvez trouver une page de démonstration ici http://www.mosne.it/playground/mosne_slide_up_down/

0
mosne