问题
I'm trying to get objects to "slide in" from the bottom of the screen, but since I can't get the screen height as a unit in CSS, I'm trying to do this with media queries, like so:
@media(max-height:500px) {
@keyframe slideUp {
0% { transform: translate3d(0,500px,0); }
100% { transform: translate3d(0,0,0); }
}
}
@media(max-height:750px) {
@keyframe slideUp {
0% { transform: translate3d(0,750px,0); }
100% { transform: translate3d(0,0,0); }
}
}
/* etc. */
This doesn't work (it uses the first version of slideUp
regardless of height), so I assume keyframes, once defined, cannot be overwritten or reassigned based on media queries? Is there any way to achieve this effect (short of having many different keyframe setups and using a media query to assign the appropriate one to the class)?
回答1:
I don't why nobody else has suggested this but instead of setting the keyframes in the media query you can set the animation in the media query.
@media(max-height:500px)
{
#selectorGroup {
animation: slideUp500 1s forwards;
}
}
@media(max-height:750px)
{
#selectorGroup {
animation: slideUp750 1s forwards;
}
}
@keyframes slideUp500 {
0% { transform: translate3d(0,500px,0); }
100% { transform: translate3d(0,0,0); }
}
@keyframes slideUp750 {
0% { transform: translate3d(0,750px,0); }
100% { transform: translate3d(0,0,0); }
}
回答2:
A way of doing a slide up animation regardless of screen or element height is to use position: fixed
:
.box {
position: fixed;
animation: slideUp 1s forwards;
}
@keyframes slideUp {
from { top: 100%; }
to { top: 0; }
}
Demo: http://jsfiddle.net/myajouri/Kvtd2/
If you want to slide relative to a parent element and not the viewport, use position: absolute
instead.
回答3:
Long time since this question was asked. But I'm seeing that nobody has answered the solution that I'll give you, and this one, in my opinion, is easier than creating different media-queries
for different screen sizes.
@myajouri proposed you to use a fixed
position and you discarded this solution because you need to use 3d transforms to get hardware acceleration. But you can still use 3d transforms with a fixed position. With CSS
transformations, if you use percentages, they will be relative to the size of the element itself. This will allow you to move the element from outside the screen no matter what size it has, so, only one keyframe animation is needed. Check the next snippet:
body {
margin: 0;
padding: 0;
}
.element {
animation: slideUp 1s ease-in-out infinite alternate;
background: #CCC;
border: 5px solid gray;
box-sizing: border-box;
height: 100%;
position: fixed;
width: 100%;
}
@keyframes slideUp {
from {
transform: translate3d(0, 100%, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
<div class="element" />
回答4:
If you have to use translate3d
to get hardware acceleration on mobile devices (as you mentioned), and given that you can't use at-rules inside @media
:
You could define one @keyframes
with large translateX
(say 5000px
) and change the animation-duration
based on the screen height to ensure the speed is more or less the same across the different heights.
I would also define height ranges (max-height
and min-height
) as opposed to upper limits (max-height
only) to prevent unwanted style overrides.
@keyframes slideUp {
from { transform: translate3d(0,5000px,0); }
to { transform: translate3d(0,0,0); }
}
.box { animation: slideUp 5s forwards; }
@media (min-height: 0) and (max-height: 500px) {
.box { animation-duration: 0.5s; }
}
@media (min-height: 501px) and (max-height: 750px) {
.box { animation-duration: 0.75s; }
}
@media (min-height: 751px) and (max-height: 1000px) {
.box { animation-duration: 1s; }
}
DEMO: http://jsfiddle.net/myajouri/9xLyf/
来源:https://stackoverflow.com/questions/20407906/defining-keyframe-animations-inside-media-queries