Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS transitions mixing absolute and relative positioning

Short and sweet version:

Is it possible to combine position: relative and position: absolute with smooth CSS-transitions?

Verbose version:

I'm creating a small widget (I call it a Deck), which I wan't to be able to have a collapsed and expanded state. All well so far, this is working fine.

Switching between the two states, naturally warrants a transition animation. This is working too, but not the way I would like it to be realized. What I would like to do, is use CSS-transitioning, instead of using absolute positioning using JavaScript, like I am now.

Alas, the current scenario is, in expanded state the cards in the deck are always positioned absolutely, their position being calculated on the fly as they are added to the deck. When collapsing, the first four are stacked in a cascading manner and the rest on top of the fourth card. Visually mimicking a stack.

The problem with this approach is that I can't rely on normal layout flow for positioning the cards, which sucks for many reasons. If I use position: relative for the cards in expanded state, they flow nicely one after another. But the transition to collapsed state is not being animated - simply snapping from one position to the other in an instant. This is ofcourse logical since without absolute positioning in the first place, the browser clearly doesn't know from where to transition from.

What I have so far is this (Fiddle):

CSS (relevant rules only):

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 (relevant markup only):

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

In my perfect world, adding the class collapsed to div.deck-container would animate the cards into their collapsed positions and vice versa, but it seems this isn't possible. Please someone tell me I'm wrong.

like image 569
nikc.org Avatar asked Nov 08 '11 11:11

nikc.org


People also ask

How does absolute and relative positioning work together?

position: relative places an element relative to its current position without changing the layout around it, whereas position: absolute places an element relative to its parent's position and changing the layout around it.

Can a div be absolute and relative at the same time?

If you position it as relative , then you're moving it from its "normal" place (according to the page's flow). If you position it as absolute , then you're positioning it relative to its closest ancestor which is fixed or relative ... Clearly, nothing can be absolute and relative at the same time.

Can you have multiple transitions CSS?

You can transition two (or more) CSS properties by separating them with a comma in your transition or transition-property property. You can do the same with duration, timing-functions and delays as well. If the values are the same, you only need to specify one of them.

How do you move positions with absolute elements?

Absolute Positioning You can use two values top and left along with the position property to move an HTML element anywhere in the HTML document. Move Left - Use a negative value for left. Move Right - Use a positive value for left. Move Up - Use a negative value for top.


1 Answers

No, you can't animate the position property. There are only a number of css properties you can animate, and most of them have numbers or colors as values (With some exceptions). You can see this list in the w3c css transitions especification.

Anyway, since you can animate top and left properties, you could change your markup a little to achieve the effect, as in 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; } 

I just set the original position to absolute and positioned those elements. Then, when toggling the class, only topand left attributes change, so the transition works.

like image 104
scumah Avatar answered Sep 21 '22 16:09

scumah