Перевести процентные значения X и Y в зависимости от высоты и ширины элементов?

80

Сдвиг элемента по оси Y на 50% переместит его вниз на 50% от его собственной высоты, а не на 50% от высоты родителей, как я ожидал. Как указать элементу перевода, чтобы он основывал процент перевода на родительском элементе? Или я чего-то не понимаю?

http://jsfiddle.net/4wqEm/2/

Эндрю Тиббетс
источник
6
Ладно, похоже, выхода нет. При преобразовании CSS в процентах используется% элемента, который переводится, для определения расстояния, на которое нужно переместиться. Он не действует как ваше типичное объявление css, такое как top, margin-top или padding-top, которые все основаны на родительском контейнере.
Эндрю Тиббетс,
1
Спасибо, мне не сразу было понятно, какое процентное значение составляет процент.
Филип Уолтон,
3
Следующее, что вы знаете, они также сделают проценты означать процент от размера шрифта! (ох ...)
Кевин Пено

Ответы:

41

При использовании процента в translate это относится к ширине или высоте самого себя. Взгляните на https://davidwalsh.name/css-vertical-center ( демо ):

Одна интересная особенность преобразований CSS заключается в том, что при их применении с процентными значениями они основывают это значение на размерах элемента, в котором они реализованы, в отличие от таких свойств, как верх, правый, нижний, левый, поля и отступы. , которые используют только размеры родителя (или в случае абсолютного позиционирования, которое использует его ближайшего относительного родителя).

Bowen
источник
2
Но при анимации SVG, transform: translate(50%)похоже, используется ширина и высота родительского элемента
Atav32
27

Вы можете использовать vw и vh для перевода в зависимости от размера области просмотра

@keyframes bubbleup {
  0% {
    transform: translateY(100vh);
  }

  100% {
    transform: translateY(0vh);
  }
}
Кокодоко
источник
У меня это не работает ... vh ~ 40 это как нижняя часть страницы ?!
AturSams
Это было мое плохое ... элемент не был внутри абсолютного элемента ... :)
AturSams
11
@AxeEffect Это недопустимый ответ. Это относительно области просмотра, а не родительского элемента. Что делать, если размер родительского элемента не соответствует размеру области просмотра?
trusktr 02
@wolfdawn, если вы используете масштабирование, порядок имеет значение. Итак, «scale (1.5) translateY (40vw)» - это не то же самое, что «translateY (40vw) scale (1.5)».
Kardaw
1
Вы должны знать, что Apple и Google сломали модуль vh в мобильных браузерах, поэтому в этом случае он ненадежен.
Кев
17

Что мне подходит, используя только CSS, так это:

.child {
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);

    /* Backward compatibility */
    -webkit-transform: translate(-50%, -50%);
    -moz-transform: translate(-50%, -50%);
    -o-transform: translate(-50%, -50%);
    -ms-transform: translate(-50%, -50%);
}

Как это устроено:

  • верхнее и левое позиционирование перемещают дочерний виджет в соответствии с родительскими координатами. Верхний левый угол дочернего виджета появится точно в центре родительского (это не то, что мы хотим сейчас).
  • translation переместит дочерний виджет на -50% вверх и влево в зависимости от его размера (не родительского). Это означает, что центральная точка виджета будет перемещена точно туда, где была верхняя левая точка, которая ранее была настроена как центр родителя, и это то, что мы хотим.
золв
источник
6

Чтобы использовать процент в свойстве translate, вы должны использовать Javascript: http://jsfiddle.net/4wqEm/27/

HTML код:

<div id="parent">
    <div id="children"></div>
</div>​​​​​​​​​​​​​

Код CSS:

#parent {
    width: 200px;
    height: 200px;
    background: #ff0;
}
#children {
    width: 10%;
    height: 10%;
    background: #f00;
}

Код Javascript:

parent = document.getElementById('parent');
children = document.getElementById('children');

parent_height = parent.clientHeight;
​children_translate = parent_height * 50/100;
children.style.webkitTransform = "translateY("+children_translate+"px)";​​​​​​​​​​​​​​​​​​​​​​​​​​

Я надеюсь, что смогу помочь вам и сказать мне, если у вас возникнут другие проблемы.

Лукас Виллемс
источник
1
я не могу сделать это только с CSS3?
Dchris
3
Это задержка (не ваш ответ, просто тот факт, что авторы спецификации не смогли сделать это в CSS и что мы должны использовать JS).
trusktr 02
3

Ваше утверждение абсолютно верно относительно процентов, исходящих от самого переведенного элемента. Вместо использования свойства translate в вашем случае вы должны использовать абсолютное позиционирование, чтобы оставаться относительно родительского div. Я абсолютно вертикально расположил ваш красный div здесь: (не забудьте добавить позицию относительно родительского div, он должен быть расположен не по умолчанию, а по умолчанию):

js скрипка здесь

 body {
    margin: 0;
    width: 100%;
    height: 100%;
    }
 body > div {
    width: 200px;
    height: 200px;
    background: #ff0;
    position: relative;
    }
 body > div > div {
    width: 10%;
    height: 10%;
    -webkit-transform: translateY(-50%);
    background: #f00;
    position: absolute;
    top: 50%;
    }
юлиал
источник
1
Но анимация сверху и слева не ускоряется аппаратно, не так ли?
trusktr 02
1

Вы также можете использовать один дополнительный блок и использовать для него переход, кроме дочернего узла

HTML код:

<div id="parent">
    <div id="childrenWrapper">    
        <div id="children"></div>
    </div>
</div>​​​​​​​​​​​​​

css должен быть примерно таким

#parent {
    position: relative;
    width: 200px;
    height: 200px;
    background: #ff0;
}
#childrenWrapper{
    width: 100%;
    height: 100%;
}
#children {
    width: 10%;
    height: 10%;
    background: #f00;
}
Петрик Пяточкин
источник
1

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

user4993573
источник
1

Его разветвляется с позиционированием, требуемым для следующего рабочего образца URL

body {
margin: 0;
width: 100%;
height: 100%;
}

body>div {
position: relative;
width: 200px;
height: 200px;
background: #ff0;
}

body>div>div {
position: absolute;
left: 50%;
top: 50%;
width: 10%;
height: 10%;
background: #f00;
transform: translate(-50%, -50%);
}

ноты :

  1. вы можете абсолютное позиционирование вашего красного квадрата, изменив родительский элемент на относительное положение
  2. затем использование 50% сверху и 50% слева поместит красный квадрат в соответствии с его верхним левым углом.
  3. с помощью transform: translate (-50%, - 50%) красный квадрат будет позиционироваться в соответствии с его центром
Мхмад К. Абдельхак
источник
0

Решение этой проблемы - вообще не использовать переводчик. Когда вы переводите элемент, процент, который вы выбираете, зависит от его собственной высоты.

Если вы хотите расположить элемент на основе высоты родителя, используйте top: 50%;

Итак, код будет выглядеть так:

body {
    margin: 0;
    width: 100%;
    height: 100%;
}
body > div {
    width: 200px;
    height: 200px;
    background: #ff0;
    position: relative;
}
body > div > div {
    position: absolute;
    top: 50%;
    width: 10%;
    height: 10%;
/*     -webkit-transform: translateY(50%); */
    background: #f00;
}
Влад
источник