Разверните div из середины вместо верхнего и левого, используя CSS - PullRequest
31 голосов
/ 10 декабря 2011

Я не уверен, возможно ли это, но я подумал, что было бы здорово использовать CSS-преобразования, чтобы создать эффект, когда div расширяется от его центра до заданной высоты и ширины, а не только из верхнего левого угла.

Например, если у меня есть ( demo )

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

и (префиксы поставщиков оставлены для краткости)

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

при наведении, это расширит квадрат вправо и вниз до 100px. Я бы хотел, чтобы он расширялся от середины.

Я знаю, что, возможно, я мог бы использовать transform: scale(x) ( demo ), но это не такдействительно предоставьте мне очень «идеальный по пикселям» макет (так как он основан на процентах), и он также не влияет на окружающий макет (настройте другие элементы, находящиеся в потоке документа, на его изменение размера).По сути, это то, что я хочу сделать, за исключением того, что соответствующим образом затронут поток документов.

Кто-нибудь знает способ сделать это без JavaScript ?

Ответы [ 4 ]

61 голосов
/ 10 декабря 2011

Ключ заключается в переходе поля по формуле.Есть небольшая «покачивание», которая раздражает во время перехода, если он плавает.

РЕДАКТИРОВАННЫЕ ВАРИАНТЫ ДОБАВЛЕНИЯ

Опция 1 : расширяется в пространстве, зарезервированном вокруг него 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) */
}

Опция 2 : расширяется над элементами вокруг него 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 */
}

Опция 3 : расширяет элементы перед ним в потоке и смещает элементы после него 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;
}

ДОБАВЛЕНО НЕ КВАДРАТНЫЙПРИМЕР

Был сделан комментарий, что он работает не для квадратов (одинаковая ширина / высота), а просто означает, что во время перехода нужно по-разному подстраиваться для каждого направления.Итак, вот Вариант 2 (с не квадратом) , который начинается как прямоугольник, а ширина увеличивается вдвое больше высоты (поэтому изменяется даже форма прямоугольника) во время перехода:Расширяется над элементами вокруг него 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) */
}

Если бы width также изменялся только на 100 пикселей (то есть с 110 на 210 пикселей), тогда просто margin: -50px все равно работал бы.

2 голосов
/ 10 декабря 2011

Вам также нужно будет изменить его положение, чтобы сделать это относительным / абсолютным и изменить значение top во время анимации.

(редактирование на основе комментария)

Вместо абсолютного позиционирования вы можете попытаться сделать то же самое с отрицательным верхним полем.Это будет держать его в потоке документов.Тем не менее, каким-то образом вам нужно переместить элемент div, а также анимировать высоту / ширину.

1 голос
/ 10 декабря 2011

вам, возможно, придется установить абсолютное положение деления, а затем настроить левое и верхнее положение при наведении курсора jsFiddle пример

0 голосов
/ 10 декабря 2011

Я делаю это, регулируя верхнее и левое выравнивание при наведении курсора.Пример: я добавлю 50 пикселей к ширине и переместу его влево на 25 пикселей, чтобы получить общий эффект расширения из середины.

...