【问题标题】:CSS transitions jumping with min-width media queriesCSS 过渡跳跃与最小宽度媒体查询
【发布时间】:2023-03-14 20:16:01
【问题描述】:

我有一个侧边栏导航,它可以折叠以便在 flex 布局中为更多内容让路。当用户单击折叠导航时,内容区域 div .ca 会展开以填充空间,并且使用媒体查询重新排列 flex 布局。

See it in action here.

我已经对每个移动元素应用了 CSS 过渡,但是当导航打开和关闭时,.ca div 会跳转。这似乎与 flex 布局中单元的宽度有关——.songgrid-unit

该单元在px 中有一个width 值,但媒体查询在% 中设置了一个min-width 值来覆盖它,以避免断点之间出现大的空白:

html:

<div class="navbar open ease">
 <div class="nav-toggle">
  <div class="nt-wrap">
   <div class="nt-bar ease" id="ntb-top"></div>
   <div class="nt-bar ease" id="ntb-bot"></div>
  </div>
 </div>
</div>
<div class="ca ease">
 <div class="songgrid ease">
  <div class="songgrid-unit ease">
   <!-- post content -->
  </div>
  <div class="songgrid-unit ease">
   <!-- post content -->
  </div>
  <div class="songgrid-unit ease">
   <!-- post content -->
  </div>
 </div>
</div>

CSS:

.navbar {
 position: fixed;
 display: flex;
 flex-direction: column;
 justify-content: space-between;
 width: 214px;
 height: 100vh;
 left: 0;
 top: 0;
 box-sizing: border-box;
 padding: 48px 8px 48px 32px;
 background-color: #282828;
 border-right: solid 1px #555;
 z-index: 20;
}
.navbar.closed {
 left: -214px;
}
.ca {
 position: relative;
 width: 100%;
 padding: 48px 32px 48px 280px;
 box-sizing: border-box; /*keep padding inside width*/
}
.ca.fullwidth {
 width: 100%;
 padding: 48px 32px 48px 64px;  
}
.songgrid {
 flex: 1;
 display: flex;
 justify-content: flex-end;
 flex-wrap: wrap;
}
.songgrid-unit {
 width: 280px;
 box-sizing: border-box;
 padding: 0 16px 48px;
 display: flex;
 flex-direction: column;
 justify-content: space-between;
}

/*adjust no. of cols as per screen width in both container widths*/
@media only screen and (max-width: 623px) {
 .ca.fullwidth .songgrid-unit {
  min-width: 100%;
 }
}
@media screen and (min-width: 624px) and (max-width: 904px) {
 .songgrid-unit {
  min-width: 100%;
 }
 .ca.fullwidth .songgrid-unit {
  min-width: 50%;
 }
}
@media screen and (min-width: 905px) and (max-width: 1184px) {
 .songgrid-unit {
  min-width: 50%;
 }
 .ca.fullwidth .songgrid-unit {
  min-width: 33%;
 }
}
@media screen and (min-width: 1185px) and (max-width: 1464px) {
 .songgrid-unit {
  min-width: 33%;
 }
 .ca.fullwidth .songgrid-unit {
  min-width: 25%;
 }
}
@media screen and (min-width: 1465px) and (max-width: 1744px) {
 .songgrid-unit {
  min-width: 25%;
 }
 .ca.fullwidth .songgrid-unit {
  min-width: 20%;
 }
}
@media only screen and (min-width: 1745px) and (max-width: 1949px) {
 .songgrid-unit {
  min-width: 20%;
 }
 .ca.fullwidth .songgrid-unit {
  min-width: 16.66667%;
 }
}
@media only screen and (min-width: 1950px) {
 .songgrid-unit {
  min-width: 16.66667%;
 }
 .ca.fullwidth .songgrid-unit {
  min-width: 14.285%;
 }
}
.ease {
 transition: all 0.4s ease-in 0s;
 -webkit-backface-visibility: hidden;
}

jQuery:

$(".nav-toggle").click(function(){
 $(".navbar").toggleClass("open closed");
 $(".ca").toggleClass("fullwidth");
});

如果我删除媒体查询,转换效果很好,但 min-width 值会破坏效果。

为什么会发生这种情况,我该如何解决?谢谢。

【问题讨论】:

    标签: html jquery css flexbox css-transitions


    【解决方案1】:

    很难说,因为您链接的网站上的代码与您在此处发布的代码有些不同。但在我看来,.ca div 实际上并没有跳跃,它只是因为网格内的项目大小发生变化,每行项目的数量发生变化。当项目要么占用更多空间以便可以在一行中容纳更少的项目,或者占用更少的空间以便每行可以容纳更多项目时,就会发生跳跃。

    我使用了您在此处发布的代码,只是为了演示我认为正在发生的事情。我隐藏了导航并在歌曲网格容器和单个歌曲网格项目周围添加了一些轮廓,然后我放慢了过渡速度。因此,您可以按下蓝色框,查看慢动作中的过渡效果。看起来宽度都过渡得很好,当布局不可避免地发生变化时它只是跳跃。

    不幸的是,我没有一个超级简单的解决方案,这不是你可以通过基本的 CSS 过渡来控制的。但也许看看这样的库:https://isotope.metafizzy.co/

    我实际上并不认为媒体查询与它有任何关系,但我也可能完全误解了您所看到的效果!

    $(".nav-toggle").click(function(){
    // $(".navbar").toggleClass("open closed");
     $(".ca").toggleClass("fullwidth");
    });
    .navbar {
     position: fixed;
     display: flex;
     flex-direction: column;
     justify-content: space-between;
     width: 214px;
     height: 100vh;
     left: 0;
     top: 0;
     box-sizing: border-box;
     padding: 48px 8px 48px 32px;
     background-color: #282828;
     border-right: solid 1px #555;
     z-index: 20;
      left: -214px;
    
    }
    .nav-toggle {
    width: 50px;
    height: 50px;
    background-color: blue;
    position: absolute;
    right: -50px;
    }
    .navbar.closed {
     left: -214px;
    }
    .ca {
     position: relative;
     width: 100%;
     padding: 48px 32px 48px 280px;
     background: lightblue;
     box-sizing: border-box; /*keep padding inside width*/
    }
    
    .ca.fullwidth {
     width: 100%;
     padding: 48px 32px 48px 64px;  
    }
    .songgrid {
     flex: 1;
     display: flex;
     justify-content: flex-end;
     flex-wrap: wrap;
     outline: 2px solid blue;
    }
    .songgrid-unit {
     width: 280px;
     box-sizing: border-box;
     padding: 0 16px 48px;
     display: flex;
     flex-direction: column;
     justify-content: space-between;
     background: rgba(255,255,255,.5);
     outline: 2px solid gray;
    }
    
    
    /*adjust no. of cols as per screen width in both container widths*/
    @media only screen and (max-width: 623px) {
     .ca.fullwidth .songgrid-unit {
      min-width: 100%;
     }
    }
    @media screen and (min-width: 624px) and (max-width: 904px) {
     .songgrid-unit {
      min-width: 100%;
     }
     .ca.fullwidth .songgrid-unit {
      min-width: 50%;
     }
    }
    @media screen and (min-width: 905px) and (max-width: 1184px) {
     .songgrid-unit {
      min-width: 50%;
     }
     .ca.fullwidth .songgrid-unit {
      min-width: 33%;
     }
    }
    @media screen and (min-width: 1185px) and (max-width: 1464px) {
     .songgrid-unit {
      min-width: 33%;
     }
     .ca.fullwidth .songgrid-unit {
      min-width: 25%;
     }
    }
    @media screen and (min-width: 1465px) and (max-width: 1744px) {
     .songgrid-unit {
      min-width: 25%;
     }
     .ca.fullwidth .songgrid-unit {
      min-width: 20%;
     }
    }
    @media only screen and (min-width: 1745px) and (max-width: 1949px) {
     .songgrid-unit {
      min-width: 20%;
     }
     .ca.fullwidth .songgrid-unit {
      min-width: 16.66667%;
     }
    }
    @media only screen and (min-width: 1950px) {
     .songgrid-unit {
      min-width: 16.66667%;
     }
     .ca.fullwidth .songgrid-unit {
      min-width: 14.285%;
     }
    }
    .ease {
     transition: all 3s ease-in 0s;
     -webkit-backface-visibility: hidden;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <html>
    <body>
    <div class="navbar open ease">
     <div class="nav-toggle">
      click
     </div>
    </div>
    <div class="ca ease">
     <div class="songgrid ease">
      <div class="songgrid-unit ease">
      content
      </div>
      <div class="songgrid-unit ease">
      content
      </div>
      <div class="songgrid-unit ease">
      content
      </div>
     </div>
    </div>
    </body>
    </html>

    【讨论】:

    • 是的——我在发帖后一直在摆弄这个,一定是改了几处 CSS。为混乱道歉。是的,当然——改变柱子的数量会打断平滑的运动。媒体查询会影响这一点是有道理的,因为它们是导致这种变化的原因。听起来JS可能是这样做的唯一方法。非常感谢您帮助我诊断。
    【解决方案2】:

    在从@sparrow 的回复中找到正确路径的帮助下,我发现通过将更多的flex 属性应用于在网格中创建列的项目,可以使过渡更加平滑。

    如下更新 .songgrid-unit 类的 CSS 可修复该问题:

    .songgrid-unit {
     width: 280px;
     box-sizing: border-box;
     padding: 0 16px 48px;
     display: flex;
     flex-grow: 1;       /*new line*/
     flex-shrink: 1;     /*new line*/
     flex-basis: auto;   /*new line*/
     flex-direction: column;
     justify-content: space-between;
    }
    

    感谢@sparrow 和this thread 的作者。

    【讨论】:

      猜你喜欢
      • 2012-03-19
      • 1970-01-01
      • 2012-05-05
      • 2017-07-29
      • 2013-11-19
      • 2012-12-12
      • 2012-07-09
      • 2014-03-10
      相关资源
      最近更新 更多