Comment récupérer la largeur et la hauteur réelles d'un élément HTML?

895

Supposons que j'en ai un <div>que je souhaite centrer dans l'affichage du navigateur (fenêtre d'affichage). Pour ce faire, je dois calculer la largeur et la hauteur de l' <div>élément.

Que dois-je utiliser? Veuillez inclure des informations sur la compatibilité du navigateur.

snortasprocket
la source
9
Gardez à l'esprit qu'obtenir la hauteur d'un élément à travers n'importe quelle méthode a toujours un impact sur les performances car il fait recalculer la position de tous les éléments dans la page (redistribution). Par conséquent, évitez d'en faire trop. Consultez cette liste pour savoir quel genre de choses déclenche une refusion.
Marcelo Lazaroni

Réponses:

1290

Vous devez utiliser les propriétés .offsetWidthet .offsetHeight. Notez qu'ils appartiennent à l'élément, non .style.

var width = document.getElementById('foo').offsetWidth;

La fonction.getBoundingClientRect() renvoie les dimensions et l'emplacement de l'élément sous forme de nombres à virgule flottante après avoir effectué des transformations CSS.

> console.log(document.getElementById('id').getBoundingClientRect())
DOMRect {
    bottom: 177,
    height: 54.7,
    left: 278.5,​
    right: 909.5,
    top: 122.3,
    width: 631,
    x: 278.5,
    y: 122.3,
}
Greg
la source
174
Il faut se méfier! offsetHeight / offsetWidth peut retourner 0 si vous avez effectué certaines modifications DOM à l'élément récemment. Vous devrez peut-être appeler ce code dans un appel setTimeout après avoir modifié l'élément.
Dan Fabulich
37
Documentation sur .offsetWidthet .offsetHeight: developer.mozilla.org/en/Determining_the_dimensions_of_elements
Denilson Sá Maia
31
Dans quelles circonstances renvoie-t-il 0?
Cheetah
46
@JDandChips: offsetWidthsera égal à 0 si l'élément l'est display:none, alors que le calcul widthpourrait toujours avoir une valeur positive dans ce cas. visibility:hiddenn'affecte pas le offsetWidth.
MrWhite
21
@Supuhstar ont tous deux des significations différentes. offsetWidthrenvoie la boîte "entière", y compris le contenu, le remplissage et les bordures; tandis que clientWidthrenvoie la taille de la zone de contenu seule (elle aura donc une valeur plus petite chaque fois que l'élément a un remplissage et / ou une bordure non nul). (mod édité pour plus de clarté)
Edurne Pascual
200

Jetez un oeil à Element.getBoundingClientRect().

Cette méthode retourne un objet contenant les width, heightet d'autres valeurs utiles:

{
    width: 960,
    height: 71,
    top: 603,
    bottom: 674,
    left: 360,
    right: 1320
}

Par exemple:

var element = document.getElementById('foo');
var positionInfo = element.getBoundingClientRect();
var height = positionInfo.height;
var width = positionInfo.width;

Je crois que cela n'a pas les problèmes qui se produisent .offsetWidthet .offsetHeightoù ils reviennent parfois 0(comme discuté dans les commentaires ici )

Une autre différence getBoundingClientRect()peut renvoyer des pixels fractionnaires, où .offsetWidthet.offsetHeight arrondira à l'entier le plus proche.

IE8 Remarque : getBoundingClientRectne renvoie pas la hauteur et la largeur sur IE8 et les versions inférieures. *

Si vous devez prendre en charge IE8, utilisez .offsetWidthet .offsetHeight:

var height = element.offsetHeight;
var width = element.offsetWidth;

Il convient de noter que l'objet renvoyé par cette méthode n'est pas vraiment un objet normal . Ses propriétés ne sont pas énumérables (donc, par exemple, Object.keysne fonctionne pas immédiatement.)

Plus d'informations à ce sujet ici: Comment convertir au mieux un ClientRect / DomRect en un simple objet

Référence:

Zach Lysobey
la source
8
getboundingClientRect () renverra la largeur et la hauteur réelles des éléments mis à l'échelle via css alors offsetHeightque offsetWidthce ne sera pas le cas.
Luke
66

REMARQUE : cette réponse a été écrite en 2008. À l'époque, la meilleure solution multi-navigateur pour la plupart des gens était vraiment d'utiliser jQuery. Je laisse la réponse ici pour la postérité et, si vous utilisez jQuery, c'est un bon moyen de le faire. Si vous utilisez un autre framework ou du JavaScript pur, la réponse acceptée est probablement la voie à suivre.

Depuis jQuery 1.2.6, vous pouvez utiliser l'une des fonctions CSS principales , heightet width(ou outerHeightet outerWidth, selon le cas).

var height = $("#myDiv").height();
var width = $("#myDiv").width();

var docHeight = $(document).height();
var docWidth = $(document).width();
tvanfosson
la source
45

Juste au cas où cela serait utile à n'importe qui, je mets une zone de texte, un bouton et divise tout avec le même CSS:

width:200px;
height:20px;
border:solid 1px #000;
padding:2px;

<input id="t" type="text" />
<input id="b" type="button" />
<div   id="d"></div>

Je l'ai essayé en chrome, firefox et ie-edge, j'ai essayé avec jquery et sans, et je l'ai essayé avec et sans box-sizing:border-box. Toujours avec<!DOCTYPE html>

Les resultats:

                                                               Firefox       Chrome        IE-Edge    
                                                              with   w/o    with   w/o    with   w/o     box-sizing

$("#t").width()                                               194    200    194    200    194    200
$("#b").width()                                               194    194    194    194    194    194
$("#d").width()                                               194    200    194    200    194    200

$("#t").outerWidth()                                          200    206    200    206    200    206
$("#b").outerWidth()                                          200    200    200    200    200    200
$("#d").outerWidth()                                          200    206    200    206    200    206

$("#t").innerWidth()                                          198    204    198    204    198    204
$("#b").innerWidth()                                          198    198    198    198    198    198
$("#d").innerWidth()                                          198    204    198    204    198    204

$("#t").css('width')                                          200px  200px  200px  200px  200px  200px
$("#b").css('width')                                          200px  200px  200px  200px  200px  200px
$("#d").css('width')                                          200px  200px  200px  200px  200px  200px

$("#t").css('border-left-width')                              1px    1px    1px    1px    1px    1px
$("#b").css('border-left-width')                              1px    1px    1px    1px    1px    1px
$("#d").css('border-left-width')                              1px    1px    1px    1px    1px    1px

$("#t").css('padding-left')                                   2px    2px    2px    2px    2px    2px
$("#b").css('padding-left')                                   2px    2px    2px    2px    2px    2px
$("#d").css('padding-left')                                   2px    2px    2px    2px    2px    2px

document.getElementById("t").getBoundingClientRect().width    200    206    200    206    200    206
document.getElementById("b").getBoundingClientRect().width    200    200    200    200    200    200
document.getElementById("d").getBoundingClientRect().width    200    206    200    206    200    206

document.getElementById("t").offsetWidth                      200    206    200    206    200    206
document.getElementById("b").offsetWidth                      200    200    200    200    200    200
document.getElementById("d").offsetWidth                      200    206    200    206    200    206
Graham
la source
1
Juste pour être clair ... l'un de ces navigateurs fait-il quelque chose de différent l'un de l'autre? Je ne trouve aucune différence ... De plus, je ne vote pas pour l'instant (encore), mais cela ne répond pas vraiment directement à la question, bien qu'il puisse être facilement modifié pour le faire.
Zach Lysobey
1
Ne visait pas à répondre à la question - il a déjà été répondu. Juste quelques informations utiles et oui, tous les principaux navigateurs de la dernière version sont d'accord sur ces valeurs - ce qui est une bonne chose.
Graham
3
Eh bien ... si votre intention n'est pas de répondre à la question, alors cela n'a pas vraiment sa place ici (comme une "réponse"). J'envisagerais de mettre cela dans une ressource externe (peut-être un aperçu de GitHub ou un article de blog) et de le lier dans un commentaire sur la question d'origine ou l'une des réponses.
Zach Lysobey
21
@ZachLysobey Il y a des exceptions à chaque règle - et c'est une chose cool et utile à voir.
Dan Nissenbaum
16

Selon MDN: Déterminer les dimensions des éléments

offsetWidthet offsetHeightrenvoyer la "quantité totale d'espace occupé par un élément, y compris la largeur du contenu visible, les barres de défilement (le cas échéant), le remplissage et la bordure"

clientWidthet clientHeightrenvoyer "l'espace occupé par le contenu affiché, y compris le remplissage, mais pas la bordure, les marges ou les barres de défilement"

scrollWidthet scrollHeightrenvoyer la "taille réelle du contenu, quelle que soit la quantité actuellement visible"

Cela dépend donc si le contenu mesuré devrait être hors de la zone visible actuelle.

HarlemSquirrel
la source
5

Il vous suffit de le calculer pour IE7 et les versions antérieures (et uniquement si votre contenu n'a pas de taille fixe). Je suggère d'utiliser des commentaires conditionnels HTML pour limiter le piratage aux anciens IE qui ne prennent pas en charge CSS2. Pour tous les autres navigateurs, utilisez ceci:

<style type="text/css">
    html,body {display:table; height:100%;width:100%;margin:0;padding:0;}
    body {display:table-cell; vertical-align:middle;}
    div {display:table; margin:0 auto; background:red;}
</style>
<body><div>test<br>test</div></body>

C'est la solution parfaite. Il centre <div>de n'importe quelle taille et le rétrécit à la taille de son contenu.

Kornel
la source
3

Il est facile de modifier les styles des éléments mais un peu difficile à lire la valeur.

JavaScript ne peut lire aucune propriété de style d'élément (elem.style) provenant de css (interne / externe), sauf si vous utilisez l'appel de méthode intégré getComputedStyle en javascript.

getComputedStyle (élément [, pseudo])

Élément: l'élément pour lequel lire la valeur.
pseudo: Un pseudo-élément si nécessaire, par exemple :: before. Une chaîne vide ou aucun argument signifie l'élément lui-même.

Le résultat est un objet avec des propriétés de style, comme elem.style, mais maintenant par rapport à toutes les classes CSS.

Par exemple, ici le style ne voit pas la marge:

<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  <script>
    let computedStyle = getComputedStyle(document.body);

    // now we can read the margin and the color from it

    alert( computedStyle.marginTop ); // 5px
    alert( computedStyle.color ); // rgb(255, 0, 0)
  </script>

</body>

Vous avez donc modifié votre code javaScript pour inclure le getComputedStyle de l'élément que vous souhaitez obtenir sa largeur / hauteur ou un autre attribut

window.onload = function() {

    var test = document.getElementById("test");
    test.addEventListener("click", select);


    function select(e) {                                  
        var elementID = e.target.id;
        var element = document.getElementById(elementID);
        let computedStyle = getComputedStyle(element);
        var width = computedStyle.width;
        console.log(element);
        console.log(width);
    }

}

Valeurs calculées et résolues

Il existe deux concepts en CSS:

Une valeur de style calculée est la valeur après l'application de toutes les règles CSS et de l'héritage CSS, comme résultat de la cascade CSS. Cela peut ressembler à hauteur: 1em ou taille de police: 125%.

Une valeur de style résolue est celle finalement appliquée à l'élément. Des valeurs comme 1em ou 125% sont relatives. Le navigateur prend la valeur calculée et rend toutes les unités fixes et absolues, par exemple: hauteur: 20 pixels ou taille de police: 16 pixels. Pour les propriétés géométriques, les valeurs résolues peuvent avoir une virgule flottante, comme la largeur: 50,5 px.

Il y a longtemps, getComputedStyle a été créé pour obtenir des valeurs calculées, mais il s'est avéré que les valeurs résolues sont beaucoup plus pratiques et la norme a changé.
Donc, de nos jours, getComputedStyle retourne en fait la valeur résolue de la propriété.

Notez s'il vous plaît:

getComputedStyle requiert le nom complet de la propriété

Vous devez toujours demander la propriété exacte que vous souhaitez, comme paddingLeft ou hauteur ou largeur. Sinon, le résultat correct n'est pas garanti.

Par exemple, s'il existe des propriétés paddingLeft / paddingTop, que devons-nous obtenir pour getComputedStyle (elem) .padding? Rien, ou peut-être une valeur «générée» à partir de rembourrages connus? Il n'y a pas de règle standard ici.

Il existe d'autres incohérences. À titre d'exemple, certains navigateurs (Chrome) affichent 10 pixels dans le document ci-dessous, et certains d'entre eux (Firefox) - ne le font pas:

<style>
  body {
    margin: 30px;
    height: 900px;
  }
</style>
<script>
  let style = getComputedStyle(document.body);
  alert(style.margin); // empty string in Firefox
</script>

pour plus d'informations https://javascript.info/styles-and-classes

Lekens
la source
1

element.offsetWidth et element.offsetHeight devraient faire l'affaire, comme suggéré dans le post précédent.

Cependant, si vous souhaitez simplement centrer le contenu, il existe une meilleure façon de le faire. En supposant que vous utilisez xhtml DOCTYPE strict. définissez la marge: 0, la propriété auto et la largeur requise en px sur la balise body. Le contenu est aligné au centre de la page.

questzen
la source
1
Je pense qu'il veut aussi le centrer verticalement, ce qui est un problème avec CSS, à moins que vous ne puissiez répondre à certains critères spécifiques (par exemple, un contenu de taille connue)
Greg
1

... semble CSS aider à mettre div au centre ...

<style>
 .monitor {
 position:fixed;/* ... absolute possible if on :root */
 top:0;bottom:0;right:0;left:0;
 visibility:hidden;
 }
 .wrapper {
 width:200px;/* this is size range */
 height:100px;
 position:absolute;
 left:50%;top:50%;
 visibility:hidden;
 }

 .content {
 position:absolute;
 width: 100%;height:100%;
 left:-50%;top:-50%;
 visibility:visible;
 }

</style>

 <div class="monitor">
  <div class="wrapper">
   <div class="content">

 ... so you hav div 200px*100px on center ...

  </div>
 </div>
</div>
sanecin
la source
0

vous pouvez également utiliser ce code:

var divID = document.getElementById("divid");

var h = divID.style.pixelHeight;
Sergio
la source
1
Hmm, fonctionne dans Chrome et IE9, ne semble pas fonctionner dans Firefox. Cela fonctionne-t-il uniquement pour certains types de documents?
BrainSlugs83
1
pixelHeight était une invention d'Internet Explorer qui ne devrait plus être utilisée stackoverflow.com/q/17405066/2194590
HolgerJeromin
0

si vous devez le centrer dans le port d'affichage du navigateur; vous pouvez y arriver avec CSS uniquement

yourSelector {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
} 
tdjprog
la source
-2

Voici le code de WKWebView qui détermine la hauteur d'un élément Dom spécifique (ne fonctionne pas correctement pour toute la page)

let html = "<body><span id=\"spanEl\" style=\"font-family: '\(taskFont.fontName)'; font-size: \(taskFont.pointSize - 4.0)pt; color: rgb(\(red), \(blue), \(green))\">\(textValue)</span></body>"
webView.navigationDelegate = self
webView.loadHTMLString(taskHTML, baseURL: nil)

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("document.getElementById(\"spanEl\").getBoundingClientRect().height;") { [weak self] (response, error) in
        if let nValue = response as? NSNumber {

        }
    }
}
Aleksey Mazurenko
la source
juste pour être clair, c'est du swiftcode iOS , non? Pas JavaScript. Je retiens un downvote (b / c cela peut en fait être assez utile) mais veuillez noter que cela ne répond pas à la question, et serait probablement plus approprié sur une autre question, spécifique à iOS. Si aucun n'existe déjà, envisagez peut-être d'en poser une et de répondre par vous-même.
Zach Lysobey
-3

Si offsetWidth renvoie 0, vous pouvez obtenir la propriété de largeur de style de l'élément et rechercher un nombre. "100px" -> 100

/\d*/.exec(MyElement.style.width)

Arko
la source