web-dev-qa-db-fra.com

Développez div à partir du milieu au lieu de simplement en haut et à gauche en utilisant CSS

Je ne sais pas si c'est possible, mais je pensais que ce serait cool d'utiliser des transformations CSS pour créer un effet où un div se dilate de son centre à une hauteur et une largeur prédéterminées, plutôt que juste à partir du coin supérieur gauche.

Par exemple, si j'ai ( démo )

<div id="square"></div>

et (les préfixes des fournisseurs ont été omis par souci de concision)

#square {
    width: 10px;
    height: 10px;
    background: blue;
    transition: width 1s, height 1s;
}
#square:hover {
    width: 100px;
    height: 100px;
}

En vol stationnaire, cela étendra le carré vers la droite et jusqu'à 100 pixels. Je voudrais qu'il se développe à partir du milieu.

Je suis conscient que je pourrais probablement utiliser transform: scale(x) ( demo ), mais cela ne me donne pas vraiment une disposition très "pixel parfaite" (car elle est basée sur un pourcentage ) et n'affecte pas non plus la mise en page environnante (faites en sorte que les autres éléments du flux de documents s'ajustent à son redimensionnement). C'est essentiellement ce que je veux faire, sauf avec le flux de documents affecté en conséquence.

Quelqu'un connaît-il un moyen de le faire sans javascript ?

31
Jason

La clé est de faire passer la marge par une formule. Il y a un petit "tremblement" qui est gênant pendant la transition s'il flotte.

OPTIONS D'AJOUT MODIFIÉES

Option 1: se développe dans l'espace réservé autour de lui http://jsfiddle.net/xcWge/ 14 / :

#square {
    width: 10px;
    height: 10px;
    margin: 100px; /*for centering purposes*/
    -webkit-transition: width 1s, height 1s, margin 1s;
    -moz-transition: width 1s, height 1s, margin 1s;
    -ms-transition: width 1s, height 1s, margin 1s;
    transition: width 1s, height 1s, margin 1s;
}
#square:hover {
    width: 100px;
    height: 100px;
    margin: 55px; /* initial margin - (width change (and/or height change)/2), so here 100px is initial margin, and the change is (100px final W/H - 10px initial W/H = 90px change, so 100px - (90px / 2 [= 45px]) = 55px) */
}

Option 2: se développe sur les éléments qui l'entourent http://jsfiddle.net/xcWge/18 / :

#square {
    width: 10px;
    height: 10px;
    margin: 0; /*for centering purposes*/
    -webkit-transition: width 1s, height 1s, margin 1s;
    -moz-transition: width 1s, height 1s, margin 1s;
    -ms-transition: width 1s, height 1s, margin 1s;
    transition: width 1s, height 1s, margin 1s;
}
#square:hover {
    width: 110px;
    height: 110px;
    margin: -50px; /* 0 - (110px - 10px [= 100px]) / 2 =  -50px */
}

Option 3: se développe sur les éléments avant lui dans le flux et décale les éléments après lui http: // jsfiddle.net/xcWge/22/ :

#square {
    width: 10px;
    height: 10px;
    margin: 0;
    position: relative;
    top: 0;
    left: 0;
    -webkit-transition: width 1s, height 1s, top 1s, left 1s, margin 1s;
    -moz-transition: width 1s, height 1s, top 1s, left 1s, margin 1s;
    -ms-transition: width 1s, height 1s, top 1s, left 1s, margin 1s ;
    transition: width 1s, height 1s, top 1s, left 1s, margin 1s;
}
#square:hover {
    width: 110px;
    height: 110px;
    top: -50px; /* initial top[0] - (new height[110px] - initial height[10px] [=100px])/2 [=50px] = -50px) */
    left: -50px; /* initial left[0] - (new width[110px] - initial width[10px] [=100px])/2 [=50px] = -50px) */
    margin-right: -50px;
    margin-bottom: -50px;
}

EXEMPLE NON CARRÉ AJOUTÉ

Un commentaire a été fait, cela ne fonctionne pas pour un non carré (même largeur/hauteur), mais cela signifie simplement qu'il faut ajuster différemment pour chaque direction pendant la transition. Voici donc Option 2 (avec non-carré) qui commence comme un rectangle, et la largeur augmente deux fois comme autant que la hauteur (change donc la forme du rectangle même) pendant la transition: se développe sur les éléments autour d'elle http://jsfiddle.net/xcWge/2131/

#rectangle {
    width: 110px;
    height: 10px;
    margin: 0; /*for centering purposes*/
    -webkit-transition: width 1s, height 1s, margin 1s;
    -moz-transition: width 1s, height 1s, margin 1s;
    -ms-transition: width 1s, height 1s, margin 1s;
    transition: width 1s, height 1s, margin 1s;
}
#rectangle:hover {
    width: 310px;
    height: 110px;
    margin: -50px -100px; /* initial margin - ((initial margin - width change (or height change))/2) */
}

Si le width ne changeait que de 100 px également (donc de 110 px à 210 px), alors juste un margin: -50px aurait encore fonctionné.

63
ScottS

Vous devrez également modifier sa position afin de le faire également, en le définissant sur relatif/absolu et en modifiant la valeur top lors de l'animation.

(modifier en fonction du commentaire)

Au lieu d'un positionnement absolu, vous pouvez essayer de faire la même chose avec une marge supérieure négative. Cela le garderait dans le flux de documents. D'une manière ou d'une autre, cependant, vous devez réellement déplacer le div ainsi que l'animation de la hauteur/largeur.

2
idrumgood

vous devrez peut-être rendre votre position div absolue, puis régler la position gauche et supérieure en survol. exemple jsFiddle

1
ONYX

Je le fais en ajustant également l'alignement supérieur et gauche en survol. Ex: je vais ajouter 50 px à la largeur et la déplacer vers la gauche de 25 px pour donner un effet global à partir du milieu.

0
bennett_an