绝对和相对定位之间的CSS转换



是否有可能将position: relativeposition: absolute与平滑的css过渡结合起来?

我正在创建一个小部件(我称之为Deck),我不想让它有一个折叠和展开的状态。到目前为止,一切正常。

在两种状态之间切换自然需要一个过渡动画。这也在起作用,但不是我想要的方式。我想使用css过渡,而不是使用绝对定位和JavaScript,就像我现在一样。

当前的场景是:在展开状态下,牌组中的牌总是处于绝对位置,它们的位置在添加到牌组时被动态计算。当折叠时,前四张以级联方式堆叠,其余的在第四张卡的顶部。视觉上模仿一堆或一堆。

这种方法的问题是,我不能依靠正常的布局流来定位卡牌,这有很多原因。如果我在扩展状态下使用position: relative,它们会一个接一个流畅地流动。但是,到崩溃状态的过渡并不是动画——只是瞬间从一个位置快速切换到另一个位置。这当然是合乎逻辑的,因为首先没有绝对定位,浏览器就不知道从哪里开始过渡。

在我的完美世界中,将collapsed类添加到div.deck-container将使卡片进入其崩溃位置,反之亦然,但似乎这是不可能的。请告诉我,我错了。

$('button#toggler').click(function() {
  $('div.deck-container').toggleClass('collapsed');
});
div.deck-container {
  position: relative;
}
div.deck-container li {
  display: inline-block;
  position: relative;
  transition: all 0.5s ease-in-out;
  border: 1px solid black;
  padding: 3px;
  background-color: #fff;
}
div.deck-container.collapsed li {
  position: absolute;
  left: 9px;
  top: 6px;
}
div.deck-container.collapsed li:first-child {
  left: 0;
  top: 0px;
}
div.deck-container.collapsed li:nth-child(2) {
  left: 3px;
  top: 2px;
}
div.deck-container.collapsed li:nth-child(3) {
  left: 6px;
  top: 4px;
}
button {
  position: absolute;
  top: 50px;
  left: 50px;
}
<div class="deck-container">
  <ul>
    <li>Card 1</li>
    <li>Card 2</li>
    <li>Card 3</li>
    <li>Card 4</li>
    <li>Card 5</li>
  </ul>
</div>
<button id="toggler">Toggle state</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

不,你不能动画position属性。只有一些css属性可以动画,大多数属性都有数字或颜色作为值(有一些例外)。你可以在w3c css过渡规范中看到这个列表。

无论如何,因为你可以动画topleft属性,你可以稍微改变你的标记来达到效果。

我只是将原始位置设置为绝对并定位这些元素。然后,当切换类时,只有topleft属性改变,因此转换工作。

$('button#toggler').click(function() {
  $('div.deck-container').toggleClass('collapsed');
});
div.deck-container {
  position: relative;
}
div.deck-container li {
  background-color: #fff;
  position: absolute;
  border: 1px solid black;
  padding: 3px;
  display: inline-block;
  transition: all 0.5s ease-in-out;
}
div.deck-container li {
  left: 160px;
  top: 0px;
}
div.deck-container li:first-child {
  left: 0px;
  top: 0px;
}
div.deck-container li:nth-child(2) {
  left: 40px;
  top: 0px;
}
div.deck-container li:nth-child(3) {
  left: 80px;
  top: 0px;
}
div.deck-container li:nth-child(4) {
  left: 120px;
  top: 0px;
}
div.deck-container.collapsed li {
  left: 12px;
  top: 8px;
}
div.deck-container.collapsed li:first-child {
  left: 0;
  top: 0px;
}
div.deck-container.collapsed li:nth-child(2) {
  left: 3px;
  top: 2px;
}
div.deck-container.collapsed li:nth-child(3) {
  left: 6px;
  top: 4px;
}
div.deck-container.collapsed li:nth-child(4) {
  left: 9px;
  top: 6px;
}
button {
  position: absolute;
  top: 50px;
  left: 50px;
}
<div class="deck-container">
  <ul>
    <li>Card 1</li>
    <li>Card 2</li>
    <li>Card 3</li>
    <li>Card 4</li>
    <li>Card 5</li>
  </ul>
</div>
<button id="toggler">Toggle state</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

也许你可以用translate代替:

$('button#toggler').click(function() {
  $('div.deck-container').toggleClass('collapsed');
});
div.deck-container li {
  background-color: #fff;
  border: 1px solid black;
  padding: 3px;
  display: inline-block;
  transition: all 0.5s ease-in-out;
}
div.deck-container.collapsed li:first-child {
  transform: translate(0, 0);
}
div.deck-container.collapsed li:nth-child(2) {
  transform: translate(-100%, 2px);
}
div.deck-container.collapsed li:nth-child(3) {
  transform: translate(-200%, 4px);
}
button {
  position: absolute;
  top: 50px;
  left: 50px;
}
<div class="deck-container">
  <ul>
    <li>Card 1</li>
    <li>Card 2</li>
    <li>Card 3</li>
  </ul>
</div>
<button id="toggler">Toggle state</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

相关内容

  • 没有找到相关文章

最新更新