Si observa las especificaciones del modelo de cuadro CSS , observará lo siguiente:
El porcentaje [margen] se calcula con respecto al ancho del bloque que contiene el cuadro generado. Tenga en cuenta que esto también es cierto para 'margin-top' y 'margin-bottom'. Si el ancho del bloque contenedor depende de este elemento, el diseño resultante no está definido en CSS 2.1. (énfasis mío)
Esto es de hecho cierto. Pero por que ? ¿Qué demonios obligaría a cualquiera a diseñarlo de esta manera? Es fácil pensar en los escenarios en los que desea, por ejemplo, que una cosa siempre esté un 25% por debajo de la parte superior de la página, pero es difícil encontrar alguna razón por la que desee que el relleno vertical sea relativo al tamaño horizontal de el padre.
Aquí hay un ejemplo del fenómeno al que me refiero:
<div style="border: 1px solid red; margin: 0; padding: 0; width: 200px; height: 800px;">
This div is 200x800.
<div style="border: 1px solid blue; margin: 10% 0 0 10%;">
This div has top-margin of 10% and left-margin of 10% with respect to its parent.
</div>
</div>
margin: 25%
realmente significa. No sería un margen uniforme, aunque el código lo sugiera. No tengo pruebas para respaldar esto, pero parece razonable.height: 10%; width: 10%
que tampoco obtendrás un elemento cuadrado.Note that in a horizontal flow, percentages on ‘margin-top’ and ‘margin-bottom’ are relative to the width of the containing block, not the height (and in vertical flow, ‘margin-left’ and ‘margin-right’ are relative to the height, not the width).
así lo dice en ambos sentidosRespuestas:
Transferir mi comentario a una respuesta, porque tiene sentido lógico. Sin embargo, tenga en cuenta que esta es una conjetura infundada. El razonamiento real de por qué la especificación se escribe de esta manera aún es, técnicamente, desconocido.
Actualización: las últimas dos oraciones pueden no ser del todo precisas. La altura del elemento de hoja (niño sin hijos) tiene un efecto sobre la altura de todos los elementos por encima, por lo que esto afecta a muchas situaciones diferentes.
fuente
h_p
. Un relleno superior del 10% hará que la altura del niñoh_c = h_ci + 0.1h_p
, dondeh_ci
es la altura interior del niño y no dependa de la altura del padre. Para un niño, simplemente encuentra la altura del padre de la ecuaciónh_p = h_ci + 0.1h_p
=>h_p = h_ci / 0.9
. Siempre puede hacer esto, sin importar cuántos hijos tenga, incluso para diferentes rellenos. Es solo una incógnita (h_p
) y una ecuación.width
resultados en el mismo problema horizontalmente.Para que el margen "n%" (y el relleno) sean los mismos para margen superior / margen derecho / margen inferior / margen izquierdo, los cuatro deben ser relativos a la misma base. Si arriba / abajo usara una base diferente a izquierda / derecha ', entonces el margen "n%" (y el relleno) no significarían lo mismo en los cuatro lados.
(También tenga en cuenta que tener el margen superior / inferior en relación con el ancho habilita un hack CSS extraño que le permite especificar un cuadro con una relación de aspecto inmutable ... incluso si el cuadro se vuelve a escalar).
fuente
padding: n [type]
. Por lo tanto, tendríapadding: 5% logical
(lo que sugiere el OP) en comparaciónpadding: 5% width
con el segundo parámetro predeterminado en "ancho" para la compatibilidad con versiones anteriores.Voto por la respuesta de @ChuckKollars después de jugar con este JSFiddle (en Chrome 46.0.2490.86) y hacer referencia a esta publicación (escrita en chino).
Una razón importante contra la conjetura de cálculo infinito es que: el uso de
width
caras es el mismo problema de cálculo infinito .Eche un vistazo a este JSFiddle , la
parent
pantallainline-block
es elegible para definir el margen / relleno en él. Elchild
tiene valor de margen20%
. Si seguimos la conjetura de cálculo infinito :child
depende de laparent
parent
depende de lachild
Pero como resultado, Chrome detiene el cálculo en alguna parte, lo que resulta:
Si intenta expandir el panel "resultado" horizontalmente en el JSFiddle, encontrará que el ancho de ellos no cambiará. Tenga en cuenta que el contenido en
child
está envuelto en dos líneas (no, por ejemplo, una línea), ¿por qué? Supongo que Chrome solo lo codifica en alguna parte. Si edita elchild
contenido para hacerlo más ( JSFiddle ), encontrará que mientras haya espacio adicional horizontalmente, Chrome mantiene el contenido en dos líneas.Entonces podemos ver: hay alguna forma de evitar el cálculo infinito .
Estoy de acuerdo con la conjetura de que: este diseño es solo para mantener los cuatro valores de margen / relleno basados en la misma medida.
Esta publicación (escrita en chino) también propone otra razón es que: se debe a la orientación de la lectura / composición tipográfica. Leemos de arriba a abajo, con el ancho fijo y la altura infinita (virtualmente).
fuente
Me doy cuenta de que el OP pregunta por qué la especificación CSS define los porcentajes de margen superior / inferior como un% de ancho (y no, como se supondría, altura), pero pensé que también podría ser útil publicar una solución potencial.
La mayoría de los navegadores modernos admiten vw y vh ahora, lo que le permite especificar números de margen contra el ancho y la altura de la vista.
100vw / 100vh equivale a 100% de ancho / 100% de altura (respectivamente) si no hay barra de desplazamiento; Si hay una barra de desplazamiento, los números de la ventana gráfica no tienen en cuenta esto (mientras que los números% sí). Afortunadamente, casi todos los navegadores usan tamaños de barra de desplazamiento de 17px ( ver aquí ), por lo que puede usar la función css calc para dar cuenta de esto. Si no sabe si aparecerá o no una barra de desplazamiento, esta solución no funcionará.
Por ejemplo: suponiendo que no haya una barra de desplazamiento horizontal, un margen superior del 50% de la altura podría definirse como "margin-top: 50vh;". Con una barra de desplazamiento horizontal, esto podría definirse como "margin-top: calc (0.5 * (100vh - 17px));" (¡recuerde que los operadores menos y más en calc requieren espacios en ambos lados!).
fuente