首页 > 解决方案 > CSS 过渡跳跃与最小宽度媒体查询

问题描述

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

在这里查看它的实际应用

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

该单元有一个width值,px但媒体查询设置了一个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值会破坏效果。

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

标签: htmljquerycssflexboxcss-transitions

解决方案


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

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

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


推荐阅读