【问题标题】:Defining keyframe animations inside media queries在媒体查询中定义关键帧动画
【发布时间】:2021-09-14 07:12:39
【问题描述】:

我试图让对象从屏幕底部“滑入”,但由于我无法将屏幕高度作为 CSS 中的一个单位,因此我试图通过媒体查询来做到这一点,例如所以:

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

这不起作用(它使用slideUp 的第一个版本,无论高度如何),所以我假设关键帧一旦定义,就不能根据媒体查询被覆盖或重新分配?有什么方法可以实现这种效果(没有许多不同的关键帧设置并使用媒体查询为类分配适当的关键帧)?

【问题讨论】:

标签: css css-animations


【解决方案1】:

我不知道为什么没有其他人建议这样做,但是您可以在媒体查询中设置动画,而不是在媒体查询中设置关键帧。

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

【讨论】:

  • 再看一遍 - 我看到你确实在原始问题中提出了这个建议,但在某些情况下,这是唯一的方法
  • 很糟糕,你必须半复制代码,但是可以。
  • @Kyle Hawk 花点时间去看看那些顶级网站的混乱 CSS。这应该会让你感觉更好:)
【解决方案2】:

现在你可以使用原生 CSS 变量来解决这个问题。

在你的情况下:

@media(max-height:500px) {
    :root {
        --slide-up-y: 500px
    }
}

@media(max-height:750px) {
    :root {
        --slide-up-y: 750px
    }
}

@keyframes slideUp {
    0%    { transform: translate3d(0,var(--slide-up-y),0); }
    100%  { transform: translate3d(0,0,0); }
  }
}

【讨论】:

    【解决方案3】:

    不管屏幕或元素高度如何,一种向上滑动动画的方法是使用position: fixed

    .box {
        position: fixed;
        animation: slideUp 1s forwards;
    }
    
    @keyframes slideUp {
        from { top: 100%; }
        to { top: 0; }
    }
    

    演示: http://jsfiddle.net/myajouri/Kvtd2/

    如果您想相对于父元素而不是视口滑动,请改用position: absolute

    【讨论】:

    • 不幸的是,它需要在移动设备上快速,这意味着我需要使用 3d 变换来获得硬件加速。否则我会这样做。
    • 我明白了。为此,我刚刚发布了另一个答案。它需要一些实验才能获得您想要的结果,但我希望它对您有所帮助。
    • 你有相对于父元素滑动的例子吗?似乎需要更多 position: absolute jsfiddle.net/ypuun2xL
    • @Simon_Weaver 您主要还需要父级上的position: relative。以下是实现此目的的两种不同方法(根据您的需要,它可以变得更复杂/更简单):jsfiddle.net/ypuun2xL/3jsfiddle.net/ypuun2xL/4
    【解决方案4】:

    很久没问这个问题了。但我看到没有人回答我给你的解决方案,而在我看来,这个解决方案比为不同的屏幕尺寸创建不同的media-queries 更容易。

    @myajouri 建议您使用fixed 位置,但您放弃了此解决方案,因为您需要使用 3d 变换来获得硬件加速。但是您仍然可以使用具有固定位置的 3d 变换。使用CSS 转换,如果您使用百分比,它们将与元素本身的大小相关。这将允许您从屏幕外部移动元素,无论其大小如何,因此只需要一个关键帧动画。检查下一个sn-p:

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

    【讨论】:

      【解决方案5】:

      如果您必须使用translate3d 在移动设备上获得硬件加速(如您所述),并且您不能在@media 中使用at-rules:

      您可以定义一个@keyframes 和大translateX(比如5000px)并根据屏幕高度更改animation-duration,以确保不同高度上的速度大致相同。

      我还将定义高度范围(max-heightmin-height)而不是上限(仅限max-height),以防止不必要的样式覆盖。

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

      演示: http://jsfiddle.net/myajouri/9xLyf/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-14
        • 1970-01-01
        • 2016-12-12
        • 2011-10-17
        • 2019-12-25
        • 1970-01-01
        • 2014-02-14
        • 2014-09-27
        相关资源
        最近更新 更多