Web Platform Javascript

Manipulating DOM Visuals

Once you have a reference to a DOM element (here denoted with the el variable) you might want to find out it's size, relate it to cursor coordinates or move it. Where possible use CSS classes to manipulate the appearance of elements to simplify your code. Adding a class and using transitions is an easy to make an element move with animation, for example.

If you want to experiment with these, open this JSFiddle. The box on the right shows various position/size properties. Use the drop-down to pick a different element. Observe how the values change when you scroll the page. Try changing the CSS for the different boxes to see how values change.

Getting the position

Get the position an element is actually being shown at, relative to the browser viewport with getBoundingClientRect:

const rect = el.getBoundingClientRect();
// 'rect' contains left, top, right, bottom, x, y, width and height properties

You can also use offsetLeft and offsetTop to get integer-rounded locations. Remember that the values are relative to the viewport (ie. the size of the browser window), and thus might be quite different to how the position was set in CSS.

Viewport-relative units go great with elements that have CSS position: fixed, because it works on the same principle. For example:

<div id="box">
   BOX
</div>
#box {
  display: inline-block;
  position: fixed;
  left: 10px;
}

offsetLeft works just like we expect, with the same value as in the CSS. If you've used a relative unit (like rem) it will return a pixel value regardless.

console.log(el.offsetLeft); // 10

CSS positions

At times you might want to work with coordinates in relation to how they are defined in CSS. Unfortunately it's not as simple as it could be.

Take for example this DIV that has '5px' set as its left style:

<div style="left:5px" id="box">
   BOX
</div>

You can fetch it by accessing style.left of the element:

console.log(el.style.left); // "5px"

However it doesn't work if property is not assigned directly on the element, for example:

<div id="box">
  BOX
</div>
#box {
  left: 5px
}
console.log(el.style.left); // Empty result

It gives an empty result because the style 'left' is not defined on the element, but on class 'box'.

To get around this, use getComputedStyle and getPropertyValue instead. This takes into account all the possible influences on the position, and gives you whatever CSS value is in force.

const style = window.getComputedStyle(el);
style.getPropertyValue("left"); // "5px"

For both of these approaches, a string value is returned. To perform computations on it, use parseInt to convert it to a number.

const left = parseInt(el.style.left, 10); // Convert "5px" into 5
console.log(left); // 5

Setting the position

To set the position of an element, you're really just manipulating it's CSS properties, so everything you know about CSS positioning can be applied here.

Test how to move the element with just CSS - such as live editing the CSS in the developer tools - before trying it in Javascript

For example, to set the left property to 10 pixels:

el.style.left = "10px";

The easy case for setting the position is when the item has position: fixed, to stay working in viewport-relative units.

For example, if you want to nudge the element from its current position:

el.style.left = (el.offsetLeft + 10) + "px"

Without fixed positioning, the best approach to perform a relative move is:

const el = document.getElementById('box');
const style = window.getComputedStyle(el);
el.style.left = (parseInt(style.getPropertyValue("left"), 10) + 10) + "px";

Don't forget that the CSS positionining rules still apply. If your element is positioned with position: relative, setting el.style.left = "-1rem" will set it negative 1rem, in relation to its parent.

Scrolling

Commonly used to check the overall scrolling of the body (as in the below example) but can also be used for internal scrolling of elements where it is enabled.

const top = document.body.scrollTop;
const left = document.body.scrollLeft;

These values can also be set, eg to scroll to the top-left of the page:

document.body.scrollTop = 0;
document.body.scrollLeft = 0;

Or for example to nudge the scrolling by an amount:

document.body.scrollTop += 50;

Read more

Dimensions

Relative to viewport:

const rect = el.getBoundingClientRect();
// 'rect' contains left, top, right, bottom, x, y, width and height properties

You can also use offsetHeight and offsetWidth properties, which is rounded to an even number. These dimensions are effectively the visible size of the element, but does and thus does not include the margin.

const width = el.offsetWidth;

clientHeight and clientWidth is similar, but does not include border or scrollbar dimensions. scrollWidth and scrollHeight is size including stuff not visible due to scrolling.

Viewport dimensions

You can get the dimensions of the viewport itself - ie the browser window - using the window object:

window.innerWidth;
window.innerHeight;

Or the user's screen:

window.screen.innerWidth;
window.screen.innerHeight;

Read more

Centre points

Once you have the coordinates and dimensions of an element, you can calculate its centre.

For example, to position an element in the middle of the viewport:

const winHalfWidth = window.innerWidth / 2;
const winHalfHeight = window.innerHeight /2;

const el = document.getElementById('box');
const elRect = el.getBoundingClientRect();
const elHalfWidth = elRect.width / 2;
const elHalfHeight = elRect.height / 2;

el.style.left = (winHalfWidth-elHalfWidth) + "px";
el.style.top = (winHalfHeight-elHalfHeight) +"px";

In most cases though you'll want to set positions using CSS, since it takes care of when the browser resizes and so on.

More