Menu Search
Jump to the content X X
Smashing Conf Barcelona 2016

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

Thinking Inside The Box With Vanilla JavaScript

During the past four or five years of blogging regularly and doing research for other writing projects, I’ve come across probably thousands of articles on JavaScript.

To me, it seems that a big chunk of these articles can be divided into two very general categories:

  1. jQuery;
  2. Theory and concept articles focused on things like IIFEs1, closures2 and design patterns3.

Yes, I’ve likely stumbled upon a ton of other articles that don’t fall into either of these categories or that are more specific. But somehow it feels that most of the ones that really get pushed in the community fall under one of the two categories above.

I think those articles are great, and I hope we see more of them. But sometimes the simplest JavaScript features are sitting right under our noses and we just haven’t had a lot of exposure to them. I’m talking about native, more-or-less cross-browser features that have been in the language for some time.

So, in this article, I won’t be talking about jQuery, and I won’t be looking at structural code concepts or patterns. Instead, I’m going to introduce you to some pure JavaScript features that you can use today and that you might not have ever considered before.

insertAdjacentHTML() Link

Years ago, Microsoft introduced a method called insertAdjacentHTML() as a way to insert a specified string of text as HTML or XML into a specific place in the DOM. This feature has been available in Internet Explorer (IE) since version 4. Let’s see how it works.

Suppose you have the following HTML:

<div id="box1">
    <p>Some example text</p>
<div id="box2">
    <p>Some example text</p>

And suppose you want to insert another snippet of HTML between #box1 and #box2. You can do this quite easily using insertAdjacentHTML():

var box2 = document.getElementById("box2");
box2.insertAdjacentHTML('beforebegin', '<div><p>This gets inserted.</p></div>');

With that, the generated DOM ends up like this:

<div id="box1">
    <p>Some example text</p>
<div><p>This gets inserted.</p></div>
<div id="box2">
    <p>Some example text</p>

The insertAdjacentHTML() method takes two parameters. The first defines where you want to place the HTML, relative to the targeted element (in this case, the #box2 element). This may be one of the following four string values:

  • beforebegin
    The HTML would be placed immediately before the element, as a sibling.
  • afterbegin
    The HTML would be placed inside the element, before its first child.
  • beforeend
    The HTML would be placed inside the element, after its last child.
  • afterend
    The HTML would be placed immediately after the element, as a sibling.

Again, these are string values, not keywords, so they must be placed inside of single or double quotes.

The second parameter is the string you want to insert, also placed in quotes (or else it would be a variable holding a string that was previously defined). Note that it should be a string, not a DOM element or element collection; so, it could just be text, with no actual markup.

insertAdjacentHTML() has, as outlined in a post on Mozilla Hacks5, a couple of advantages over something more conventional, like innerHTML(): It does not corrupt the existing DOM elements, and it performs better.

And if you’re wondering why this one hasn’t received a lot of attention so far, despite being well supported in all in-use versions of IE, the reason is probably that, as mentioned in the Mozilla Hacks article, it was not added to Firefox until version 8. Because all other major browsers support this, and Firefox users have been auto-updating since version 5, it’s quite safe to use.

For more on this method:

getBoundingClientRect() Link

You can obtain the coordinates and, by extension, the dimensions of any element on the page using another lesser-known method, the getBoundingClientRect() method.

Here’s an example of how it might be used:

var box = document.getElementById('box'),
    x, y, w;

x = box.getBoundingClientRect().left;
y = box.getBoundingClientRect().top;

if (box.getBoundingClientRect().width) {
  w = box.getBoundingClientRect().width; // for modern browsers
} else {
  w = box.offsetWidth; // for oldIE

console.log(x, y, w);

Here, we’ve targeted an element with an ID of box, and we’re accessing three properties of the getBoundingClientRect() method for the #box element. Here’s a summary of six fairly self-explanatory properties that this method exposes:

  • top
    How many pixels the top edge of the element is from the topmost edge of the viewport
  • left
    How many pixels the left edge of the element is from the leftmost edge of the viewport
  • right
    How many pixels the right edge of the element is from the leftmost edge of the viewport
  • bottom
    How many pixels the bottom edge of the element is from the topmost edge of the viewport
  • width
    The width of the element
  • height
    The height of the element

All of these properties are read-only. And notice that the coordinate properties (top, left, right and bottom) are all relative to the top-left of the viewport.

What about the if/else in the example from above? IE 6 to 8 don’t support the width and height properties; so, if you want full cross-browser support for those, you’ll have to use offsetWidth and/or offsetHeight.

As with insertAdjacentHTML(), despite the lack of support for width and height, this method has been supported in IE since ancient times, and it has support everywhere else that’s relevant, so it’s pretty safe to use.

I will concede something here: Getting the coordinates of an element using offset-based values (such as offsetWidth) is actually faster than using getBoundingClientRect()9. Note, however, that offset-based values will always round to the nearest integer, whereas getBoundingClientRect()’s properties will return fractional values.

For more info:

The <table> API Link

If you’ve ever manipulated elements on the fly with JavaScript, then you’ve likely used methods such as createElement, removeChild, parentNode and related features. And you can manipulate HTML tables in this way, too.

But you may not realize that there is a very specific API for creating and manipulating HTML tables with JavaScript, and it has very good browser support. Let’s take a quick look at some of the methods and properties available with this API.

All of the following methods are available to be used on any HTML table element:

  • insertRow()
  • deleteRow()
  • insertCell()
  • deleteCell()
  • createCaption()
  • deleteCaption()
  • createTHead()
  • deleteTHead()

And then there are the following properties:

  • caption
  • tHead
  • tFoot
  • rows
  • rows.cells

With these features, we can create an entire table, including rows, cells, a caption and cell content. Here’s an example:

var table = document.createElement('table'),
    tbody = document.createElement('tbody'),
    i, rowcount;


for (i = 0; i <= 9; i++) {
  rowcount = i + 1;
  tbody.rows[i].cells[0].appendChild(document.createTextNode('Row ' + rowcount + ', Cell 1'));
  tbody.rows[i].cells[1].appendChild(document.createTextNode('Row 1, Cell 2'));
  tbody.rows[i].cells[2].appendChild(document.createTextNode('Row 1, Cell 3'));

table.caption.appendChild(document.createTextNode('A DOM-Generated Table'));


The script above combines some customary core DOM methods with methods and properties of the HTMLTableElement API. The same code written without the table API might be considerably more complex and, thus, harder to read and maintain.

Once again, these table-related features have support all the way back to IE 7 (and probably earlier) and everywhere else that’s relevant, so feel free to use these methods and properties where you see fit.

For more info:

  • HTMLTableElement13,” Mozilla Developer Network
  • “Tabular Data,” in the “HTML” specification, WHATWG

Wrapping Up Link

This discussion of specific native JavaScript features has been a reminder of sorts. We can easily become comfortable with the features of a language that we know well, without looking deeper into the language’s syntax for simpler and more maintainable ways to solve our problems.

So, from time to time, look inside the box, so to speak. That is, investigate all that vanilla JavaScript has to offer14, and try not to rely too much on plugins and libraries, which can unnecessarily bloat your code.

(Credits of image on front page: nyuhuhuu15)

(al ea)

Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4,js,output
  5. 5
  6. 6
  7. 7
  8. 8,js,output
  9. 9
  10. 10
  11. 11
  12. 12,js,output
  13. 13
  14. 14
  15. 15
SmashingConf Barcelona 2016

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf Barcelona, on October 25–26, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook


Louis Lazaris is a freelance web developer and author based in Toronto, Canada. He blogs about front-end code on Impressive Webs and curates Web Tools Weekly, a weekly newsletter for front-end developers.

  1. 1

    Thanks a lot for this article; it helps showing the pure power of JavaScript instead of that magic library we all use. I have the feeling that a more and more people know jQuery, but actually forget what is happening under the hood. Nice read!

    • 2

      I really hope people do not use these tools. They are outdated, cumbersome, not always cross browser friendly, and for goodness sake, no one should be building markup with javascript in modern times.

      jQuery may irk purists, but it is generally way easier to maintain, and in our fast moving tech world, that is priority one.

      • 3

        “for goodness sake, no one should be building markup with javascript in modern times”

        When you say this — do you mean people should use jQuery to build markup and not bother to know how to do it in the base language, or that markup should not be generated client-side at all?

      • 4

        Yeah. Let’s all add 90k (compressed) to our page size BEFORE we’ve even written any code…

        Most of that 90k, you won’t even use.

        • 5

          90k if it’s not already in your browser’s cache, which it might very well be if you i.e. use the google hosted jquery versions or another global cdn. For mobile (where 90k is a lot more than for desktops) we use stripped versions like zepto which can be as small as 9k. And yes, you might very well decide this BEFORE writing any code, with techniques like caching that is not a bad practice ;)

          • 6

            You’ve got to remember that JQuery et al are free as in speech (not beer) ;)

            Yes, you can (and should cache) static resources, but you don’t control the end users cache (

            Network performance isn’t the only consideration. What about memory consumption and battery life? How many objects is that 90k of javascript creating in the device’s memory?

            There is also technical debt and maintainability to consider (personally I don’t like the way JQuery is written – in my experience is makes hard to read code that is painful to maintain).

            Mindlessly including any JS Library because “that’s what everyone else does” (I refer to the millions of JQuery/Javascript how to articles or the “Look a CSS only…” articles that loads up 1Mb of JS) is only going to lead to trouble – what happens when your users discover a bug in code that comes from the library, who fixes it…?

        • 7

          I don’t like using JQuery either but there is a way to build a JQuery file that includes only the modules that you use. For example if you only use the css and ajax modules => 28kb minified+gziped file, it’s still crappy but at least 1/3rd smaller.

          There are CLIs like `npm install -g jquery-builder` and there are websites like for it

    • 8

      Very true Sander. I’ve come across a lot of people who when they started their career, learnt jQuery first and even today aren’t very comfortable with native JavaScript. Have seen situations where 1kb of native JavaScript is enough to achieve the desired result but people go ahead and include a 90Kb plus file instead.

    • 9

      petr Tomkevich

      January 20, 2014 9:22 am

      Thanks for digging up some useful functionality in the DOM. Vanilla JS is the best.

  2. 10

    Great examples! I often use jQuery in my projects, but I know that it’s not always necessary – in many cases things can be done with better performance in pure JS.

    Here is some other examples with jQuery vs pure JS and comparisons of performance:

  3. 11

    Amitay Horwitz

    October 6, 2013 11:56 pm

    It’s important to draw the line between the JavaScript language itself and the DOM API. These features belong to the DOM, rather than the language – but I agree it’s useful to be aware of them (and others)

    • 12

      Louis Lazaris

      October 7, 2013 12:22 am

      Agreed — good point. Thanks for adding that clarification. For example, these features are not mentioned in the ECMA spec. I guess this is more about the fact that these can be used natively, without a library or framework, in all browsers.

  4. 13

    Joey Hipolito

    October 6, 2013 11:57 pm

    I didn’t know that those thing actually exist. Thanks a lot!

    • 14

      Don’t worry. I think the most of people didn’t know it, including me =).
      Great article!

  5. 15

    Mark Ross Smith

    October 7, 2013 2:10 am

    Great article! I admit I am a jQuery addict, and often forget the raw power of the native JS library. I’ve used some of these features in the past, but never the table API which I never realised existed to this extent.

    I really should look towards achieving functionality using barebones JS before screaming in horror and running to grab the nearest JS library.


  6. 16

    You made me happy. I’m one of those developers who respect the power of jQuery but at the same time, prefer vanilla JavaScript.

    I found the insertAdjacentHTML() and getBoundingClientRect() really interesting.

    Thanks a lot for such a great article and I would like to see more articles on DOM or vanilla JavaScript from you.


  7. 17

    Izrada web stranica

    October 7, 2013 3:34 am

    Nice examples of vanilla js. Good article bro. Keep going! :)

  8. 18

    Great read. Thanks. I often struggle to find simple solutions when searching on the internet that don’t use jquery. I love pure JS without extra libraries, such as mootools, scriptaculous, prototype and jquery etc. Thanks for the article.

  9. 19

    Rodney Solomon

    October 7, 2013 6:42 am

    Can this be potentially used by hackers?

  10. 21

    Jack Tarantino

    October 7, 2013 7:01 am

    Good post. I’d love to see a series of these! Something showing off the raw power of javascript and how so many of the features that we rely on from libraries are really just wrappers or worse for features that are already in browsers. Thanks again!

  11. 22

    wow…. getting right and bottom of elements really awesome.

  12. 23

    Aaron Martone

    October 7, 2013 8:47 am

    A problem many developers have is to be set with the language they learned (even the current iteration) and not allow themselves to progress and take in the benefits and functions of innovations such as jQuery is to JavaScript.

    BUT, at the same time, you have to ask yourself whether the scope of what it is you want to DO with the language, warrant the load of this new tech. It’s a fine line between hopping on the bandwagon for the same of something new vs. staying with what you know for fear of learning something new.

    The solution here is to just apply what is necessary to meet the requirements, and nothing more. If good ol’ JavaScript is what we need, it would be reckless to just “add jQuery” because it provides so much functionality that, in this case, would be wasted.

    Good article; as developers, we need only apply functionality the meets the need, rather than exceed it. It’s not an argument of declaring that “Just adding jQuery makes the application instantly future-proofed and scale-able.” In this world of mobile-heavy device usage, we need to remain ever-mindful of the load being put on the devices that access our projects.

  13. 24

    Doug McDonald

    October 7, 2013 10:31 am

    I do agree that often native JS functions go under-appreciated and or under-used but one thing I’d mention from an enterprise POV is that throughout a project we strive for consistency to ease new developers picking up project.

    Since many things are easier via a library/framework chosen for that project, we try to avoid mixing too many approaches.

    As a result, I’d typically say that if the project uses native JS, use it throughout, similarly if we’re using jQuery use it throughout. We recently wrote a Win8 app with WinJS and intentionally didn’t use jQuery as we wanted both exposure to, and consistency of approach and syntax.

    My only point being, for larger apps, if there a lot of areas where libraries are used, it can be slightly confusing to see native JS if it’s not expected. “Is this page old?/new?” , “Was there some reason why it’s not the same?”. So in summary I totally support the usage of native functions, as long as it’s not inconsistent with usage of libraries to perform the same function.

    • 25

      Something equally underappreciated would be comments in JS code (or code in general) which would solve all problems concerning confusion you mentioned and help with various mainetance issues – but that’s another story.

  14. 26

    Nice, thank you!

  15. 27

    Michael Warren

    October 7, 2013 10:47 am

    The main problem here is the IDs everywhere. IDs are notoriously bad unless used very sparingly since they need to be unique, so using raw JS, you either have to 1) put IDs everywhere to stick with native JS, or 2) add in some css selector engines on top to give you the DOM traversal/selection power of jquery without jquery (which essentially means you have jquery anyway).

    Personally, I don’t use jquery just for little things like appending and adding table rows, etc. I use it for DOM traversal excellence and accept that it has things like .append() along the way.

    • 28

      Louis Lazaris

      October 7, 2013 9:59 pm

      If you don’t require IE6/7 support, which is becoming more likely every month, then you can use querySelector/querySelectorAll, which is supported in IE8. You just have to remember that you can’t use CSS3 selectors when using qs/qsa in IE8.

    • 29

      You can also just include sizzle, which is the selector engine used by jQuery, so you get the ease of jquery selecting without the bulk of jquery. only 4kb!!

    • 30

      To add on the comments of the previous commentators: You could also easily use getElementByClass. This is supported by all browsers except our favorite douchebag Internet Exploiter.

      For this nasty old wheezer you just use some workarounds. Nonetheless, knowing your way around the JS world WITHOUT having to rely on some huge framework just to get some simple stuff done – that gives you quite the good felling in your tummy ;)

      cu, w0lf.

      ps: Why use stuff like append and prepend? That is just a simple wrapper of jQuery for DOM traversal in combination with its selector engine. No need to use THAT bit for simple JS handiwork.

      cu, w0lf.

  16. 31

    Thanks for this nice article and clever point of view: never forget the basics.

  17. 32

    Hi Louis, really nice outside the box article.. Many times we focus on using frameworks and forget to check if a “native” technique already exists to do the same thing… Especially I like very much the Table API features you have listed.. Thanks to share the post!

  18. 33

    Ricardo Muniz Crespo

    October 7, 2013 11:26 pm

    A really bad habit of mine consist out of using jQuery for every little piece, which could usually be replaced with basic JavaScript. Unfortunately importing the library each and every single time adds a huge load to the websites I built, although it is not necessary. Thank you for sharing, I will check out the sources.

  19. 34

    Awesome post. Thanks.

  20. 35

    Marco Barbosa

    October 8, 2013 2:20 am

    Just learned about getBoundingClientRect last week and it’s pretty useful!

    Gotta love vanilla Javascript :)


↑ Back to top