---
title: Bitovi Academy - Layout
description: Learn how the browser lays out elements in the page and how to get an elements dimensions and location.
---

- ![AI implementation](https://www.bitovi.com/hubfs/AIConsultingIcon.svg)
  
  [AI implementation](https://www.bitovi.com/services/ai-consulting?hsLang=en-us)
- ![Systems engineering](https://www.bitovi.com/hubfs/icon%20-%20backend.svg)
  
  [Systems engineering](https://www.bitovi.com/services/systems-engineering-consulting?hsLang=en-us)
- ![Project management](https://www.bitovi.com/hubfs/icon%20-%20PM.svg)
  
  [Project management](https://www.bitovi.com/services/agile-project-management-consulting?hsLang=en-us)
- ![Product design](https://www.bitovi.com/hubfs/icon%20-%20design.svg)
  
  [Product design](https://www.bitovi.com/services/product-design-consulting?hsLang=en-us)
- ![Frontend development](https://www.bitovi.com/hubfs/icon%20-%20frontend.svg)
  
  [Frontend development](https://www.bitovi.com/services/frontend-development-consulting?hsLang=en-us)
- [View more
  
  →
  
  ](https://www.bitovi.com/digital-consulting-services?hsLang=en-us)

We're Experts in...

- [JavaScript](https://www.bitovi.com/services/frontend/javascript-consulting?hsLang=en-us)
- [AI training](https://www.bitovi.com/ai-training-for-software-engineers?hsLang=en-us)
- [Angular](https://www.bitovi.com/services/frontend/angular-consulting?hsLang=en-us)
- [Design Systems](https://www.bitovi.com/services/axure-figma-migration?hsLang=en-us)
- [React](https://www.bitovi.com/services/frontend/react-consulting?hsLang=en-us)
- [Temporal](https://www.bitovi.com/services/backend/temporal-consulting?hsLang=en-us)
- [React Native](https://www.bitovi.com/services/frontend/react-consulting/react-native?hsLang=en-us)
- [Node.js](https://www.bitovi.com/services/backend/nodejs-consulting-1?hsLang=en-us)

Showcase

![Yum! Brands](https://www.bitovi.com/hubfs/yum-showcase-link-1.png)

[View case study](https://www.bitovi.com/en/bitovi-yum-case-study?hsLang=en-us)

More Projects

- [![Levi's](https://www.bitovi.com/hubfs/levis.svg)](https://www.bitovi.com/web-application-consulting-work/levis-ecommerce-responsive-redesign?hsLang=en-us)
- [![Christie's International Real Estate](https://www.bitovi.com/hubfs/christies.svg)](https://design.bitovi.com/christies)
- [![BAFS](https://www.bitovi.com/hubfs/bafs.svg)](https://www.bitovi.com/ux-design-consulting/ux-case-studies/bafs-ppp?hsLang=en-us)
- [View more
  
  →
  
  ](https://www.bitovi.com/our-software-consulting-work?hsLang=en-us)

Open Source Tools

We build powerful tools and open source them to support the community.

[See what we've built →](https://www.bitovi.com/open-source?hsLang=en-us)

- [![Blog](https://www.bitovi.com/hubfs/icon%20-%20blog.svg)
  
  BlogWe post about perfecting software delivery
  
  ](https://bitovi.com/blog)
- [![Partnerships](https://www.bitovi.com/hubfs/Handshake-1.svg)
  
  PartnershipsLearn about Bitovi's technology partners
  
  ](https://www.bitovi.com/partnerships?hsLang=en-us)
- [![Academy](https://www.bitovi.com/hubfs/limbo/icons/icon-academy.svg)
  
  AcademyFree courses to build delivery skills
  
  ](https://www.bitovi.com/academy/?hsLang=en-us)
- [![Open source tools](https://www.bitovi.com/hubfs/icon%20-%20open%20source.svg)
  
  Open source toolsUse our tools or contribute to our open source mission.
  
  ](https://www.bitovi.com/open-source?hsLang=en-us)

Let's Connect

- [![Discord](https://www.bitovi.com/hubfs/DiscordLogo.svg)
  
  Discord
  
  ](https://discord.gg/J7ejFsZnJ4)
- [![LinkedIn](https://www.bitovi.com/hubfs/LinkedinLogo.svg)
  
  LinkedIn
  
  ](https://www.linkedin.com/company/bitovi/)
- [![GitHub](https://www.bitovi.com/hubfs/GithubLogo.svg)
  
  GitHub
  
  ](https://github.com/bitovi/)

![Eggbot](https://www.bitovi.com/hubfs/build_assets/bitovi-limbo-cms-react/338/js_client_assets/assets/eggbot-LTGhdSGL.png)

Name *

Work Email *

Phone

What's your project?

Send

### Contact Us

(312) 620-0386contact@bitovi.com

- [ Advanced JavaScript ](https://www.bitovi.com/academy/learn-advanced-javascript.html?hsLang=en-us)
- [ DOM and jQuery ](https://www.bitovi.com/academy/learn-dom-jquery.html?hsLang=en-us) 
    - [ Functional Utilities ](https://www.bitovi.com/academy/learn-dom-jquery/functional-utilities.html?hsLang=en-us)
    - [ Finding Elements ](https://www.bitovi.com/academy/learn-dom-jquery/finding-elements.html?hsLang=en-us)
    - [ Traversing Elements ](https://www.bitovi.com/academy/learn-dom-jquery/traversing-elements.html?hsLang=en-us)
    - [ Attributes and Properties ](https://www.bitovi.com/academy/learn-dom-jquery/attributes-and-properties.html?hsLang=en-us)
    - [ Layout ](https://www.bitovi.com/academy/learn-dom-jquery/layout.html?hsLang=en-us)
    - [ Events Part 1 ](https://www.bitovi.com/academy/learn-dom-jquery/events-part-1.html?hsLang=en-us)
    - [ Events Part 2 ](https://www.bitovi.com/academy/learn-dom-jquery/events-part-2.html?hsLang=en-us)
    - [ Fn Plugins ](https://www.bitovi.com/academy/learn-dom-jquery/fn-plugins.html?hsLang=en-us)
    - [ Tabs Widget ](https://www.bitovi.com/academy/learn-dom-jquery/tabs-widget.html?hsLang=en-us)
- [ Debug JavaScript ](https://www.bitovi.com/academy/learn-to-debug-javascript.html?hsLang=en-us)
- [ Learn TypeScript ](https://www.bitovi.com/academy/learn-typescript.html?hsLang=en-us)
- [ Learn React Native ](https://www.bitovi.com/academy/learn-react-native.html?hsLang=en-us)
- [ Learn Web Components ](https://www.bitovi.com/academy/learn-web-components.html?hsLang=en-us)
- [ Agile Program Management With Jira ](https://www.bitovi.com/academy/learn-agile-program-management-with-jira.html?hsLang=en-us)
- [ Learn RxJS ](https://www.bitovi.com/academy/learn-rxjs.html?hsLang=en-us)
- [ Giving a Training ](https://www.bitovi.com/academy/training.html?hsLang=en-us)
- [ Learn Technology Consulting ](https://www.bitovi.com/academy/learn-technology-consulting.html?hsLang=en-us)
- [ Learn React ](https://www.bitovi.com/academy/learn-react.html?hsLang=en-us)
- [ Learn NgRx ](https://www.bitovi.com/academy/learn-ngrx.html?hsLang=en-us)
- [ Learn Graphql ](https://www.bitovi.com/academy/learn-graphql.html?hsLang=en-us)
- [ Learn Docker ](https://www.bitovi.com/academy/learn-docker.html?hsLang=en-us)
- [ Learn CanJS ](https://www.bitovi.com/academy/learn-canjs.html?hsLang=en-us)
- [ Learn Angular ](https://www.bitovi.com/academy/learn-angular.html?hsLang=en-us)
- [ Advanced TypeScript ](https://www.bitovi.com/academy/advanced-typescript.html?hsLang=en-us)

[View More Courses](https://www.bitovi.com/academy/#courses) [ ]

# Layout `page`

Learn how the browser lays out elements in the page and how to get an elements dimensions and location.

## Slides

## Slider Demo

Understanding how the DOM is positioned helps build dynamic widgets. The following

```
<style>
.slider {
    border: solid 1px blue;
    background-color: red;
    height: 40px;
    width: 40px;
    cursor: ew-resize;
    position: relative;
}
.container, percent-slider {
    border: solid 4px black;
    padding: 5px;
    display: block;
}
</style>

<slider-demo></slider-demo>

<script type="module">
import { Component } from "//unpkg.com/can@5/core.mjs";

function width(el) {
    var cs = window.getComputedStyle(el,null)
    return el.clientWidth - parseFloat( cs.getPropertyValue("padding-left") )
        - parseFloat( cs.getPropertyValue("padding-left") );
}

Component.extend({
    tag: "percent-slider",
    view: `
        <div class='slider'

        on:mousedown='startDrag(scope.event.clientX)'/>`,
    ViewModel: {
        start: {type: "number", default: 0},
        end: {type: "number", default: 1},
        currentValue: {
            default: function(){
                return this.value || 0;
            },
            set(value) {
                return Math.min( Math.max(this.start, value), this.end) || 0;
            }
        },
        width: {type: "number", default: 0},
        get left(){
            var left = ( (this.currentValue - this.start) / (this.end - this.start) ) * this.width;
            return Math.min( Math.max(0, left), this.width) || 0;
        },
        connectedCallback(el) {
            // derive the width
            this.width = width(el) - el.firstElementChild.offsetWidth;
            this.listenTo(window,"resize", () => {
                this.width = width(el) - el.firstElementChild.offsetWidth;
            });

            // Produce dragmove and dragup events on the view-model
            this.listenTo("startClientX", () => {
                var startLeft = this.left;
                this.listenTo(document,"mousemove", (event)=>{
                    this.dispatch("dragmove", [event.clientX - this.startClientX + startLeft]);
                });
                this.listenTo(document,"mouseup", (event)=>{
                    this.dispatch("dragup", [event.clientX - this.startClientX + startLeft]);
                    this.stopListening(document);
                })
            });
            // Update the slider position when currentValue changes
            this.listenTo("dragmove", (ev, left)=> {
                this.currentValue = this.start + (left / this.width) * (this.end - this.start);
            },"notify");

            // If the value is set, update the current value
            this.listenTo("value", (ev, newValue) => {
                this.currentValue = newValue;
            }, "notify");

            // Update the value on a dragmove
            this.listenTo("dragup", (ev, left)=> {
                this.currentValue = this.start + (left / this.width) * (this.end - this.start);
            },"notify");

            this.listenTo("left", function(ev, left){
                el.firstElementChild.style.left = ""+left+"px";
            },"notify");
            el.firstElementChild.style.left = ""+this.left+"px";

            return this.stopListening.bind(this);
        },
        startClientX: "any",
        startDrag(clientX) {
            this.startClientX = clientX;
        }
    }
});

Component.extend({
    tag: "slider-demo",
    view: `
        <percent-slider currentValue:bind='this.value' el:this:to="this.valueSlider"/>
        <div>Value <strong id='progress'>{{this.value}}</strong></div>

        <percent-slider start:from='0' end:from='40' currentValue:bind='this.padding' />
        <div>Container padding <strong id='progress'>{{this.padding}}</strong></div>

        <percent-slider start:from='10' end:from='70' currentValue:bind='this.width' />
        <div>Height / Width <strong id='progress'>{{this.width}}</strong></div>
    `,
    ViewModel: {
        value: {default: 0.5},
        padding: {default: 20},
        width: {default: 40},
        valueSlider: "any",
        connectedCallback(el) {
            const setPadding = (ev, newPadding) => {
                this.valueSlider.style.padding = ""+newPadding+"px";
                window.dispatchEvent( new Event("resize") );
            }
            this.listenTo("padding", setPadding);
            setPadding(null, this.padding);

            const setHeightWidth = (ev, newWidth) => {
                 this.valueSlider.firstElementChild.style.width = ""+newWidth+"px";
                 this.valueSlider.firstElementChild.style.height = ""+newWidth+"px";
                 window.dispatchEvent( new Event("resize") );
            };
            this.listenTo("width", setHeightWidth);
            setHeightWidth(null, this.width);
        }
    }
})

</script>

```

## Setup

Run the following example in CodePen:

```
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.12.0.css">
<script src="//code.jquery.com/qunit/qunit-1.12.0.js"></script>
<script src="//bitovi.github.io/academy/static/scripts/jquery-test.js"></script>
<link rel="stylesheet" href="//bitovi.github.io/academy/static/scripts/jquery-test.css">
<script type="module">
(function() {
  $ = function(selector) {
    if ( !(this instanceof $) ) {
      return new $(selector);
    }
    var elements;
    if (typeof selector === "string") {
      elements = document.querySelectorAll(selector);
    } else if ($.isArrayLike(selector)) {
      elements = selector;
    }
    [].push.apply(this, elements);
  };

  $.extend = function(target, object) {
    for (var prop in object) {
      if (object.hasOwnProperty(prop)) {
        target[prop] = object[prop];
      }
    }
    return target;
  };

  // Static methods
  $.extend($, {
    isArray: function(obj) {
      return Object.prototype.toString.call(obj) === "[object Array]";
    },
    isArrayLike: function(obj) {
      return obj &&
        typeof obj === "object" &&
        (   obj.length === 0 ||
            typeof obj.length === "number" &&
            obj.length > 0 &&
            obj.length - 1 in obj );

    },
    each: function(collection, cb) {
      if ($.isArrayLike(collection)) {
        for (var i = 0; i < collection.length; i++) {
          if (cb.call(this, i, collection[i]) === false) {
            break;
          }
        }
      } else {
        for (var prop in collection) {
          if (collection.hasOwnProperty(prop)) {
            if (cb.call(this, prop, collection[prop]) === false) {
              break;
            }
          }
        }
      }
      return collection;
    },
    makeArray: function(arr) {
      if ($.isArray(arr)) {
        return arr;
      }
      var array = [];
      $.each(arr, function(i, item) {
        array[i] = item;
      });
      return array;
    },
    proxy: function(fn, context) {
      return function() {
        return fn.apply(context, arguments);
      };
    }
  });

  function makeTraverser(traverser) {
    return function() {
      var elements = [], args = arguments;
      $.each(this, function(i, element) {
        var els = traverser.apply(element, args);
        if ($.isArrayLike(els)) {
          elements.push.apply(elements, els);
        } else if (els) {
          elements.push(els);
        }
      });
      return $(elements);
    };
  }

  $.extend($.prototype, {
    html: function(newHtml) {
      if(arguments.length) {
        return $.each(this, function(i, element) {
          element.innerHTML = newHtml;
        });
      } else {
        return this[0].innerHTML;
      }
    },
    val: function(newVal) {
      if(arguments.length) {
        return $.each(this, function(i, element) {
          element.value = newVal;
        });
      } else {
        return this[0].value;
      }
    },
    text: function(newText) {
      if (arguments.length) {
        return $.each(this, function(i, element) {
          element.textContent = newText;
        });
      } else {
        return this[0].textContent;
      }
    },
    find: makeTraverser(function(selector) {
      return this.querySelectorAll(selector);
    }),
    parent: makeTraverser(function() {
      return this.parentNode;
    }),
    next: makeTraverser(function() {
      return this.nextElementSibling;
    }),
    prev: makeTraverser(function() {
      return this.previousElementSibling;
    }),
    children: makeTraverser(function() {
      return this.children;
    }),
    attr: function(attrName, value) {
      if (arguments.length == 2) {
        return $.each(this, function(i, element) {
          element.setAttribute(attrName, value);
        });
      } else {
        return this[0] && this[0].getAttribute(attrName);
      }
    },
    css: function(cssPropName, value) {
      if (arguments.length == 2) {
        return $.each(this, function(i, element) {
          element.style[cssPropName] = value;
        });
      } else {
        return this[0] &&
          window.getComputedStyle(this[0])
            .getPropertyValue(cssPropName);
      }
    },
    addClass: function(className) {
      return $.each(this, function(i, element) {
        element.classList.add(className);
      });
    },
    removeClass: function(className) {
      return $.each(this, function(i, element) {
        element.classList.remove(className);
      });
    },
    width: function() { },
    hide: function() { },
    show: function() { },
    offset: function() { }
  });

})();
</script>

```

Each exercise builds on the previous exercise. There is a completed solution at the end of this page.

## Exercise: `collection.width() -> number`

### The problem

[collection.width](http://api.jquery.com/width/) gets the current computed width for the first element in the set of matched elements.

```
<div class="outer"><div class="inner">Hi</div></div>
<style>
  .outer {
    width: 100px;
  }
  .inner {
    border: solid 5px green;
    padding: 10px;
  }
</style>
<script type="module">
  import "https://unpkg.com/jquery@3/dist/jquery.js";

  console.log($(".inner").width()); // Logs 70
</script>
```

Click to see test code

```
QUnit.test('$.fn.width', function(){
    // .big-width { width: 1000px; ... }
    // #qunit-fixture div { padding: 20px; border: solid 10px black; }
    $('#qunit-fixture')
        .html('<div class="big-width"><div>Element</div></div>');
    equal(
        $('#qunit-fixture .big-width div').width(),
        1000 - 60,
        'width is correct');
});
```

### What you need to know

- The [clientWidth](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth) property returns the width of the element including the padding.
- You can read the computed `padding-left` and `padding-right` style properties.
- Use [parseInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt) to convert a string to a number. Make sure to include a radix argument!
  
  ```
  console.log(parseInt("011")); //-> 11 or 9 depending on the browser!
  console.log(parseInt("011", 10)); //-> 11
  console.log(parseInt("011px", 10)); //-> 11
  ```

### The solution

Click to see the solution

```
    width: function() {
      var paddingLeft = parseInt(this.css("padding-left"), 10),
      paddingRight = parseInt(this.css("padding-right"), 10);
      return this[0].clientWidth - paddingLeft - paddingRight;
    },
```

## Exercise: `collection.show()` and `collection.hide()`

### The problem

[collection.show()](http://api.jquery.com/show/) and [collection.hide()](http://api.jquery.com/hide/) show or hide the elements in the collection.

Click to see test code

```
QUnit.test('$.fn.show and $.fn.hide', function(){
    $('#qunit-fixture').html('<div id="el">text</div>');

    equal( $('#el').hide()[0].style.display, 'none');
    equal( $('#el').show()[0].style.display, '');

});

```

### What you need to know

- To hide an element, set its display to `"none"`.
- To show an element, set its display to `""`.

### The solution

Click to see the solution

```
    hide: function() {
      return this.css("display", "none");
    },
    show: function() {
      return this.css("display", "");
    },
```

## Bonus Exercise: `collection.offset()`

### The problem

[collection.offset()](http://api.jquery.com/offset/) returns the current coordinates of the first element relative to the document.

```
<div class="outer"><div class="inner">Hi</div></div>
<style>
  .outer {
    position: absolute;
    left: 20px;
    top: 30px;
  }
  .inner {
    border: solid 1px green;
    padding: 10px;
    position: relative;
    left: 10px;
    top: 10px;
  }
</style>
<script type="module">
  import "https://unpkg.com/jquery@3/dist/jquery.js";

  console.log($(".inner").offset());
  // Logs { left: 30, top: 40 }
</script>
```

Click to see test code

```
QUnit.test("$.fn.offset", function () {
  var bigWidth = document.createElement("div"),
    row1 = document.createElement("div"),
    row2 = document.createElement("div"),
    pos = document.createElement("div");

  bigWidth.className = "big-width";
  row1.className = "row";
  row2.className = "row";
  pos.id = "pos";

  bigWidth.appendChild(row1);
  bigWidth.appendChild(row2);
  row2.appendChild(pos);

  document.body.appendChild(bigWidth);

  var offset = $("#pos").offset();

  equal(offset.top, 120, "top");
  equal(offset.left, -990, "left");

  //cleaning up after our test
  var node = $(".big-width")[0];
  node.parentNode.removeChild(node);
});
```

### What you need to know

- [getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) gives an element’s position relative to the window.
- [pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window/pageXOffset) and [pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window/pageYOffset) give how far the window has been scrolled.

### The solution

Click to see the solution

```
    offset: function() {
      var offset = this[0].getBoundingClientRect();
      return {
        top: offset.top + window.pageYOffset,
        left: offset.left + window.pageXOffset
      };
    }
```

## Complete solution

Click to see completed solution

```
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.12.0.css">
<script src="//code.jquery.com/qunit/qunit-1.12.0.js"></script>
<script src="//bitovi.github.io/academy/static/scripts/jquery-test.js"></script>
<link rel="stylesheet" href="//bitovi.github.io/academy/static/scripts/jquery-test.css">
<script type="module">
(function() {
  $ = function(selector) {
    if ( !(this instanceof $) ) {
      return new $(selector);
    }
    var elements;
    if (typeof selector === "string") {
      elements = document.querySelectorAll(selector);
    } else if ($.isArrayLike(selector)) {
      elements = selector;
    }
    [].push.apply(this, elements);
  };

  $.extend = function(target, object) {
    for (var prop in object) {
      if (object.hasOwnProperty(prop)) {
        target[prop] = object[prop];
      }
    }
    return target;
  };

  // Static methods
  $.extend($, {
    isArray: function(obj) {
      return Object.prototype.toString.call(obj) === "[object Array]";
    },
    isArrayLike: function(obj) {
      return obj &&
        typeof obj === "object" &&
        (   obj.length === 0 ||
            typeof obj.length === "number" &&
            obj.length > 0 &&
            obj.length - 1 in obj );

    },
    each: function(collection, cb) {
      if ($.isArrayLike(collection)) {
        for (var i = 0; i < collection.length; i++) {
          if (cb.call(this, i, collection[i]) === false) {
            break;
          }
        }
      } else {
        for (var prop in collection) {
          if (collection.hasOwnProperty(prop)) {
            if (cb.call(this, prop, collection[prop]) === false) {
              break;
            }
          }
        }
      }
      return collection;
    },
    makeArray: function(arr) {
      if ($.isArray(arr)) {
        return arr;
      }
      var array = [];
      $.each(arr, function(i, item) {
        array[i] = item;
      });
      return array;
    },
    proxy: function(fn, context) {
      return function() {
        return fn.apply(context, arguments);
      };
    }
  });

  function makeTraverser(traverser) {
    return function() {
      var elements = [], args = arguments;
      $.each(this, function(i, element) {
        var els = traverser.apply(element, args);
        if ($.isArrayLike(els)) {
          elements.push.apply(elements, els);
        } else if (els) {
          elements.push(els);
        }
      });
      return $(elements);
    };
  }

  $.extend($.prototype, {
    html: function(newHtml) {
      if(arguments.length) {
        return $.each(this, function(i, element) {
          element.innerHTML = newHtml;
        });
      } else {
        return this[0].innerHTML;
      }
    },
    val: function(newVal) {
      if(arguments.length) {
        return $.each(this, function(i, element) {
          element.value = newVal;
        });
      } else {
        return this[0].value;
      }
    },
    text: function(newText) {
      if (arguments.length) {
        return $.each(this, function(i, element) {
          element.textContent = newText;
        });
      } else {
        return this[0].textContent;
      }
    },
    find: makeTraverser(function(selector) {
      return this.querySelectorAll(selector);
    }),
    parent: makeTraverser(function() {
      return this.parentNode;
    }),
    next: makeTraverser(function() {
      return this.nextElementSibling;
    }),
    prev: makeTraverser(function() {
      return this.previousElementSibling;
    }),
    children: makeTraverser(function() {
      return this.children;
    }),
    attr: function(attrName, value) {
      if (arguments.length == 2) {
        return $.each(this, function(i, element) {
          element.setAttribute(attrName, value);
        });
      } else {
        return this[0] && this[0].getAttribute(attrName);
      }
    },
    css: function(cssPropName, value) {
      if (arguments.length == 2) {
        return $.each(this, function(i, element) {
          element.style[cssPropName] = value;
        });
      } else {
        return this[0] &&
          window.getComputedStyle(this[0])
            .getPropertyValue(cssPropName);
      }
    },
    addClass: function(className) {
      return $.each(this, function(i, element) {
        element.classList.add(className);
      });
    },
    removeClass: function(className) {
      return $.each(this, function(i, element) {
        element.classList.remove(className);
      });
    },
    width: function() {
      var paddingLeft = parseInt(this.css("padding-left"), 10),
      paddingRight = parseInt(this.css("padding-right"), 10);
      return this[0].clientWidth - paddingLeft - paddingRight;
    },
    hide: function() {
      return this.css("display", "none");
    },
    show: function() {
      return this.css("display", "");
    },
    offset: function() {
      var offset = this[0].getBoundingClientRect();
      return {
        top: offset.top + window.pageYOffset,
        left: offset.left + window.pageXOffset
      };
    }
  });

})();
</script>

```

###### On this page...

###### Get help

If you need [help](https://discord.gg/J7ejFsZnJ4) with an exercise, please reach out to us on [Discord](https://discord.gg/J7ejFsZnJ4)

If you find a bug, please [create an issue](https://github.com/bitovi/academy/issues/new) or email [contact@bitovi.com](mailto:contact@bitovi.com?Subject=Training%20Suggestion)

## Join the Bitovi Newsletter

 Do you want to receive updates about new Bitovi Academy courses, Bitovi open source projects, and dev community news? If so, please provide your email. We won’t spam you or give it away for any reason!  
*By providing your email you agree to receive communications from Bitovi*

![](https://bitovi.github.io/academy/static/img/close.svg)

```json
{
     "@context": "http://schema.org",
     "@type": "Organization",
     "mainEntityOfPage":{
          "@type":"WebPage",
          "@id":"https://www.bitovi.com/academy/learn-dom-jquery/layout.html",
          "description": "Learn how the browser lays out elements in the page and how to get an elements dimensions and location.

"
     },
     "url": "http://bitovi.com",
     "logo": "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg",
     "image": "https://www.bitovi.com/hubfs/bitovi-logo-x2.png",
     "name": "Bitovi Web App Consulting",
     "alternateName": "Bitovi",
      "naics": "541511",
      "description": "Bitovi is a UX, UI design and front-end JavaScript development consulting company",
     "address": {
          "@type": "PostalAddress",
          "streetAddress": "1134 Pine Tree Lane ",
          "addressLocality": "Libertyville",
          "addressRegion": "IL",
          "addressCountry": "United States",
          "postalCode": "60048"
     },
     "areaServed": {
          "@type": "GeoCircle",
          "geoMidpoint": {
               "@type": "GeoCoordinates",
               "latitude": "41.8781",
               "longitude": "87.6298"
          },
          "geoRadius": "5000 km"
     },
     "telephone": "312-620-0386",
     "email": "contact@bitovi.com",
     "sameAs": [
          "https://www.facebook.com/BitoviLLC/",
          "https://twitter.com/bitovi",
          "https://www.linkedin.com/company/bitovi"
     ]
}
```