By Jochen Voss, last updated 2011-08-31
This page discusses how the get and set the size of an element in an HTML page. Some general information about how to use CSS and JavaScript in an HTML page can be found on my page about HTML5 apps.
The geometry of most HTML elements is controlled by the CSS Box Model. Elements are assumed to be rectangular, being surrounded by some (transparent) margin and possibly a border. For container elements, there is also an inner margin, called padding, which keeps child elements at a certain distance from the container boundaries.
Figure 1. Illustration of the (horizontal) margin, border-width and padding in the CSS box model. The corresponding vertical quantities are arranged analogously.
The relevant quantites, from the outside in, are
There are two ways to read out the various parameters governing the geometry of an HTML element: Some of the parameters are exposed as properties of the JavaScript objects representing the elements. Alternatively, the parameters can be accessed by reading the computed CSS style information.
Some care is needed, since the returned values are not always identical to the values given in the style sheet. For example, sometimes browsers seem to round border widths to an integer number of screen pixels, and with non-standard zoom levels the returned (CSS pixel) values are then fractional values, slightly different from what was given in the style sheet.
The top part of table 1 lists the available parameters. The visual height of an object can, for example, be computed using code like the following:
var box = document.getElementById("mybox"); var clientWidth = box.clientWidth;
For the yellow box from the example in
figure 2 the result is
clientWidth = 12 + 282 + 6 = 300
. This method allows to
obtain the regions delimited by the inner and outer edges of the element
border. It does not offer any information about margins or padding.
Figure 2. The test element we use for the
example in the text. The yellow rectangle is a DIV
element
with the following CSS style applied to it
width: 282px; border: solid black; background: yellow; margin: 1px 4px 7px 10px; border-width: 2px 5px 8px 11px; padding: 3px 6px 9px 12px;
Contained in this element is a green square, implemented as a
DIV
of size 100×100 and without any margin, borders or
padding.
The computed CSS information can be obtained using the
window.getComputedStyle
function, using code like the
following. The top part of table 1 lists the
available parameters. Since the returned values are strings of the form
12px
, we need to convert the return values to numbers. This can be
done using the parseFloat
function (which ignores the
trailing px
).
var box = document.getElementById("mybox"); var style = window.getComputedStyle(box,null); var pl = parseFloat(style.getPropertyValue("padding-left"));
Google Chrome 5.0.375.55 MacOS X | Firefox 3.6.3 MacOS X | ||
---|---|---|---|
object properties |
offsetWidth | 316 | 316 |
scrollWidth | 300 | 316 | |
clientWidth | 300 | 300 | |
offsetHeight | 122 | 122 | |
scrollHeight | 112 | 122 | |
clientHeight | 112 | 112 | |
clientTop | 2 | 2 | |
clientLeft | 11 | 11 | |
computed CSS style |
width | 282px | 282px |
height | 100px | 100px | |
margin-top | 1px | 1px | |
border-top-width | 2px | 2px | |
padding-top | 3px | 3px | |
margin-right | * | 4px | |
border-right-width | 5px | 5px | |
padding-right | 6px | 6px | |
margin-bottom | 7px | 7px | |
border-bottom-width | 8px | 8px | |
padding-bottom | 9px | 9px | |
margin-left | 10px | 10px | |
border-left-width | 11px | 11px | |
padding-left | 12px | 12px |
Table 1. The dimensions of the yellow rectangle in figure 2 as obtained by different browsers. The given value are for the default zoom-level.
Since the DOM object properties listed in the top part of table 1 are read-only, object geometry can only be changed by changing the CSS style information of an object directly.
Example 1. Code like the following can be used to make an element big enough to contain a child element of a given width.
var childWidth = 100; var box = document.getElementById("mybox"); box.style.paddingLeft = childWidth+"px";
Example 2. The following code changes the element size so that it will take up a given width in the parent container.
var parentWidth = 100; var box = document.getElementById("mybox"); var style = window.getComputedStyle(box,null); var ml = parseFloat(style.getPropertyValue("margin-left")); var bl = parseFloat(style.getPropertyValue("border-left-width")); var pl = parseFloat(style.getPropertyValue("padding-left")); var pr = parseFloat(style.getPropertyValue("padding-rigth")); var br = parseFloat(style.getPropertyValue("border-rigth-width")); var mr = parseFloat(style.getPropertyValue("margin-rigth")); box.style.paddingLeft = (parentWidth-ml-bl-pl-pr-br-mr)+"px";
This section gives an extensive example, illustrating the techniques
explained on this page. Try clicking the download
button at the
bottom of the listing to experiment with it.
<!DOCTYPE html> <html> <head> <title>Element Geometry Test</title> <meta charset="utf-8"> <style type="text/css"> DIV { margin: 8px 0px; padding: 8px 50px; width: 200px; height: 52px; overflow: hidden; } DIV P { margin: 0px; font-size: 12px; text-align: center; background: white; } DIV#red { background: red; } DIV#green { margin-left: 50px; background: green; } DIV#blue { margin-left: 50px; border-left: 50px solid #000040; background: blue; } SPAN { border: 1px solid red; padding: 1px 1ex; background: #E0E0E0; cursor: pointer; } </style> <script type="text/javascript"> names = [ "red", "green", "blue" ]; function measure() { for (var j in names) { var div = document.getElementById(names[j]); var p = div.getElementsByTagName("p")[0]; var style = window.getComputedStyle(p, null); p.textContent = style.width } } function set_inner_width() { var width = this.textContent; for (var j in names) { document.getElementById(names[j]).style.width = width; } measure(); } function set_outer_width() { var target = parseFloat(this.textContent); for (var j in names) { var div = document.getElementById(names[j]); var style = window.getComputedStyle(div, null); var lengths = [ "margin-left", "border-left-width", "padding-left", "padding-right" ]; var sum = 0; for (var i in lengths) { sum += parseFloat(style.getPropertyValue(lengths[i])); } div.style.width = (target-sum)+"px"; } measure(); } function init() { spans = document.getElementsByClassName("button1"); for (var i in spans) spans[i].onclick = set_inner_width; spans = document.getElementsByClassName("button2"); for (var i in spans) spans[i].onclick = set_outer_width; measure(); } </script> </head> <body onload="init()"> <img src="https://m.seehuhn.de/cssgeom/scale.png"> <div id="red"><img src="https://m.seehuhn.de/cssgeom/scale.png"><p></div> <div id="green"><img src="https://m.seehuhn.de/cssgeom/scale.png"><p></div> <div id="blue"><img src="https://m.seehuhn.de/cssgeom/scale.png"><p></div> <hr> <p>Set inner width to: <span class="button1">300px</span>, <span class="button1">400px</span>, <span class="button1">500px</span> <p>Set outer width to: <span class="button2">300px</span>, <span class="button2">400px</span>, <span class="button2">500px</span> </body> </html>
Copyright © 2011 Jochen Voss. All content on this website (including text, pictures, and any other original works), unless otherwise noted, is licensed under the CC BY-SA 4.0 license.