I\'m not sure if this is possible, but I thought it would be cool using CSS transforms to create an effect where a div expands from its center to a predetermined height and
You'll have to transition it's position in order to do this as well, setting it to relative/absolute and changing the top
value as it animates.
(edit based on comment)
Instead of absolute positioning, you could try to do the same sort of thing with a negative top margin. That would keep it in the document flow. Somehow, though, you need to actually move the div as well as animating the height/width.
I do this by adjusting the top and left alignment on hover also. Ex: i'll add 50 px to the width and move it left 25px to give the over all effect of it expaning from the middle.
you may have to make you're div position absolute and then adjust the left and top position on hover. jsFiddle example
The key is to transition the margin by a formula. There is a little "wiggle" that is annoying during the transition if it is floated.
EDITED ADDING OPTIONS
Option 1: Expands within space reserved around it 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: Expands over elements around it 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: Expands over elements before it in flow and shifts elements after it 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;
}
ADDED NON-SQUARE EXAMPLE
A comment was made this does not work for a non-square (same width/height), but that just means one has to adjust differently for each direction during the transition. So here is Option 2 (with non-square) that starts as a rectangle, and the width expands twice as much as the height (so changes rectangle shape even) during the transition: Expands over elements around it 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) */
}
If the width
were only changing by 100px also (so from 110px to 210px), then just a margin: -50px
would have still worked.