【问题标题】:CSS transitions between absolute and relative positioningCSS过渡混合绝对和相对定位
【发布时间】:2011-12-24 09:24:28
【问题描述】:

短而甜的版本:

是否可以将 position: relativeposition: absolute 与平滑的 CSS 过渡结合起来?

详细版:

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

在两种状态之间切换,自然需要过渡动画。这也有效,但不是我希望实现的方式。我想做的是使用 CSS 转换,而不是像现在这样使用 JavaScript 使用绝对定位。

唉,目前的情况是,在展开状态下,牌组中的牌总是绝对定位,它们的位置是在添加到牌组时动态计算的。折叠时,前四张以级联方式堆叠,其余在第四张牌的顶部。在视觉上模仿堆栈。

这种方法的问题是我不能依靠正常的布局流程来定位卡片,这有很多原因很糟糕。如果我将position: relative 用于展开状态的卡片,它们会一个接一个地流畅地流动。但是到折叠状态的过渡并没有动画 - 只是在瞬间从一个位置捕捉到另一个位置。这当然是合乎逻辑的,因为首先没有绝对定位,浏览器显然不知道从哪里过渡。

我目前拥有的是这个 (Fiddle):

CSS(仅相关规则):

div.deck-container {
    position: relative;
}
div.deck-container li {
    display: inline-block;
    position: relative;

    -webkit-transition: all 0.5s ease-in-out;
    -moz-transition: all 0.5s ease-in-out;
    -o-transition: all 0.5s ease-in-out;
    -ms-transition: all 0.5s ease-in-out;
    transition: all 0.5s ease-in-out;
}
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;
}

HTML(仅相关标记):

<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>

在我的完美世界中,将 collapsed 类添加到 div.deck-container 会使卡片动画化到它们的折叠位置,反之亦然,但这似乎是不可能的。请有人告诉我我错了。

【问题讨论】:

    标签: css-transitions css


    【解决方案1】:

    不,您不能为 position 属性设置动画。只有一些 css 属性可以设置动画,并且大多数都具有数字或颜色作为值(有一些例外)。你可以在w3c css transitions especification看到这个列表。

    无论如何,由于您可以为topleft 属性设置动画,因此您可以稍微更改标记以达到效果,如this fiddle

    div.deck-container {
        position: relative;
    }
    div.deck-container li {
        background-color: #fff;
        position: absolute;
        border: 1px solid black;
        padding: 3px;
        display: inline-block;
        -webkit-transition: all 0.5s ease-in-out;
        -moz-transition: all 0.5s ease-in-out;
        -o-transition: all 0.5s ease-in-out;
        -ms-transition: all 0.5s ease-in-out;
        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;
    }
    

    我只是将原始位置设置为绝对位置并定位这些元素。然后,当切换类时,只有 topleft 属性发生变化,所以转换起作用。

    【讨论】:

    • 我害怕这个。我知道可以通过在展开状态下使用绝对定位来在状态之间设置动画。但在这种情况下,我和我当前的 JavaScript 驱动解决方案一样好——甚至更好——因为一副牌中的卡片数量不是有限的。
    • 啊,在那种情况下,你肯定需要 JS ......无论如何,作为一个混合解决方案,你可以使用 JS 设置卡片的顶部和左侧位置,这可能很容易,然后使用动画它们过渡。
    • 过渡是否只有悬停功能?当我将鼠标悬停在 div#hoverdiv 上时,我可以移动 div#test 吗?
    • 这很漂亮
    【解决方案2】:

    @nikc.org 也许你可以改用translate

        div.deck-container {
            position: relative;
        }
        div.deck-container li {
            background-color: #fff;
            position: relative;
            border: 1px solid black;
            padding: 3px;
            display: inline-block;
            -webkit-transition: all 0.5s ease-in-out;
            -moz-transition: all 0.5s ease-in-out;
            -o-transition: all 0.5s ease-in-out;
            -ms-transition: all 0.5s ease-in-out;
            transition: all 0.5s ease-in-out;
        }
    
        div.deck-container.collapsed li:first-child {
          -webkit-transform: translate(0, 0);
             -moz-transform: translate(0, 0);
              -ms-transform: translate(0, 0);
               -o-transform: translate(0, 0);
                  transform: translate(0, 0);
        }
        div.deck-container.collapsed li:nth-child(2) {
            -webkit-transform: translate(-100%, 2px);
             -moz-transform: translate(-100%, 2px);
              -ms-transform: translate(-100%, 2px);
               -o-transform: translate(-100%, 2px);
                  transform: translate(-100%, 2px);
        }
        div.deck-container.collapsed li:nth-child(3) {
            -webkit-transform: translate(-200%, 4px);
             -moz-transform: translate(-200%, 4px);
              -ms-transform: translate(-200%, 4px);
               -o-transform: translate(-200%, 4px);
                  transform: translate(-200%, 4px);
        }
    

    working example

    【讨论】:

    • 是的,这在过渡不起作用的情况下起到了作用。
    猜你喜欢
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 2013-01-25
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多