¿Traducir los valores porcentuales de X e Y según la altura y el ancho de los elementos?

80

La traducción del eje Y de un elemento al 50% lo moverá hacia abajo el 50% de su propia altura, no el 50% de la altura de los padres como es de esperar. ¿Cómo le digo a un elemento de traducción que base su porcentaje de traducción en el elemento principal? ¿O no estoy entendiendo algo?

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

Andrew Tibbetts
fuente
6
Muy bien, parece que no hay forma de evitarlo. La traducción CSS por porcentaje toma el% del elemento que se está traduciendo para calcular la distancia a mover. No actúa como su declaración css típica como top, margin-top o padding-top, que se basan en el contenedor principal.
Andrew Tibbetts
1
Gracias, no me di cuenta de inmediato de cuál era el valor porcentual.
Philip Walton
3
Lo siguiente que sabes es que también harán que los porcentajes signifiquen el porcentaje del tamaño de fuente. (oh ...)
Kevin Peno

Respuestas:

41

Cuando se usa el porcentaje en traducir, se refiere al ancho o alto de sí mismo. Eche un vistazo a https://davidwalsh.name/css-vertical-center ( demostración ):

Una cosa interesante acerca de las transformaciones CSS es que, al aplicarlas con valores porcentuales, basan ese valor en las dimensiones del elemento en el que se están implementando, a diferencia de propiedades como top, right, bottom, left, margin y padding. , que solo usa las dimensiones del padre (o en caso de posicionamiento absoluto, que usa su padre relativo más cercano).

Bowen
fuente
2
Pero al animar un SVG, transform: translate(50%)parece usar el ancho y la altura del elemento principal
Atav32
27

Puede usar vw y vh para traducir según el tamaño de la ventana gráfica

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

  100% {
    transform: translateY(0vh);
  }
}
Kokodoko
fuente
Esto no funciona para mí ... ¡¿vh ~ 40 es como la parte inferior de la página ?!
AturSams
Fue mi mal ... el elemento no estaba dentro de un elemento absoluto ... :)
AturSams
11
@AxeEffect Esta no debería ser la respuesta aceptada. Esto es relativo a la ventana gráfica, no al elemento principal. ¿Qué sucede si el elemento principal no tiene el tamaño completo de la ventana gráfica?
trusktr
@wolfdawn si usa escalado, el orden importa. Entonces, "scale (1.5) translateY (40vw)" no es lo mismo que "translateY (40vw) scale (1.5)".
Kardaw
1
Debe saber que Apple y Google han roto la unidad vh en los navegadores móviles y, por lo tanto, no es confiable en ese caso.
Kev
17

Lo que me funciona usando solo CSS es:

.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%);
}

Cómo funciona:

  • El posicionamiento superior e izquierdo mueve el widget secundario de acuerdo con las coordenadas principales. La esquina superior izquierda del widget secundario aparecerá exactamente en el centro del elemento principal (esto no es lo que queremos en este momento).
  • la traducción moverá el widget secundario -50% hacia la parte superior e izquierda según su tamaño (no el principal). Significa que el punto central del widget se moverá exactamente donde estaba el punto superior izquierdo, que anteriormente se configuró como el centro de un padre, y esto es lo que queremos.
zolv
fuente
6

Para usar el porcentaje en la propiedad de traducción, debe usar Javascript: http://jsfiddle.net/4wqEm/27/

Código HTML :

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

Código CSS:

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

Código 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)";​​​​​​​​​​​​​​​​​​​​​​​​​​

Espero poder ayudarte y decirme si tienes algún otro problema.

Lucas Willems
fuente
1
¿No puedo hacerlo solo con CSS3?
Dchris
3
Esto es retrasado (no es su respuesta, solo el hecho de que los autores de especificaciones no encontraron una manera de hacer esto en CSS y que tenemos que usar JS).
trusktr
3

Su declaración es absolutamente correcta sobre los porcentajes que provienen del elemento traducido. En lugar de usar la propiedad translate en su caso, debería usar el posicionamiento absoluto para permanecer en relación con el div principal. Absolutamente coloqué verticalmente su div rojo aquí: (no se olvide de agregar la posición relativa al div principal, debe colocarse de manera diferente a la predeterminada estática):

js fiddle pen aquí

 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%;
    }
iulial
fuente
1
Pero la animación superior e izquierda no se acelera por hardware, ¿verdad?
trusktr
1

También puede usar un bloque adicional y usar la transición para él, excepto el nodo secundario

Código HTML :

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

css debería ser algo como esto

#parent {
    position: relative;
    width: 200px;
    height: 200px;
    background: #ff0;
}
#childrenWrapper{
    width: 100%;
    height: 100%;
}
#children {
    width: 10%;
    height: 10%;
    background: #f00;
}
Petryk P'yatochkin
fuente
1

Puede hacer que el elemento esté en una posición absoluta y usar la propiedad izquierda y superior para tomar el valor porcentual como principal.

usuario4993573
fuente
1

Está bifurcado con el posicionamiento requerido en la siguiente muestra de trabajo de 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%);
}

notas:

  1. Puede posicionar en absoluto su cuadrado rojo cambiando el elemento principal a la posición relativa
  2. luego, usando 50% arriba y 50% a la izquierda colocará el cuadrado rojo de acuerdo con su esquina superior izquierda
  3. usando transform: translate (-50%, - 50%) colocará el cuadrado rojo de acuerdo con su centro
Mhmad Q.Abdelhaq
fuente
0

La solución a este problema es no utilizar la traducción en absoluto. Cuando traduce un elemento, el porcentaje que selecciona se basa en su propia altura.

Si desea colocar el elemento en función de la altura del padre, use top: 50%;

Entonces el código se verá así:

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;
}
Vlad
fuente