CSS transitions jumping with min-width 媒体查询

CSS transitions jumping with min-width media queries

我有一个侧边栏导航栏,它可以折叠起来为弹性布局中的更多内容让路。当用户单击折叠导航时,内容区域 div .ca 扩展以填充 space 并且 flex 布局使用媒体查询重排。

See it in action here.

我已将 CSS 过渡应用到每个移动元素,但 .ca div 在导航打开和关闭时跳跃。这似乎与 flex 布局中单元的宽度有关 – .songgrid-unit.

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

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 值会破坏效果。

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

很难判断,因为您链接的网站上的代码与您在此处发布的代码有点不同。但在我看来 .ca div 实际上并没有跳跃,它只是看起来是因为随着网格内项目大小的变化,每行的项目数量也会发生变化。当项目占用更多 space 以便少一个可以放在一行中,或者占用更少 space 这样每行可以多一个时,就会发生跳跃。

我试了一下您在此处发布的代码,只是为了演示我认为正在发生的事情。我隐藏了导航并在 songgrid-container 和 dividual songgrid 项目周围添加了一些轮廓,然后我稍微放慢了过渡速度。因此,您可以按蓝色框并以慢动作查看过渡效果。看起来宽度都很好地过渡,它只是在布局不可避免地发生变化时跳跃。

不幸的是,我没有一个超级简单的解决方案,这不是您可以通过基本的 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>

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

按如下方式更新 .songgrid-unit class 的 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 的作者。