У меня есть элемент position: fixed; в правом верхнем углу страницы.
Я хочу, чтобы он «рос и двигался» к центру экрана при нажатии.
Лучшее решение, которое я знаю, чтобы разместить что-то в мертвом центре страницы, это
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
Все отлично работает, если элемент изначально позиционируется со свойствами top и left, но в анимации возникает неприятный скачок, если элемент изначально позиционируется со right вместо left.
const myFunc = function() {
let f = document.getElementById('element')
if (f.className.includes('bar')) {
f.className = 'foo'
} else {
f.className = 'foo bar'
}
}.wrapper {
position: relative;
width: 100%;
height: 100%;
}
.foo {
position: fixed;
top: 20px;
right: 20px;
width: 200px;
height: 50px;
background-color: blue;
transition: 0.5s all;
}
.bar {
position: fixed;
top: 50%;
left: 50%;
width: 500px;
height: 500px;
background-color: red;
transform: translate(-50%, -50%);
transition: 0.5s all;
}<div class = "wrapper">
<div class = "foo" id = "element" onclick = "myFunc()">
</div>
</div>Как избавиться от начального прыжка в анимации к горизонтальному центру? (т.е. я хочу обратное «сжатие назад вверху справа», здесь все работает нормально).
см. codepen.io/anon/pen/LoVzrR
Сукин сын, клянусь, я пробовал все варианты этого ;-) Спасибо!






Вам просто нужно изменить справа налево в состоянии foo.
Это также означает, что вы измените свойство translate на: translate(50%,-50%);, поскольку значение tanslateX должно быть слева направо, чтобы центрировать элемент:
const myFunc = function () {
let f = document.getElementById('element')
if (f.className.includes('bar')) {
f.className = 'foo'
}
else {
f.className = 'foo bar'
}
}.wrapper {
position: relative;
width: 100%;
height: 100%;
}
.foo {
position: fixed;
top: 20px;
right: 20px;
width: 200px;
height: 50px;
background-color: blue;
transition: 0.5s all;
}
.bar {
position: fixed;
top: 50%;
right: 50%;
width: 500px;
height: 500px;
background-color: red;
transform: translate(50%, -50%);
transition: 0.5s all;
}<div class = "wrapper">
<div class = "foo" id = "element" onclick = "myFunc()">
</div>
</div>Кстати, если вы знаете размер вашего элемента в обоих состояниях, вы можете сделать переход только в верхнем и правом свойствах, используя calc() следующим образом:
const myFunc = function() {
let f = document.getElementById('element')
if (f.className.includes('bar')) {
f.className = 'foo'
} else {
f.className = 'foo bar'
}
}.wrapper {
position: relative;
width: 100%;
height: 100%;
}
.foo {
position: fixed;
top: 20px;
right: 20px;
width: 200px;
height: 50px;
background-color: blue;
transition: 0.5s all;
}
.bar {
position: fixed;
top: calc(50% - 250px);
right: calc(50% - 250px);
width: 500px;
height: 500px;
background-color: red;
transition: 0.5s all;
}<div class = "wrapper">
<div class = "foo" id = "element" onclick = "myFunc()">
</div>
</div>Это изменяет траекторию анимации и предотвращает анимацию элемента в одном направлении вверх/вправо и в другом одновременно с помощью свойства transform.
Признаюсь, поначалу это доставляло мне некоторые неудобства, но с некоторой настойчивостью я смог доставить тебя туда, лол.
Это потому, что вы не даете переходу CSS отправную точку, с которой можно связать позиционирование свойства right. Вы переключились с присвоения элементу right свойства 20px на left свойство 50%. Для желаемого эффекта вам нужно задать начальную right позицию 20px и окончаниеright позицию 50% для .bar (избавившись от left: 50%;).
Теперь, после того, как вы исправите вышеупомянутую проблему, вам нужно обратиться к методу .bar класса transform, создав его transform: translate(50%, -50%); Это потому, что мы перешли на использование right позиционирования по оси x, поэтому нам нужно, чтобы он шел 50% справа , а не -50% (что заставит элемент уйти за пределы экрана -50% пространства из мертвой точки родителя).
Вот ваша новая живая демонстрация. Я надеюсь, что это имеет смысл :) CSS логически требует, чтобы все переходы имели начальную точку и действительную, совместную конечную точку. Некоторые браузеры делают предположение за вас, но они никогда не должны этого делать, потому что это затормозит кросс-платформенную разработку.
@TommyF, ты проверяешь мой ответ?
при использовании
rightвы можете использоватьtop: 50%; right: 50%; transform: translate(50%, -50%);?