HTML要素の実際の幅と高さを取得するにはどうすればよいですか?


894

<div>ブラウザのディスプレイ(ビューポート)の中央に配置したいものがあるとします。そのためには、<div>要素の幅と高さを計算する必要があります。

何を使うべきですか?ブラウザの互換性に関する情報を含めてください。


9
ブラウザがページ内のすべての要素の位置を再計算(リフロー)するため、任意のメソッドを通じて要素の高さを取得すると、常にパフォーマンスに影響することに注意してください。したがって、やり過ぎないようにしてください。このリストをチェックし、リフローをトリガーするものを確認してください。
Marcelo Lazaroni、2016

回答:


1287

.offsetWidthおよび.offsetHeightプロパティを使用する必要があります。それらはではなく要素に属していることに注意してください.style

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

関数.getBoundingClientRect()は、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,
}

174
注意してください!最近、要素に対して特定のDOM変更を行った場合、offsetHeight / offsetWidthは0を返すことがあります。要素を変更した後、setTimeout呼び出しでこのコードを呼び出す必要がある場合があります。
Dan Fabulich、2010年

37
.offsetWidthおよびについてのドキュメント.offsetHeightdeveloper.mozilla.org/en/Determining_the_dimensions_of_elements
DenilsonSáMaia '22

31
どのような状況で0を返しますか?
チーター

46
@JDandChips:offsetWidth要素がの場合は0になりますがdisplay:nonewidthこのインスタンスでは計算された値がまだ正の値である可能性があります。visibility:hiddenには影響しませんoffsetWidth
MrWhite 2012年

21
@Supuhstarはどちらも異なる意味を持っています。offsetWidthコンテンツ、パディング、ボーダーを含む「全体」のボックスを返します。while clientWidthは、コンテンツボックスのサイズのみを返します(そのため、要素にゼロ以外のパディングや境界がある場合は、より小さい値になります)。(わかりやすくするためにmodを編集)
Edurne Pascual 14

200

見てくださいElement.getBoundingClientRect()

このメソッドは、 widthheightと他のいくつかの有用な値:

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

例えば:

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

私はこれには問題がなく、それらが時々戻る場所には問題がない.offsetWidth.offsetHeight思います0ここコメントで説明されています

別の違いは、getBoundingClientRect()小数画素を返すことがあり、ここで、.offsetWidth及び.offsetHeight最も近い整数に丸めます。

IE8注IE8以下ではgetBoundingClientRect高さと幅を返しません。*

IE8をサポートする必要がある場合は、.offsetWidthおよびを使用し.offsetHeightます。

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

このメソッドによって返されるオブジェクトは実際には通常のオブジェクトではないことに注意してください。そのプロパティは列挙可能ではありません(たとえば、Object.keysそのままでは機能しません)。

これに関する詳細情報: ClientRect / DomRectをプレーンオブジェクトに変換する最善の方法

参照:


8
getboundingClientRectは()に対し、CSSを介して、スケーリングされた要素の実際の幅と高さが返されるoffsetHeightoffsetWidthしないであろう。
ルーク

66

注意この回答は2008年に書かれました。当時、ほとんどの人にとって最良のクロスブラウザソリューションは、実際にはjQueryを使用することでした。答えは後世に残しておきます。jQueryを使用している場合、これは良い方法です。他のフレームワークまたは純粋なJavaScriptを使用している場合、受け入れられる答えはおそらく進むべき道です。

jQuery 1.2.6以降では、コアCSS関数の 1つ、heightおよびwidthouterHeightおよびouterWidth、必要に応じて、および)を使用できます。

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

var docHeight = $(document).height();
var docWidth = $(document).width();

45

誰にとっても便利なように、テキストボックス、ボタン、divをすべて同じ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>

私はchrome、firefox、ie-edgeで試してみました。jqueryを使って試してみました。 box-sizing:border-box。いつもと<!DOCTYPE html>

結果:

                                                               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

1
明確にするために...これらのブラウザのいずれかが互いに異なることをしていますか?違いを見つけることはできません...また、私は(まだ)反対票を投じていません、質問に直接答えることはできませんが、簡単に編集できます。
Zach Lysobey 2016年

1
質問への回答を目的としていませんでした-すでに回答されています。ほんの一部の役立つ情報とはい、すべての主要な最新バージョンのブラウザーはこれらの値に同意しています。これは良いことです。
グラハム

3
まあ...あなたの意図が質問に答えることではない場合、これは(「答え」として)実際にはここに属しません。これを外部リソース(GitHub要旨、またはブログ投稿など)に入れ、元の質問または回答の1つに対するコメントでリンクすることを検討します。
Zach Lysobey 2016年

21
@ZachLysobeyすべてのルールには例外があり、これは見た目がクールで便利なものです。
Dan Nissenbaum 2016

16

MDNによると:要素の寸法の決定

offsetWidthそしてoffsetHeight、「表示コンテンツの幅、スクロールバー(ある場合)、パディング、およびボーダーを含む、要素が占めるスペースの合計量」を返します

clientWidthそして、clientHeight「パディングを含むがボーダー、マージン、またはスクロールバーを含まない、実際に表示されるコンテンツが占めるスペースの量」を返す

scrollWidthscrollHeight「現在表示されているコンテンツの量に関係なく、コンテンツの実際のサイズ」を返します

したがって、測定されたコンテンツが現在の表示可能領域外にあると予想されるかどうかによって異なります。


5

IE7以前の場合にのみ計算する必要があります(コンテンツのサイズが固定されていない場合のみ)。HTML条件付きコメントを使用して、ハッキングをCSS2をサポートしない古いIEに制限することをお勧めします。他のすべてのブラウザでは、これを使用します。

<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>

これは完璧なソリューションです。<div>任意のサイズの中央に配置し、コンテンツのサイズにシュリンクラップします。


3

要素のスタイルを変更するのは簡単ですが、値を読み取るのは少し難しいです。

JavaScriptは、JavaScriptの組み込みメソッド呼び出しgetComputedStyleを使用しない限り、css(internal / external)からの要素スタイルプロパティ(elem.style)を読み取ることができません。

getComputedStyle(element [、pseudo])

要素:値を読み取る要素。
pseudo:必要に応じて、たとえば:: beforeなどの疑似要素。空の文字列または引数なしは、要素自体を意味します。

結果は、elem.styleのようなスタイルプロパティを持つオブジェクトですが、現在はすべてのcssクラスに関連しています。

たとえば、ここではスタイルにはマージンがありません。

<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>

そのため、javaScriptコードを変更して、幅/高さまたはその他の属性を取得する要素のgetComputedStyleを含めます。

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

}

計算および解決された値

CSSには2つの概念があります。

計算されたスタイル値は、CSSカスケードの結果として、すべてのCSSルールとCSS継承が適用された後の値です。height:1emまたはfont-size:125%のようになります。

解決されたスタイル値は、最終的に要素に適用される値です。1emや125%などの値は相対的です。ブラウザーは計算された値を受け取り、すべての単位を固定および絶対値にします(例:height:20pxまたはfont-size:16px)。ジオメトリプロパティの場合、解決された値には、width:50.5pxなどの浮動小数点が含まれる場合があります。

ずっと前に、計算された値を取得するためにgetComputedStyleが作成されましたが、解決された値の方がはるかに便利で、標準が変更されたことがわかりました。
したがって、現在getComputedStyleは実際にはプロパティの解決された値を返します。

ご注意ください:

getComputedStyleには完全なプロパティ名が必要です

paddingLeft、height、widthなど、常に正確なプロパティを要求する必要があります。そうしないと、正しい結果が保証されません。

たとえば、プロパティpaddingLeft / paddingTopがある場合、getComputedStyle(elem).paddingで何を取得する必要がありますか?何もない、または既知のパディングから「生成された」値?ここには標準的なルールはありません。

他にも矛盾があります。例として、一部のブラウザー(Chrome)では以下のドキュメントに10pxが表示され、一部のブラウザー(Firefox)では表示されません。

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

詳細についてはhttps://javascript.info/styles-and-classes


1

element.offsetWidthとelement.offsetHeightは、以前の投稿で提案されているように、実行する必要があります。

ただし、コンテンツを中央揃えにしたい場合は、より良い方法があります。xhtmlの厳密なDOCTYPEを使用すると仮定します。margin:0、autoプロパティと必要な幅(px単位)をbodyタグに設定します。コンテンツはページの中央に配置されます。


1
彼は垂直方向にも中央に配置したいと考えています。これは、特定の基準(既知のサイズのコンテンツなど)を満たすことができない場合を除き、CSSの正しい苦痛です
Greg

1

... CSSはdivを中央に配置するのに役立つようです...

<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>

0

このコードを使用することもできます:

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

var h = divID.style.pixelHeight;

1
ChromeとIE9で動作しますが、Firefoxでは動作しないようです。特定の種類のドキュメントでのみ機能しますか?
BrainSlugs83 2011

1
pixelHeightはもう使用すべきではありませんInternet Explorerの発明だったstackoverflow.com/q/17405066/2194590
HolgerJeromin

0

ブラウザのディスプレイポートの中央に配置する必要がある場合。CSSでのみ実現できます

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

-2

これは、特定のDom要素の高さを決定するWKWebViewのコードです(ページ全体では適切に機能しません)。

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 {

        }
    }
}

明確にするために、これはiOS swiftコードですよね?JavaScriptではありません。私は反対票を差し控えています(b / cこれは実際にはかなり役立つかもしれませ)が、これは質問に答え、iOS固有の別の質問にはより適切であることに注意してください。まだ存在しない場合は、たぶん尋ねて自己回答することを検討してください。
Zach Lysobey 2018年

-3

offsetWidthが0を返す場合、要素のスタイルの幅プロパティを取得して、数値を検索できます。「100px」-> 100

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.