CSS3 équivalent à jQuery slideUp et slideDown?

88

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;tout en faisant glisser l'élément vers le bas ou vers le haut?

Mike
la source
Je pense que vous conserveriez l'affichage: bloc, mais ajustez simplement la largeur de la quantité souhaitée à 0.
Dunhamzzz

Réponses:

37

Vous pouvez faire quelque chose comme ceci:

#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 and Fade:

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

Exemple - Hauteur automatique / Pas de Javascript: Voici un échantillon en direct, sans hauteur - traitant de la hauteur automatique et pas de javascript.
Voir l'exemple

TNC
la source
Pouvez-vous faire une démo sur jsFiddle?
Šime Vidas
@ Šime Dès mon premier coup d'œil, je dirais simplement de donner votre élément class = "fade" et d'ajouter de la classe lorsque vous souhaitez un fondu entrant, sortant lorsque vous souhaitez un fondu sortant.
lsuarez
@ Šime - J'ai inclus deux échantillons pour que vous puissiez les utiliser
TNC
Vsync - regardez ci-dessous et suivez le fil de discussion avant de simplement publier des commentaires comme celui-ci
TNC
3
J'ai modifié le deuxième exemple (hauteur automatique / pas de JavaScript) afin que seuls les styles barebones pour obtenir l'effet soient en place. jsfiddle.net/OlsonDev/nB5Du/251
Olson.dev
14

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

extrait de code 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/

JensT
la source
9

Alors je suis allé de l'avant et j'ai répondu à ma propre question :)

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

J'ai trouvé d'autres solutions autour desquelles utilisé la hauteur maximale comme transition, mais cela a produit une animation très saccadée pour moi.

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

Bien que non purement CSS, cela implique la 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>

Vue sur JSFiddle

Mike
la source
Oui, mon code ci-dessous ne nécessite pas de hauteur car il utilise la coordonnée y. Mais vous n'avez pas mentionné que vous aviez besoin de quelque chose avec une dépendance de hauteur :) Vous pouvez toujours faire une transition de marge, etc. Mais il semble que vous ayez ce que vous cherchez, non?
TNC
@Vraiment, pensez-vous pouvoir expliquer ce que vous entendez par transition de marge?
Mike
Ajout d'un échantillon pour le positionnement, ajoutera la marge
TNC
Ajout d'un exemple de marge / pas de javsacript
TNC
8

pourquoi ne pas profiter de la transition css des navigateurs modernes et rendre les choses plus simples et rapides 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 modifier le glissement de haut en bas ou de droite à gauche en modifiant l'origine de la transformation et transform: scaleX (0) ou transform: scaleY (0) de manière appropriée.

manas
la source
1
Je sais que cette réponse a été placée en 2014 , mais je ne peux pas vous recommandons d' utiliser cette réponse si vous voulez pousser les éléments ci - dessous vers le bas ou vers le haut depuis le conteneur parent jalonneront la hauteur dans le navigateur
Ellisan
6

Faire fonctionner les transitions de hauteur peut être un peu délicat, principalement parce que vous devez connaître la hauteur pour laquelle animer. Ceci est encore compliqué par le remplissage dans l'élément à animer.

Voici ce que j'ai trouvé:

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 glissez n'a pas de remplissage / 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>

Ensuite, utilisez 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 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"). Cliquez sur (function () {

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

contre un balisage comme celui-ci:

<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 êtes intéressé par plus de détails:

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

Rick Strahl
la source
C'est la solution la plus élégante selon moi. Et si nécessaire, jQuery peut être facilement supprimé. On peut basculer une classe dans vanila JS comme:document.getElementById("Slider").classList.toggle("slidedown");
hypers
5

Je recommanderais d'utiliser le plugin jQuery Transit qui utilise la propriété de transformation CSS3, qui fonctionne très bien sur les appareils mobiles car la plupart prennent en charge l'accélération matérielle pour donner cet aspect et cette sensation natifs.

Exemple 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' });
});
ROFLwTIME
la source
Cela vous permet-il de passer à la hauteur naturelle d'un élément en utilisant auto? par exemple. $ (". moveMe"). transition ({height: 'auto'})
monkeyboy
2
Je souhaite qu'ils remplacent les méthodes slideUp()et slideDown()avec ce plugin. Ce serait vraiment bien
steve
C'est génial BTW. Merci d'avoir ajouté cette réponse!
steve
2

Aight fam, après quelques recherches et expérimentations, je pense que la meilleure approche est d'avoir la hauteur de la chose à 0px, et de la laisser passer à une hauteur exacte. Vous obtenez la hauteur exacte avec JavaScript. Le JavaScript ne fait pas l'animation, il change simplement 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 se charge ou est redimensionnée, l'élément avec la classe infoverra son hattribut mis à jour. Ensuite, vous pourriez avoir un bouton déclencher le style="height: __"pour le régler à cette hvaleur précédemment définie .

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

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

J'ai utilisé ceci sur l'un de mes projets afin que les noms de classe soient spécifiques. Vous pouvez les modifier comme vous le souhaitez.

Le style n'est peut-être pas pris en charge dans plusieurs navigateurs. Fonctionne très bien en chrome.

Voici l'exemple en direct de ce code. Cliquez simplement sur l' ?icône pour démarrer l'animation

CodePen

Cruz Nunez
la source
1

Variante sans JavaScript. Seulement 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>

Pour le bloc suivant, modifiez uniquement les attributs ID et FOR en html.

Szen
la source
0

vous ne pouvez pas faire facilement un glissement glissé vers le bas avec css3, c'est pourquoi j'ai transformé le script JensT en un plugin avec une solution de secours et de rappel javascript.

de cette façon, si vous avez un navigateur moderne, vous pouvez utiliser la csstransition css3. si votre navigateur ne le prend pas en charge, utilisez le slideDown à l'ancienne slideUp.

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

mosne
la source
Ce n'est pas une réponse, une réponse contient plus qu'un simple lien.
Max
Cela ne répond pas à la question. Pour critiquer ou demander des éclaircissements à un auteur, laissez un commentaire sous son message - vous pouvez toujours commenter vos propres articles, et une fois que vous avez une réputation suffisante, vous pourrez commenter n'importe quel article .
Quatrième
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses aux liens uniquement peuvent devenir invalides si la page liée change.
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;
            } 
        }
uma mahesh
la source