We all love innerHTML

Published on Thursday, April 20th, 2006

This article is co-written with Anne van Kesteren, W3C Member and contributor to the WHATWG and Opera specifications, R&D and QA person.

When developing a web page, DOM methods are generally the way to go when dynamically altering elements’ attributes and performing other operations. But what about adding content to a web page in the most efficient manner, both code- and performance wise? We claim that innerHTML is unmatched by any DOM methods available and that it is in most, if not all, situations the best option.

People seem to have this feeling that innerHTML is evil. Instead of one line of innerHTML you would use about twenty lines with calls to the DOM. Every such line making one change. However, innerHTML is actually not that bad. The web browser pretty much parses it much like it parses the original page and builds some DOM nodes out of it which are then inserted at the requested location. Some mutation events are dispatched for the few who care and all is fine.

When it comes to having greater scalability in a web page, especially in AJAX scenarios, innerHTML offers unmatched flexibility. There has also been benchmark tests verifying that innerHTML is more efficient compared to using DOM methods.

The fact that it is not in a standard is simply because nobody got around to it. If you read the mailing list of the W3C Web API’s Working Group you can see that Opera, Mozilla and Apple want it to be standardized and we bet Microsoft would like the same thing. New entrants in the web browser market are probably interested as well given that it has to be supported anyway. That it’s not in a standard is probably its biggest problem, apart from the name which doesn’t really scale well. On the other hand, people complain a lot about document.write() as well which is part of DOM Level 2 HTML.

So, go on! Start, or continue, to use the best tool available for the job!

 

Related reading

36 comments

  • Sjoerd Visscher
    April 20th, 2006 at 23:39

    It’s not innerHTML that is the problem, but constructing HTML with string operations is. (No matter if it is done server side or client side.)

  • Tanny O’Haley
    April 21st, 2006 at 1:08

    Sjoerd,

    Why is it a problem to construct HTML with string operations?

  • Laurens Holst
    April 21st, 2006 at 2:31

    Because people tend to forget to escape the DOM methods, this isn’t necessary.

    ~Grauw

  • Laurens Holst
    April 21st, 2006 at 2:41

    (Well, the comment preview function of this blog clearly isn’t in sync with the server. Let’s try to recreate my comment.)

    Because people tend to forget to escape the < and & characters properly, which will then turn up as bugs, be fixed with ugly regular expressions, and create more bugs.

    With the DOM methods, this isn’t necessary, as you’re modifying the object model directly instead of a textual representation of it.

    In my experience, it is the cause of a lot of confusion for new JS programmers. Think ‘it breaks whenever I type a < here’, and ‘If I fix it with a regular expression, the smiley image tags will show up as text’.

    ~Grauw

  • Laurens Holst
    April 21st, 2006 at 2:47

    So in essence I’m saying that the problem is not that it’s not standardised (let’s be pragmatic here, all browsers support it), but simply that usually it’s not the right tool for the job :).

    In very early versions of Backbase we were still using innerHTML a lot, and it caused all kinds of bugs like ‘the error messages don’t show for URLs with a & in them’ and quite a couple more. Fortunately, these are long gone now and we learned the hard way that innerHTML is to be avoided for dynamic DOM manipulation as much as possible.

    But feel free to ignore my advise :).

    ~Grauw

  • Sébastien Guillon
    April 21st, 2006 at 3:02

    Talk about error handling : “and builds some DOM nodes out of it which are than inserted at the requested location”

    You have no idea how hard it was for me (not a native English speaker, I’m French) to understand you actually meant “then” not “than”.

    Other than that, I have no opinion on the subject (I don’t do enough JS). I do wonder though if all UAs really behave in the same way when fed invalid markup with innerHTML. I would assume not, so you then rely on specific error handling. Shouldn’t the hypothetical standardized innerHTML clarify that?

  • Lachlan Hunt
    April 21st, 2006 at 3:35

    I agree with Laurens and Sjoerd that working with strings of markup to manipulate the DOM isn’t very good practice. However, innerHTML isn’t as bad as document.write() is because of the way document.write() inserts code into the file stream during parsing.

  • Eric Shepherd
    April 21st, 2006 at 4:29

    I’m going to agree that it should be standardized, because it’s just a farce that every browser will have to support it eventually (even with application/xml eventually).

    But, I love beautiful code, and innerHTML is just ugly. I’d much rather write a few more lines of code than write strings of HTML with escaping.

    Dan Webb’s DOM Builder is interesting; it saves a few lines of code and makes construction of DOM elements easier but still does it programmatically.

    HTML is HTML, script is script. I don’t like combining them if it’s not absolutely necessary.

    My mind might change if I ever worked on something huge where DOM methods caused a gigantic performance hit that innerHTML fixed…

  • Tommy Olsson
    April 21st, 2006 at 7:19

    It’s not innerHTML that is the problem, but constructing HTML with string operations is.

    Hear, hear!

  • Robert Nyman - author
    April 21st, 2006 at 9:35

    Thanks for your comments.

    Sjoerd,

    It’s not innerHTML that is the problem, but constructing HTML with string operations is.

    It depends from what point of view you’re looking at it. If it’s from an aesthetic angle, it won’t affect the end result.

    Then, naturally, I don’t propose page after page with concatenating strings, when updating content dynamically it’s often only small parts of code that’s inserted.

    When it comes to AJAX solutions, it’s not about putting HTML string together in the JavaScript but rather to make a call to a certain URL that will return dynamic content transformed into HTML based on the parameters that were sent in.

    Compare that to, for instance, returning XML and doing XSLT transformations on the client, which has much more inconsistent and less support in web browsers.

    Laurens,

    Because people tend to forget to escape the < and & characters properly, which will then turn up as bugs

    Which is the same for unescaped ampersands and > characters directly in the HTML code, so the point is moot. The code has to, naturally, be good code no matter in what layer you write it.

    Sébastien,

    Sorry about that, the typo has been fixed.

    Lachlan,

    Yes, those two are very different things.

    Eric,

    I’m going to agree that it should be standardized, because it’s just a farce that every browser will have to support it eventually (even with application/xml eventually).

    Yes, that’s the whole point. If it’s a de facto standard, it should become a real standard.

  • Anne van Kesteren
    April 21st, 2006 at 10:05

    If it becomes a real standard you can be pretty sure the differences in implementations will be sorted out as well so that it becomes more reliable, even for “AJAX frameworks” and the like.

  • Sjoerd Visscher
    April 21st, 2006 at 11:01

    Right, if you generate HTML in a clean way and then use innerHTML to put it somewhere that’s perfectly fine of course.

    Which is the same for unescaped ampersands and > characters directly in the HTML code, so the point is moot.

    No it is not. If you type literal HTML, you see the < and & characters right in front of you, and it doesn’t look right. But s = "<input value='" + data + "'>"; looks fine.

  • Robert Nyman - author
    April 21st, 2006 at 11:25

    Sjoerd,

    Maybe I’m missing something here…

    What I meant was that if you write this in the HTML:

    <input value="Sjoerd">

    or this in the JavaScript:

    strHTML = "<input value='Sjoerd'>;

    it will generate the same HTML in the DOM. Or did you mean that the variable data in your example might contain invalid/unescaped characters?

  • Jeroen Mulder
    April 21st, 2006 at 15:31

    Being relatively inexperienced with the whole Javascript and DOM deal, I do dislike the idea of constructing HTML using all those DOM methods. Fact remains that innerHTML for people like me is much easier. Another good argument you bring forward is flexibility.

    In essence, there doesn’t seem to be a real argument against the use innerHTML except the lack of standardisation. Just because it allows for developers to make errors in the content they would use in conjunction doesn’t mean innerHTML itself is flawed — perhaps the developers are?

    Over the next couple of months I’ll be exploring this a lot more. Until this article and previously Jonathan Snook’s I wasn’t even considering innerHTML to be an option. Thanks :-)

  • Tanny O’Haley
    April 21st, 2006 at 20:45

    When I modified Lea Smart’s calendar popup, I changed it to use DOM methods to add the containing div at the top of the body since her original code used document.write to put it in the head element. However for the generated calendar, I used innerHTML because according to PPK’s benchmark tests it is faster for large amounts of HTML.

    I agree with Robert:

    The code has to, naturally, be good code no matter in what layer you write it.

    And of course, as I learn more, hopefully my code will get better.

  • Sjoerd Visscher
    April 21st, 2006 at 23:25

    Or did you mean that the variable data in your example might contain invalid/unescaped characters?

    Yes, but you can’t see it. It doesn’t matter how good you can program, somewhere, someday, you’ll forget to escape it, I promise! And not only do you need to escape < and & but also the single quote.

  • Robert Nyman - author
    April 22nd, 2006 at 0:17

    Jeroen, Tanny,

    I’m glad that you agree.

    Sjoerd,

    Yes, absolutely. But then again, that could happen in any layer. One of the customer’s web developers might add something invalid in the HTML code, the server-side language might one day suddenly generate something you never expected, or me myself could just plain miss something and produce an error.

    There’s never any way to be a 100% sure. I don’t think innerHTML is to blame for human behavior in general, though. :-)

    But, do I think that errors might occurr more often in scenarios like your example, as compared to regular HTML code. Yes, maybe. But to me personally that isn’t a reason to refrain from using innerHTML, but rather always be aware of the risks no matter what approach you choose.

  • Laurens Holst
    April 22nd, 2006 at 0:19

    Indeed :).

  • Aristotle Pagaltzis
    April 23rd, 2006 at 11:33

    DOM blows, any way you turn it. It’s clumsy and extremely verbose. Only things like DOM Builder make it tolerable. However, innerHTML blows far worse for exposing you to the vagaries of multiple layers and dealing with escaping.

    So you have a situation where there’s a pragmatic but bug-prone API, and a precise but indescribably painful one.

    The answer is clear: we need cross-browser E4X and we need it now.

  • Robert Nyman - author
    April 23rd, 2006 at 21:44

    Aristotle,

    So you have a situation where there’s a pragmatic but bug-prone API, and a precise but indescribably painful one.

    I think that sums it up pretty well. But between those two, I’d go for the pragmatic one, given the current situation.

    Not sure if E4X is the solution to all, but it definitely sounds like an interesting option!

  • Asbjørn Ulsberg
    April 27th, 2006 at 0:11

    Standardising innerHTML is a Good Thing. No doubt. It’s a de facto standard and we’re all better off with it being a real standard. Let’s just hope we can get it better specified, perhaps with some error handling (when the document is in standard mode and invalid markup is inserted, an exception could occur for example) and maybe even a better name (innerMarkup and outerMarkup would be nice).

  • Robert Nyman - author
    April 27th, 2006 at 10:33

    Asbjørn,

    I’m happy to hear that you share our opinions!

  • stocknsurf
    August 29th, 2006 at 12:05

    Hi I am facing a problem with innerhtml in firefox.

    Basically this is the issue:

    I have a divid content which is changed dynamically using innerHTML. This divid is inside a form and as a part of the dynamic content I am adding new form fields dynamically using innerHTML (based on user actions).

    But the problem is when the form is submitted from firefox, these new form fields don’t get passed on to the server side at all. Only the static fields that already existed get passed on.

    This is the problem I face only with firefox. On IE the new form fields added using innerHTML gets passed on to the server side successfully.

    I am splitting my hair over this problem with firefox. Has anyone faced the same issue? How do I solve this?

    Thanks

  • Robert Nyman - author
    August 29th, 2006 at 12:11

    stocknsurf,

    I haven’t encountered this myself, but my guess is that Firefox looks at form fields in a different way. This might be a scenario where you will have to resort to DOM methods like createElement, appendChild etc to make it work.

    Good luck!

  • Tref
    October 3rd, 2006 at 7:58

    stocknsurf, I’ve just had to debug a similar scenario so in case you haven’t located the answer here’s what I found out.

    Firefox may not accept your AJAX imported form elements if the opening and closing form tags are not nested correctly.

    For example we had a page that had the following structure.

    < body>

    < form name="form1" method="post" action="gohere.jsp" >

    < div id="page">

    < div id="main" >

    ... main content with form elements went here..

    ... some dynamic form elements were inserted using AJAX calls

    </div >

    </form >

    </div >
    </body >

    We were inserting some form fields into the form via an AJAX call but in firefox they were not showing up. We could access them by document.getElementById but document.form1.foo was coming up “undefined”

    The answer was in the nesting of the form fields. The opening tag was between the “page” and “main” divs, whereas the closing tag was after the closing “page” div.

    Hope that helps your situation

    cheers

  • Tref
    October 3rd, 2006 at 8:01

    Forgive me.. my explanation was back to front.. should read

    The answer was in the nesting of the form fields. The opening form tag was above the “page”, whereas the closing tag was between the closing of the “main” and the “page” div.

  • Robert Nyman - author
    October 3rd, 2006 at 8:38

    Tref,

    Thanks for the info.

  • jp
    October 16th, 2006 at 17:47

    Thank you so much tref, that was the problem for me too. I thought it would never be solved…

  • zhenya
    October 30th, 2006 at 17:51

    Tref, I also want to thank you. I’ve spent 4 hours today trying to solve same problem and after I read your message I only had to make cut-past and it worked!

  • Jiv
    November 15th, 2006 at 17:51

    In past, I found a way to get rid of the gap IE was putting at the top of the page (equiv. to a ) when inserting the form element like this

    ...


    But if you have a look in the DOM source of Firefox you’ll see that weird result


    This can be a possible cause why your variables doesn’t get posted!

  • Cedric Colpaert
    February 28th, 2007 at 18:11

    I had the same problem with the form elements inside innerhtml.. I’ve spend hours and hours on this.. and there’s only one website (this one) where you can find the solution

  • Robert Nyman - author
    February 28th, 2007 at 19:52

    Cedric,

    Glad you found the solution here! :-)

  • Thanh Le Quoc
    March 23rd, 2007 at 4:53

    Thanks so much…

    I also have faced with this problem.

  • e
    August 11th, 2007 at 17:26

    In regards to problems with inserting form elements with innerHTML in FireFox, is there some other reading I should find on this site? I ask because it seems that Cedric may have found something more.

    I’m facing a problem very similar to stocknsurf. I’m not quite sure if it’s related to nesting of form tags because there aren’t any div layers used on this page. Could the way the form is nested inside of tables cause the same problem?

    Everything works fine in FireFox until innerHTML is used to update a select field inside the form. Even when the update doesn’t cause any changes to the select field (just re-draws it), FireFox stops recognizing the select field. It’s as if the select field no longer exists.

  • e
    August 11th, 2007 at 17:31

    Also… I’m using a span section around the select field to update it. I’m just giving the span an id and then grabbing onto that with innerHTML.

    All of this works fine in IE, just not FireFox.

    Thanks again.

  • Charlie Cheng
    November 21st, 2007 at 6:28

    Great article, in firefox, Although, i didn’t mess up the tags. But the following may cause the same problem

    <table>
    <form …>
    ….form field mixed with for layout purpose
    </form>
    </table>

    Move to the following format will make the thing work

    <form …>
    <table>
    ….form field mixed with for layout purpose
    </table>
    </form>

    Thanks for reminding although i don’t exactly problem as you guys. But it does shorten my debugging time.

    Charlie

Share your thoughts:

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> . If you want to display code examples, please remember to write &lt; for < and &gt; for >.

Comment preview

All the proceeds from ad clicks will go to charity. However, if you like to give something directly to charity yourself, I recommend choosing from the listed ones below.

  • Save the Children
  • Red Cross
  • Cancer Research UK
  • WWF

Top results