Navigate back home
GalaSoft Laurent Bugnion
CSS length manipulation and conversion
Introduction:

This class provides an interface for easier manipulation of CSS length values. CSS provides different ways to define dimensions, thicknesses, positions using, for example, px (pixel), em (a unit coming from the good old times of printing with lead characters) or pt (point).

Converting from one unit to the other can be tricky. The conversion depends on quite a few things (mostly the way font size is set in the node's hierarchy in the DOM), and there is not a simple arithmetic way to convert ems to pixels for example. This class provides a factor calculation allowing easy conversion, by using the browser's own CSS engine. It also provides a few helper methods, for example to extract the unit from the CSS string, to add or substract pixels or other units from the value, etc...

To create an instance of the class, simply use the constructor with a CSS length string as parameter. Once the instance is created, use the methods provided to work with the values.

var oCssLength = new gslb.CssLength( "2.2em" ); oCssLength.addPixels( 150 ); document.getElementById( "divTest" ).style.left = oCssLength.toString();
Creating and working with a CSS length instance
Computing the conversion factor

Finding out the conversion factor from pixels to another unit is tricky because it depends on various factors. However, the browser does the work already. Unfortunately, the implementation is not totally compatible between the two major browser families (IE and Mozilla), so a little feature detection is needed.

To calculate the factor, I create a temporary DIV element using JavaScript, and set its width using the provided CSS unit. Then, I use the node's own attributes to find out the calculated pixel value.

To find out the pixel value in IE-based browsers, one can use the "Node.style.pixelWidth" attribute. In Mozilla-based browsers, the "Node.clientWidth" can be used. However, there are a few caveats:

  • If the conversion is applied to a specific node in the document, and if a font-size has been applied to one of the specific node's parents (for example "font-size: 80%" in the body), the calculated results will be incorrect. To avoid this, pass the specific node to the CssLength constructor. This way, all the settings will be taken in account.
  • The "clientWidth" attribute is only set when the Node has been added to the document's body. It is always 0 if the Node is not added to it.
  • The "clientWidth" attribute is always equal to 0 when the Node's "style.display" attribute is set to "none".
gslb.CssLength.getPixelPerUnitFactor = function( strUnit, nNode ) { if ( strUnit.toLowerCase() == "px" ) { return 1; } if ( !document.createElement ) { throw "Unsuitable platform"; } // Create a temporary DIV. // For greater precision, use a factor. var nDivTemp = document.createElement( "div" ); nDivTemp.style.width = "10000" + strUnit; // Set the DIV to hidden to avoid // unwanted visual effects. nDivTemp.style.visible = "hidden"; if ( !document.getElementsByTagName ) { throw "Unsuitable platform"; } // The value is only valid if the DIV belongs to the document var anBody = document.getElementsByTagName( "body" ); if ( !anBody || !anBody.length || !anBody[0] ) { throw "Unsuitable platform"; } var nParent = anBody[0]; if ( nNode && nNode.parentNode ) { // If the conversion must be applied to a // specific node, append to this node's parent. // This avoids errors if the parent's font size has // been set in CSS. nParent = nNode.parentNode; } if ( !nParent || !nParent.appendChild || !nParent.removeChild ) { throw "Unsuitable platform"; } // Even though pixelWidth is always set, if the // temporary DIV is not appended to the BODY, the // value will be invalid, except if font-size // is set to 100%. nParent.appendChild( nDivTemp ); if ( nDivTemp.style.pixelWidth != null ) { var iPixelWidth = nDivTemp.style.pixelWidth; nParent.removeChild( nDivTemp ); return iPixelWidth / 10000; } // pixelWidth is not available // --> use clientWidth instead. if ( nDivTemp.clientWidth != null ) { var iClientWidth = nDivTemp.clientWidth; // Once the value is saved, remove the node. nParent.removeChild( nDivTemp ); return iClientWidth / 10000; } throw "Unsuitable platform"; }
Computing the conversion factor
Method list

The CssLength class has the following constructor:

  • gslb.CssLength( strCssString, nNode )
    The parameter strCssString (string) contains the CSS length string to be parsed, for example "2.2em".
    The parameter nNode (Node, optional) contains a reference to the specific DOM node to which the conversion will apply. If null, the CSS settings for the BODY will be used, but this may lead to incorrect results if the font-size has been set in the node's parents hierarchy.

The CssLength class has the following static methods:

  • getPixelPerUnitFactor( strUnit, nNode ): For a given CSS length unit (em, px, pt...), returns the factor (float) allowing a conversion to and from pixels. The factor is in [px/unit].
    The parameter strUnit (string) is a valid CSS "length" string, for example "2em" or "150px".
    The parameter nNode (Node, optional) contains a reference to the specific DOM node to which the conversion will apply. If null, the CSS settings for the BODY will be used, but this may lead to incorrect results if the font-size has been set in the node's parents hierarchy.
  • getUnit( strCssString ): Extracts the CSS length unit from a given CSS length string.
    The parameter strCssString (string) contains the CSS length string to be parsed, for example "2.2em".

A CssLength instance has the following methods:

  • getPixelValue(): Returns the numeric value for this instance converted in pixels.
  • setPixelValue( iValue ): Sets the current value to the given number of pixels.
  • getUnitValue(): Returns the numeric value for this instance in original units (according to the CSS string passed to the constructor of this instance).
  • setUnitValue( fValue ): Sets the current value to the given number of units (em, px, pt...).
  • getUnit(): Returns the unit ("em", "px", ...) of this value.
  • toString(): Returns a string representation of this value in original units (according to the CSS string passed to the constructor of this instance).
  • toStringPixels(): Returns a string representation of this value converted to pixels.
  • addPixels( iPixels ): Adds a number of pixels to the present value.
    The parameter iPixels (int) contains the number of pixels to add to the present value.
  • substractPixels( iPixels ): Substracts a number of pixels from the present value.
    The parameter iPixels (int) contains the number of pixels to substract from the present value.
  • addUnits( fUnits ): Adds a number of the original units (according to the CSS string passed to the constructor of this instance) to the present value.
    The parameter fUnits (float) contains the number of units to add to the present value.
  • substractUnits( fUnits ): Substracts a number of the original units (according to the CSS string passed to the constructor of this instance) from the present value.
    The parameter fUnits (float) contains the number of units to substract from the present value.
  • getPixels( fUnitValue ): Returns the number of pixels corresponding to the number of original units (according to the CSS string passed to the constructor of this instance) passed as parameter.
  • getUnits( iPixelValue ): Returns the number of original units (according to the CSS string passed to the constructor of this instance) corresponding to the number of pixels passed as parameter.
Live demo

See here.

Downloads

Click to see the code.
Right-click and "Save as..." to save locally.
After saving, remove the ".txt" extension to execute the code in your web browser.

History
Date Version Description
17.11.2007 V1.1.1
  • Clean-up, cosmetic changes, bug corrections
04.02.2007 V1.1.0
  • Added methods setPixelValue and setUnitValue
31.01.2007 V1.0.1
  • First official version
25.01.2007 V0.0.0
  • Created