2011-11-08 17 views
22

Versione corta e dolce assoluta e relativa:transizioni CSS miscelazione posizionamento

E 'possibile combinare position: relative e position: absolute con lisce CSS-transizioni?

versione verbose:

Sto creando un piccolo widget (io lo chiamo un ponte), che ho wan't essere in grado di avere uno stato compresso ed espanso. Tutto bene finora, funziona bene.

Il passaggio tra i due stati garantisce naturalmente un'animazione di transizione. Anche questo funziona, ma non nel modo in cui mi piacerebbe che fosse realizzato. Quello che mi piacerebbe fare è usare la transizione CSS, invece di usare il posizionamento assoluto usando JavaScript, come sono ora.

Purtroppo, lo scenario corrente è, in stato espanso, le carte nel mazzo sono sempre posizionate in modo assoluto, la loro posizione viene calcolata al volo mentre vengono aggiunte al mazzo. Quando collassano, i primi quattro vengono impilati in cascata e il resto sulla quarta carta. Imitando visivamente una pila.

Il problema con questo approccio è che non posso fare affidamento sul normale flusso di layout per posizionare le carte, il che fa schifo per molte ragioni. Se utilizzo lo position: relative per le carte in stato espanso, fluiscono piacevolmente uno dopo l'altro. Ma la transizione verso lo stato collassato non viene animata: semplicemente scattare da una posizione all'altra in un istante. Questo è naturalmente logico poiché senza posizionamento assoluto in primo luogo, il browser chiaramente non sa da dove passare.

Quello che ho finora è questo (Fiddle):

CSS (solo norme pertinenti):

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 (tag rilevante solo):

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

Nel mio perfetto mondo, aggiungendo la classe collapsed a div.deck-container animerebbe le carte nelle loro posizioni compresse e viceversa, ma sembra che ciò non sia possibile. Per favore qualcuno mi dica che ho torto.

risposta

36

No, non è possibile animare la proprietà position. Esistono solo un numero di proprietà CSS che è possibile animare e la maggior parte di esse ha numeri o colori come valori (con alcune eccezioni). È possibile visualizzare questo elenco nello w3c css transitions especification.

In ogni caso, dal momento che è possibile animare le proprietà top e left, è possibile modificare leggermente il markup per ottenere l'effetto, come 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; 
} 

me a impostare la posizione originaria di assoluta e posizionati tali elementi. Quindi, quando si attiva la classe, solo gli attributi top e left cambiano, quindi la transizione funziona.

+1

avevo paura di questo.Sono consapevole che è possibile utilizzare il posizionamento assoluto nello stato espanso per animare tra gli stati. Ma stando così le cose, mi trovo altrettanto bene, o anche meglio, con la mia attuale soluzione basata su JavaScript, dal momento che il numero di carte in un mazzo non è finito. –

+1

Ah, in tal caso avrai sicuramente bisogno di JS ... In ogni caso, come soluzione mista, puoi impostare le carte in alto e a sinistra usando JS, che potrebbe essere facile, e quindi animarle usando le transizioni. – scumah

+0

Le transizioni sono solo funzioni al passaggio del mouse? Posso spostare un test div # quando passo il mouse su div # hoverdiv? – ShibinRagh

15

@ nikc.org Forse si potrebbe usare translate invece:

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

+0

Questo è molto bello. Grazie. –

+0

Sì, questo ha fatto il trucco in uno scenario in cui la transizione non funzionava. –

Problemi correlati