对弹性框顺序使用过渡



有没有办法在弹性盒项目的顺序上进行过渡?

换句话说,我可以拥有这个(这个小提琴中的细节)

#container {
    display: flex;
}
#container:hover div:last-child {
    order: -1;
}

动画(获得新位置的元素会随着时间的推移假设它的位置),请问?

我并没有真正回答这个问题,因为我没有使用 order 属性

但我想做一些类似于你所期望的事情,最终决定:

  • 在 HTML 中,向元素添加 data-order 属性
  • 为每个元素位置添加 CSS 属性
  • 使用 Javascript 更改data-order
  • 使用 CSS 过渡进行插值

setInterval(changeOrder, 3000);
function changeOrder() {
  const allSlides = document.querySelectorAll(".single-slide");
  const previous = "1";
  const current = "2";
  const next = "3";
  for (const slide of allSlides) {
    const order = slide.getAttribute("data-order");
    switch (order) {
      case current:
        slide.setAttribute("data-order", previous);
        break;
      case next:
        slide.setAttribute("data-order", current);
        break;
      case previous:
        slide.setAttribute("data-order", next);
        break;
    }
  }
}
.all-slides {
  display: flex;
  width: 80vw;
  margin: 0 auto;
  perspective: 500px;
  height: 500px;
}
.single-slide {
  padding: 30px 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 30%;
  position: absolute;
  background-color: white;
  transition: 2s ease;
  box-shadow: 0px 5px 10px lightgrey;
}
/* Left slide*/
.single-slide[data-order="1"] {
  left: 10vw;
  transform: translate(-50%) scale(0.8, 0.8);
  z-index: 1;
  opacity: 0.7;
}
/* Middle slide */
.single-slide[data-order="2"] {
  left: 40vw;
  transform: translate(-50%);
  z-index: 3;
  opacity: 1;
}
/* Right slide*/
.single-slide[data-order="3"] {
  left: 90vw;
  transform: translate(-120%) scale(0.8, 0.8);
  z-index: 2;
  opacity: 0.7;
}
.single-slide:nth-child(2) {
  order: 3;
}
.single-slide:nth-child(1) {
  order: 2;
}
.single-slide:nth-child(3) {
  order: 1;
}
<div class="all-slides">
  <div class="single-slide" data-order="2">
    <h3>First slide </h3>
    <p>Some text</p>
  </div>
  <div class="single-slide" data-order="3">
    <h3>Second slide</h3>
    <p>Some other text</p>
  </div>
  <div class="single-slide" data-order="1">
    <h3>Third slide</h3>
    <p>Yet some other text</p>
  </div>
</div>

如果要对滑块(或其他任何内容)进行动画处理,但出于辅助功能目的,希望保留 HTML 中元素的顺序,这可能是 order 属性的有用用法之一,这可能很有用。见 https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items#The_order_property_and_accessibility

可悲的是没有:order 属性是可动画的,但只能作为整数。这意味着对于动画的每个步骤/帧,它将按地板将值插入到近东整数。因此,项目只会显示在计算的整数值产生的插槽中,永远不会以任何平滑的运动方式介于两者之间。

从技术上讲,它仍然是一个动画:计算出的整数位置仍应遵循动画的计时函数和关键帧规则,只是项目在变化时从一个位置"跳"到另一个位置。

见 https://developer.mozilla.org/en-US/docs/Web/CSS/integer#Interpolation

这个问题

现在已经很老了,但我最近用这个小提琴(改编自Jason在评论中发布的小提琴)测试了这个问题:http://jsfiddle.net/aqrxcd1u/(下面的代码)。

ChromeFirefox中,这都是部分动画,因为顺序一次从当前值过渡到目标值。这意味着它不是从 5->1 开始,而是从 5->4->3->2->1 开始。

在桌面 Safari 中,它仍然直接进入 5->1。

#container {
    display: flex;
}
#container div {
    width: 100px;
    height: 100px;
    margin-right: 10px;
    background-color: red;    
}
#container div:nth-child(even) {
    background-color: blue;
}
}
#container div:last-child {
    order: 5;
    transition: order 1s;
}
#container:hover div:last-child {
    order: -1 !important;
}
<div id="container">
    <div style="order: 1">Element 1A</div>
    <div style="order: 2">Element 2B</div>
    <div style="order: 3">Element 3C</div>
    <div style="order: 4">Element 4D</div>
    <div style="order: 5">Element 5E</div>
</div>
  • Jon z 建议可以通过内联样式设置变量;
  • 我们知道变形是一个动画效果很好的道具;
  • 我们知道我们有calc();

所以这是我基于上述内容创建的内容:

// Some simple logic that will "change the order of elements"
function shuffleThem() {
  var items = [...document.getElementsByClassName('item')];
  items.sort(() => Math.random() < 0.5 ? -1 : 1);
  items.forEach((item, index) => {
    item.style.setProperty('--order', index);
  })
}
.container {
  position: relative;
}
.placeholder {
  /*
  A .placeholder will push the .container's height
  while its .item is absolutely positioned inside.
  */
  background: red;
  width: 10rem;
  height: 3rem;
}
.item {
  /*
  All items are initially rendered at the top of the .container
  and are later transformed/translated to their ordered positions.
  */
  position: absolute;
  top: 0;
  width: 10rem;
  height: 3rem;
  
  transition: transform 0.5s ease;
  transform: translateY(calc(var(--order) * 100%));
    
  text-align: center;
  line-height: 3rem;
}
<button onclick="shuffleThem()">Shufle 🔀</button>
<br /><hr /><br />
<p>Content before the .container</p>
<div class="container">
  <div class="placeholder"></div>
  <div class="placeholder"></div>
  <div class="placeholder"></div>
  <div class="placeholder"></div>
  <div class="placeholder"></div>
  
  <div class="item" style="--order: 0; background: #FFBE66">A</div>
  <div class="item" style="--order: 1; background: #66FF9F">B</div>
  <div class="item" style="--order: 2; background: #FFFFFF">C</div>
  <div class="item" style="--order: 3; background: #FF8166">D</div>
  <div class="item" style="--order: 4; background: #70C1FF">E</div>
</div>
<p>Content after the .container</p>

并不是说它适合所有情况,但它确实适合我的情况。

  • 此方法的一个主要要求是知道(或确定)项目的高度,以便可以为它们提供占位符。
  • 该方法的一个主要缺陷是您无法使用弹性框的包装功能。您要么垂直(如示例中所示)重新排序,要么水平重新排序。

这与CodePen相同。

正如埃米尔所说,它只动画为整数。但是,我正在考虑一个黑客:

  • 将要显示的元素放在具有 1/10 height的包装器中,设置包装器overflow: visible
  • 然后在这些包装器之间放置 9 个间距元素,具有相同的height
  • ordertransition放在所有这些上。
  • 更改包装器的order并观察其"过渡"。

可悲的是,它很丑陋,只能在Firefox中使用。这是我在 Angular 中测试的内容

相关内容

  • 没有找到相关文章

最新更新