CSS3相当于 jQuery slideUp 和 slideDown?

我的应用程序在使用 jQuery 的 slideDown 和 slideUp 时表现不佳。我希望在支持 CSS3的浏览器中使用等效的 CSS3。

是否有可能,使用 CSS3过渡,改变一个元素从 display: none;display: block;,同时滑动项目向下或向上?

142945 次浏览

You could do something like this:

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

Example - Slide and Fade:

This slides and animates the opacity - not based on height of the container, but on the top/coordinate. View example

Example - Auto-height/No Javascript: Here is a live sample, not needing height - dealing with automatic height and no javascript.
View example

So I've gone ahead and answered my own question :)

@True's answer regarded transforming an element to a specific height. The problem with this is I don't know the height of the element (it can fluctuate).

I found other solutions around which used max-height as the transition but this produced a very jerky animation for me.

My solution below works only in WebKit browsers.

Although not purely CSS, it involves transitioning the height, which is determined by some 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>

View on JSFiddle

I changed your solution, so that it works in all modern browsers:

css snippet:

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

here's the full example http://jsfiddle.net/RHPQd/

I would recommend using the jQuery Transit Plugin which uses the CSS3 transform property, which works great on mobile devices due to the fact that most support hardware acceleration to give that native look and feel.

JS Fiddle Example

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

you can't make easisly a slideup slidedown with css3 tha's why I've turned JensT script into a plugin with javascript fallback and callback.

in this way if you have a modern brwowser you can use the css3 csstransition. if your browser does not support it gracefuly use the old fashioned 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;
}

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

how to use it

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

you can find a demo page here http://www.mosne.it/playground/mosne_slide_up_down/

Getting height transitions to work can be a bit tricky mainly because you have to know the height to animate for. This is further complicated by padding in the element to be animated.

Here is what I came up with:

use a style like this:

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

Wrap your content into another container so that the container you're sliding has no padding/margins/borders:

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

Then use some script (or declarative markup in binding frameworks) to trigger the CSS classes.

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

Example here: http://plnkr.co/edit/uhChl94nLhrWCYVhRBUF?p=preview

This works fine for fixed size content. For a more generic soltution you can use code to figure out the size of the element when the transition is activated. The following is a jQuery plug-in that does just that:

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

which can be triggered like this:

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

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

against markup like this:

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

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

I wrote this up recently in a blog post if you're interested in more detail:

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

why not to take advantage of modern browsers css transition and make things simpler and fast using more css and less jquery

Here is the code for sliding up and down

Here is the code for sliding left to right

Similarly we can change the sliding from top to bottom or right to left by changing transform-origin and transform: scaleX(0) or transform: scaleY(0) appropriately.

Aight fam, after some research and experimenting, I think the best approach is to have the thing's height at 0px, and let it transition to an exact height. You get the exact height with JavaScript. The JavaScript isn't doing the animating, it's just changing the height value. Check it:

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

Whenever the page loads or is resized, the element with class info will get its h attribute updated. Then you could have a button trigger the style="height: __" to set it to that previously set h value.

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


});
};

Here's the styling for the info class.

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

I used this on one of my projects so class names are specific. You can change them up however you like.

The styling might not be supported cross-browser. Works fine in chrome.

Below is the live example for this code. Just click on the ? icon to start the animation

CodePen

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

Variant without JavaScript. Only 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>

For next block only change ID and FOR attributes in html.