Si vous regardez la spécification du modèle de boîte CSS , vous observerez ce qui suit:
Le pourcentage de [marge] est calculé par rapport à la largeur du bloc contenant de la boîte générée. Notez que cela est également vrai pour «margin-top» et «margin-bottom». Si la largeur du bloc conteneur dépend de cet élément, la mise en page résultante n'est pas définie dans CSS 2.1. (c'est moi qui souligne)
C'est en effet vrai. Mais pourquoi ? Qu'est-ce qui obligerait quelqu'un à le concevoir de cette façon? Il est facile de penser à des scénarios où vous voulez, par exemple, une certaine chose doit toujours être 25% en dessous du haut de la page, mais il est difficile de trouver une raison pour laquelle vous voudriez que le remplissage vertical soit relatif à la taille horizontale de le parent.
Voici un exemple du phénomène auquel je fais référence:
<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%
signifie réellement. Ce ne serait pas une marge égale, même si le code le suggère. Je n'ai aucune preuve à l'appui, mais cela semble raisonnable.height: 10%; width: 10%
vous n'obtiendrez pas d'élément carré non plus.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).
donc ça va dans les deux sensRéponses:
Transférer mon commentaire à une réponse, car cela a un sens logique. Cependant, veuillez noter qu'il s'agit d'une conjecture infondée. Le raisonnement réel pour lequel la spécification est écrite de cette manière est encore, techniquement, inconnu.
Mise à jour: les deux dernières phrases peuvent ne pas être tout à fait exactes. La hauteur de l'élément feuille (enfant sans enfant) a un effet sur la hauteur de tous les éléments au-dessus, donc cela affecte de nombreuses situations différentes.
la source
h_p
. Un haut de remplissage de 10% fera la hauteur de l'enfanth_c = h_ci + 0.1h_p
, oùh_ci
est la hauteur intérieure de l'enfant et ne dépend pas de la hauteur du parent. Pour un enfant, vous trouvez simplement la hauteur du parent à partir de l'équationh_p = h_ci + 0.1h_p
=>h_p = h_ci / 0.9
. Vous pouvez toujours le faire, quel que soit le nombre d'enfants que vous avez, même pour un rembourrage différent. C'est juste une inconnue (h_p
) et une équation.width
résultats dans le même problème horizontalement.Pour que la marge "n%" (et le remplissage) soient les mêmes pour margin-top / margin-right / margin-bottom / margin-left, les quatre doivent être relatifs à la même base. Si haut / bas utilisait une base différente de gauche / droite ', alors la marge "n%" (et le remplissage) ne signifierait pas la même chose sur les quatre côtés.
(Notez également que le fait d'avoir la marge supérieure / inférieure par rapport à la largeur permet un étrange hack CSS qui vous permet de spécifier une boîte avec un rapport hauteur / largeur inchangé ... même si la boîte est redimensionnée.)
la source
padding: n [type]
. Donc, vous auriezpadding: 5% logical
(ce que l'OP suggère) par opposition aupadding: 5% width
deuxième paramètre par défaut à "width" pour une compatibilité ascendante.Je vote pour la réponse de @ChuckKollars après avoir joué avec ce JSFiddle (sur Chrome 46.0.2490.86) et me référer à ce post (écrit en chinois).
Une raison majeure contre la conjecture de calcul infini est que: utiliser des
width
faces le même problème de calcul infini .Jetez un œil à ce JSFiddle , l'
parent
affichage estinline-block
, qui est éligible pour définir une marge / un remplissage sur celui-ci. Lechild
a une valeur de marge20%
. Si nous suivons la conjecture de calcul infinie :child
dépend de laparent
parent
dépend de lachild
Mais en conséquence, Chrome arrête le calcul quelque part, ce qui entraîne:
Si vous essayez d'agrandir le panneau "résultat" horizontalement sur le JSFiddle, vous constaterez que leur largeur ne changera pas. Veuillez noter que le contenu de
child
est enveloppé dans deux lignes (pas, disons, une ligne), pourquoi? Je suppose que Chrome le code en dur quelque part. Si vous modifiez lechild
contenu pour le rendre plus ( JSFiddle ), vous constaterez que tant qu'il y a de l'espace supplémentaire horizontalement, Chrome conserve le contenu sur deux lignes.Nous pouvons donc voir: il existe un moyen d'empêcher le calcul infini .
Je suis d'accord avec la conjecture que: cette conception consiste simplement à conserver les quatre valeurs de marge / remplissage basées sur la même mesure.
cet article (écrit en chinois) propose également une autre raison: c'est à cause de l'orientation lecture / composition. Nous lisons de haut en bas, avec la largeur fixe et la hauteur infinie (virtuellement).
la source
Je me rends compte que l'OP demande pourquoi la spécification CSS définit les pourcentages de marge haut / bas comme un% de la largeur (et non, comme on pourrait le supposer, la hauteur), mais j'ai pensé qu'il pourrait également être utile de publier une solution potentielle.
La plupart des navigateurs modernes prennent désormais en charge vw et vh, ce qui vous permet de spécifier des numéros de marge par rapport à la largeur et à la hauteur de la fenêtre.
100vw / 100vh équivaut à 100% de largeur / 100% de hauteur (respectivement) s'il n'y a pas de barre de défilement; s'il y a une barre de défilement, les numéros de la fenêtre n'en tiennent pas compte (contrairement aux nombres%). Heureusement, presque tous les navigateurs utilisent des barres de défilement de 17 pixels ( voir ici ), vous pouvez donc utiliser la fonction css calc pour en tenir compte. Si vous ne savez pas si une barre de défilement apparaîtra ou non, cette solution ne fonctionnera pas.
Par exemple: en supposant qu'il n'y a pas de barre de défilement horizontale, une marge supérieure de 50% de la hauteur pourrait être définie comme "margin-top: 50vh;". Avec une barre de défilement horizontale, cela pourrait être défini comme "margin-top: calc (0.5 * (100vh - 17px));" (rappelez-vous que les opérateurs moins et plus dans calc nécessitent des espaces des deux côtés!).
la source