Le modèle de boîte CSS est plutôt compliqué, en particulier en ce qui concerne le défilement du contenu. Alors que le navigateur utilise les valeurs de votre CSS pour dessiner des boîtes, déterminer toutes les dimensions à l'aide de JS n'est pas simple si vous ne disposez que du CSS.
C'est la raison pour laquelle chaque élément a six propriétés DOM pour votre confort: offsetWidth
, offsetHeight
, clientWidth
, clientHeight
, scrollWidth
et scrollHeight
. Il s'agit d'attributs en lecture seule représentant la disposition visuelle actuelle, et tous sont des entiers (pouvant donc être sujets à des erreurs d'arrondi).
Voyons-les en détail:
offsetWidth
, offsetHeight
: La taille de la boîte visuelle comprenant toutes les bordures. Peut être calculé en ajoutant width
/ height
et des rembourrages et des bordures, si l'élément adisplay: block
clientWidth
, clientHeight
: La partie visuelle du contenu de la boîte, à l'exclusion des bordures ou des barres de défilement, mais comprend le remplissage. Ne peut pas être calculé directement à partir de CSS, dépend de la taille de la barre de défilement du système.
scrollWidth
, scrollHeight
: La taille de tout le contenu de la boîte, y compris les parties actuellement masquées en dehors de la zone de défilement. Ne peut pas être calculé directement à partir de CSS, dépend du contenu.
Étant donné que offsetWidth
prend en compte la largeur de la barre de défilement, nous pouvons l'utiliser pour calculer la largeur de la barre de défilement via la formule
scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth
Malheureusement, nous obtenons des erreurs d' arrondi, car offsetWidth
et clientWidth
sont toujours des entiers, alors que la taille réelle peut être fractionné avec des niveaux de zoom autres que 1.
Notez que ceci
scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth
ne fonctionne pas de manière fiable dans Chrome, car Chrome revient width
avec la barre de défilement déjà soustraite. (De plus, Chrome rend paddingBottom au bas du contenu du défilement, contrairement aux autres navigateurs)
element.getBoundingClientRect()
(voir la note sur developer.mozilla.org/en-US/docs/Web/API/Element.clientWidth )naturalWidth
etnaturalHeight
scrollHeight
inclutpadding-bottom
maisscrollWidth
n'inclut paspadding-right
clientWidth
pourdocument.documentElement.clientWidth
est différent car il semble inclure lepadding
,borders
etmargin
J'ai créé une version plus complète et plus propre que certaines personnes pourraient trouver utile pour se souvenir de quel nom correspond à quelle valeur. J'ai utilisé le code couleur de Chrome Dev Tool et les étiquettes sont organisées symétriquement pour détecter plus rapidement les analogies:
Remarque 1:
clientLeft
inclut également la largeur de la barre de défilement verticale si la direction du texte est définie de droite à gauche (car la barre est affichée à gauche dans ce cas)Remarque 2: la ligne la plus à l'extérieur représente le parent le plus proche positionné (un élément dont la
position
propriété est définie sur une valeur différente destatic
ouinitial
). Ainsi, si le conteneur direct n'est pas un élément positionné , la ligne ne représente pas le premier conteneur de la hiérarchie mais un autre élément plus haut dans la hiérarchie. Si aucun parent positionné n'est trouvé, le navigateur prendra l' élémenthtml
oubody
comme référenceJ'espère que quelqu'un le trouvera utile, juste mes 2 cents;)
la source
Si vous souhaitez utiliser scrollWidth pour obtenir la LARGEUR / LA HAUTEUR DE CONTENU "RÉEL" (car le contenu peut être PLUS GRAND que la largeur / hauteur définie par CSS), la scrollWidth / Height est très ILLICITE car certains navigateurs semblent "DÉPLACER" le paddingRIGHT & paddingBOTTOM si le contenu est trop volumineux. Ils placent ensuite les rembourrages à DROITE / BAS du "contenu trop large / élevé" (voir photo ci-dessous).
==> Par conséquent, pour obtenir la LARGEUR DE CONTENU RÉEL dans certains navigateurs, vous devez soustraire les DEUX rembourrages de la largeur de défilement et dans certains navigateurs, vous n'avez qu'à soustraire le remplissage GAUCHE.
J'ai trouvé une solution pour cela et je voulais l'ajouter en tant que commentaire, mais ce n'était pas autorisé. J'ai donc pris la photo et l'ai rendue un peu plus claire en ce qui concerne les "rembourrages déplacés" et le "scrollWidth peu fiable". Dans la ZONE BLEUE, vous trouverez ma solution pour obtenir la LARGEUR DE CONTENU "RÉELLE"!
J'espère que cela aide à rendre les choses encore plus claires!
la source
Il y a un bon article sur MDN qui explique la théorie derrière ces concepts: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements
Il explique également les différences conceptuelles importantes entre la largeur / hauteur de boundingClientRect et offsetWidth / offsetHeight.
Ensuite, pour prouver que la théorie est bonne ou mauvaise, vous avez besoin de tests. C'est ce que j'ai fait ici: https://github.com/lingtalfi/dimensions-cheatsheet
Il teste chrome53, ff49, safari9, edge13 et ie11.
Les résultats des tests prouvent que la théorie est généralement correcte. Pour les tests, j'ai créé 3 divs contenant 10 paragraphes lorem ipsum chacun. Certains CSS leur ont été appliqués:
Et voici les résultats:
div1
bcr.height: 330 (chrome53, ff49, safari9, edge13, ie11)
clientWidth: 505 (chrome53, ff49, safari9)
clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)
scrollWidth: 505 (chrome53, safari9, ff49)
div2
clientHeight: 290 (chrome53, ff49, safari9, edge13, ie11)
scrollWidth: 475 (chrome53, safari9, ff49)
div3
clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)
scrollWidth: 505 (chrome53, safari9, ff49)
Ainsi, en dehors de la valeur de hauteur du boundingClientRect (299.9999694824219 au lieu de 300 attendu) dans edge13 et ie11, les résultats confirment que la théorie derrière cela fonctionne.
De là, voici ma définition de ces concepts:
Remarque: la largeur de la barre de défilement verticale par défaut est de 12px en bord13, 15px en chrome53, ff49 et safari9, et 17px en ie11 (effectuées par des mesures dans Photoshop à partir de captures d'écran, et prouvées par les résultats des tests).
Cependant, dans certains cas, votre application n'utilise peut-être pas la largeur de la barre de défilement verticale par défaut.
Donc, étant donné les définitions de ces concepts, la largeur de la barre de défilement verticale doit être égale à (en pseudo code):
dimension de présentation: offsetWidth - clientWidth - (borderLeftWidth + borderRightWidth)
dimension de rendu: boundingClientRect.width - clientWidth - (borderLeftWidth + borderRightWidth)
Remarque, si vous ne comprenez pas la mise en page et le rendu, veuillez lire l'article mdn.
De plus, si vous avez un autre navigateur (ou si vous voulez voir les résultats des tests par vous-même), vous pouvez voir ma page de test ici: http://codepen.io/lingtalfi/pen/BLdBdL
la source