Why inline CSS and JavaScript code is such a bad thing

When I review web sites, and also in my own projects with a number of different team members, I almost constantly stumble across something web developers should really refrain from: inline styling and inline JavaScript code.

What is inline style and inline JavaScript?

Let’s begin with explaining what I mean with having CSS and JavaScript inline: it is when you integrate your HTML code directly with either of them, resulting in having presentation and interaction code spread all throughout the page. Like this:

<div style="width: 800px; margin: 1em auto; font: bold 1em/1.2 Verdana, Arial, Helvetica, sans-serif">
    <div style="float: left; width: 400px; padding: 1em 2em; font-size: 0.9em">
        <span id="get-shit" onclick="callSomeFunction()">News</span>
    </div>
</div>

What is so bad with it?

Except for not being very pretty code, and hard to get a good overview of it, there are some real disadvantages to this:

HTML file size
Your HTML code will weigh more, i.e. a web page riddled with similar code will have a kb size that is a lot larger than necessary.
Lack of caching
HTML code will never be cached. Contrary to that, external dependencies, such as CSS and JavaScript files, will be cached by the visitor’s web browser after the first visit – this means that instead of loading a lot of superfluous HTML code for every page in your web site the visitor visits, it will quickly retrieve all style and interaction locally from the web browser cache.
Poor accessibility
When it comes to inline JavaScript code, such as in the above example, it’s applied to an element which doesn’t have any built-in fallback interaction handler (i.e., like a link takes you to the URL specified in its href attribute etc). This means that it won’t work when JavaScript, for one reason or the other, isn’t available.
Difficult code maintenance
When it comes to making changes to the code, I’m sure every web developer would agree on that having code in just one centralized location is a lot more preferable than changing exactly the same kind of code snippets spread all over the files in the web site. Maintaining similar code to the above for an entire web site would be hell.

Doesn’t everyone have JavaScript nowadays?

First: no they don’t. Second: some people purposely turn it off (for instance, the NoScript Firefox extension has had 31 million downloads to this date). Third, very often is not up to the end user, but external circumstances that they don’t control, which will, to some extent or another, lead to JavaScript being unavailable. These factors are:

  • Antivirus programs and firewalls being a bit too harsh in their JavaScript security judgement.
  • Company proxy servers filtering out code (for example, read An important lesson learned about AJAX and accessibility).
  • Other company internet access settings preventing proper JavaScript execution.

How you should develop

Any Interface Developer who’s fairly skilled knows that he/she should strive for a structure there the content (HTML code) is completely separated from the presentation code (CSS) and interaction code (JavaScript). What this means is that, naturally, you can’t cut the ties completely, but there should be no inline CSS or JavaScript code in your HTML.

The only acceptable dependencies are through id and class attributes for CSS and JavaScript hook-ins.

Taking the above bad example code, let’s rewrite it properly:


<link rel="stylesheet" href="css/base.css" type="text/css" media="screen">
<script type="text/javascript" src="js/base.js"></script>

<div id="container">
    <div id="navigation">
        <a id="get-news" href="news-proper-url">News</a>
    </div>
</div>


/*
    CSS code, in separate file (base.css)
*/
#container {
    width: 800px;
    margin: 1em auto:
    font: bold 1em/1.2 Verdana, Arial, Helvetica, sans-serif;
}

#navigation {
    float: left;
    width: 400px;
    padding: 1em 2em;
    font-size: 0.9em;
}

/*
    JavaScript code, in separate file (base.js)
*/
window.onload = function () {
    document.getElementById("get-news").onclick = function () {
        // Get news through AJAX
    };
}

A bit nicer, isn’t it?

When to use id and when to use class

Basically, it’s very simple. An id is unique for a web page, i.e. it should only appear once. The class attribute, on the other hand, can be in a document as many times as desired. My rule of thumb is that normally I use the id attribute for larger blocks in a web page, like site container, navigation, main content etc. Otherwise, I always use the class attribute.

When it comes to CSS code, connecting something to anything with that class in the HTML code is very simple. In regards to JavaScript and DOM access, however, native support for that doesn’t exist in all web browsers, Therefore I recommend the getElementsByClassName function, which also supports some other nifty features not available in any native web browser implementation.

Event handling in JavaScript

The code in the example is the old DOM Level 1 way of applying events to an element. It works fine for one event per element, but not if you have multiple events you want to apply, or the risk that someone else’s code will overwrite your event (or vice versa).

To avoid having to bother about event handling quirks between web browser implementations (and believe me, there are some), I recommend using a JavaScript library like DOMAssistant or jQuery instead.

But what about major players, like Google?

So, by now you have hopefully agreed with all my arguments and is ready to take a plunge into the brave new interface developing world. But, just out of curiosity, you take a look at the most popular web site in the world, Google, and think:

Wait just a minute now! Robert is having me on.

The start page, and especially the search results page, is filled with inline styling and JavaScript events. If they do it like that, it has to be the best way, right? Well, no. Google has some crazily talented JavaScript coders, as well as geniuses in other fields, but when it comes to HTML and CSS, they are actually somewhat infamous amongst talented Interface Developers.

In August a couple of years ago, my friend Roger rewrote the Google code with real proper code, and he goes more into detail explaining what he did in his post.

At the end, though, we need to consider the ridiculously high amount of visitors Google get every day, and for them it’s all about performance, performance, performance (for anyone interested in delving deeper into that, please read Improve your web site performance – tips & tricks to get a good YSlow rating). For them, cutting down any HTTP request is crucial, although that’s no excuse for not having valid code.

The most sensible option for Google would be to have one style block located at the top of their HTML code, and one JavaScript block located at the bottom of their HTML code (read more about why in Where to include JavaScript files in a document) and just have id and class attributes to connect that code to.

In the end, though, I really think that the benefit of having the code whatsoever anywhere in the HTML code is negligible, and besides, as soon as we’re talking about returning visitors (for instance, I visit Google each and every day), having external includes would be more beneficial and vastly better for performance as well as bandwidth usage. Also, in comparison, the Google Mobile page is in a much better state, so having the regular one being so poor does really have any valid motivation – I think it’s more of a left behind that hasn’t been seen to properly yet (they’re probably terrified of changing it).

Conclusion

Therefore, as stated above, make sure to include all your CSS and JavaScript code from external files. Start today! Move all inline code away from the HTML code, and you as well as your team and web site visitors will feel better right away. 🙂

63 Comments

  • A very nice writeup Robert.

    I will certainly be referencing this page, the next time I try to explain to colleagues the pitfalls of inline styles and inline javascript 🙂

  • I think another reason (though this is only a guess) for Google's old scholl HTML/CSS could be for the fact that they need to support some real old browsers.

    Another reason when using inline JS might be the best idea – heavy commercial sites with listen line/inline player pop-up buttoms at the head of the page (ie before the JS library is included). To stop quick clickers the best way around having the player open in the same window is to put the JS inline and unfortunately this was a critical bug to fix. (any other idea's how this might be done??).

    Nice article though and good to see performance issues discussed.

  • Mazza says:

    I second Morgan's comment. 🙂 Once again, another great article I will share with my co-workers.

  • Tim Shortt says:

    I agree wholeheartedly, and would also add another significant drawback to inline CSS. Using inline CSS eliminates the benefits of CSS specificity. When I see a lot of inline CSS (particularly during maintenance), it's a good indication that the developer doesn't understand specificity. Minimize the depth of your selectors during development, and use increased specificity when you need to override a style either for an exception case during initial development or later on during maintenance (rather than taking a jackhammer to the code with inline CSS).

  • Mike Budahn says:

    Would you want to create a separate JS file for code that would only ever be used on a single page?

    I suppose as long as its either in another file, or at the bottom of the page you still achieve separation of layout and interaction.

  • Robert Nyman says:

    Morgan,

    Thank you!

    Ross,

    Regarding old web browsers and Google: I think that web browsers supporting basic CSS formatting are so widespread right now (and have been for quite some time), and with a proper semantic HTML fallback, it would usable for virtually everyone.

    In the case quick clickers, I think that the best way is to include a small JavaScript block at the top being triggered as soon as the DOM (not window) has loaded to apply the proper event.

    That works most of the time, but if not, perhaps just wait till the DOM has loaded and then show such links with JavaScript when the necessary JavaScript functionality is present.

    Mazza,

    Thanks!

    Tim,

    Great point! Inline CSS severely decreases the potential of CSS specificity, and leads to <code>!important</code> scatter def ed all around since the developer doesn't understand the basics of applying CSS rule.

    Mike,

    If that user reloads the page just once, or revisits your web page before the cache has expired, you will get the same benefits as for code spread across your web site – i.e. lightning fast code retrieval from the cache instead of a superfluous HTTP request.

    Also, with that you will gain separation and better code maintenance as well, and perhaps in the future, that functionality will be available in more pages.

  • And thus this, and thus that, the eleventh command shall be that we, the cyber priests, shall forever controlleth all and command others, in what is right and what is not, or they shall surely burn in everlasting hell.

  • Robert Nyman says:

    Mikael,

    Eh… Not sure what you're getting at. If it isn't clear, this is about best practices, which will result in a better environment for you as a coder, for your employer getting a better value for their money, and last, but definitely not least:

    A better user experience for the end users.

  • Tino Zijdel says:

    > HTML code will never be cached

    This simply is untrue, although most dynamic sites will force no-cacheing headers for their HTML

    using window.onload is not the best advice either to hook behaviour since this fires only when *all* resources for the page have been loaded (including images etcetera) which often is a substantial delay – especially when a visitor has an 'empty cache'. You'd better eleborate on DOMContentLoaded, but I myself don't shy away from using inline javascript in the form of <script> -tags in the body to hook my behaviour as soon as possible (and hope that IE won't throw "operation aborted" on me)…

    I agree on inline styles though, but a small <style> -directive in the head saving an additional request is sometimes worthwhile.

  • Steven Clark says:

    Another benefit is that you can pass over the valid HTML to team members and not have to worry about someone going in and changing parts to fit their inline CSS and JS…

    So if they're working on external files you don't have the CSS guy falling over the HTML guy and the same with the JS guy – if they're separate.

    BTW nice post Robert.

  • […] Why inline CSS and JavaScript code is such a bad thing […]

  • Bruno Bichet says:

    Hi Robert,

    I’am a french webdevelopper and sometimes I translate the greatest posts I find on the web. I don’t know if your are skilled in french language, but you can find the translation here : http://www.css4design.com/blog/le-code-css-et-javascript-inline-saimal

  • Rani says:

    Hi

    Can you direct me to the place in W3C WAI where inline CSS is forbidden?

  • Robert Nyman says:

    Tino,

    Regarding HTML, let's say it was simplifying. Since most pages are very alive, so to speak, it's almost exclusively a deliberate choice not to cache the HTML (or if, then only for a short period of time).

    With <code>window.onload</code>, it's a starting point, especially in thinking. Then <code>DOMContentLoaded</code> is naturally the best way to go, but then I would have spent quite some writing on explaining which web browsers don't support, what's the workaround options etc. Basically, I just felt I would get a little too much off track, although such a solution is definitely the best one in the long run.

    And yeah, there are a few cases where it's vital that some events are applied as soon as the content is visible, and then a <code>script</code> block can be motivated.

    With inline style, very few are so small that it's even worth putting in the page itself. Rather, if you have several CSS files, concatenate them to one on the server, and serve a compressed and gzipped version of those, to make the request as efficient as possible.

    Steven,

    Absolutely, separation is key. And thanks. 🙂

    Bruno,

    Great, thanks!

    Rani,

    It is not forbidden, it's about best practices. Just as W3C: it's not about legislation, only recommendations.

  • I heard that valid google pages actually make the filesize smaller, even with a full DTD.

    We must remember that when the boys sitting in their little garage with donated and stolen computer parts wrote the main page for google, they weren't web designers. They'd never written any HTML in their lives, and so it is amazingly good markup for someone's first ever web page!

    Please note that I'm not citing any sources.

  • Ceriak says:

    Great post, Rob, we really do need these! I can hardly believe that in 2008 people just still can’t write well-designed, semantic markup (what am I talking about? They even unable to write a single _valid_ webpage – or just well-formed XML?). Keep up spreading the word!

  • Robert Nyman says:

    SneakyWho_am_i,

    He he. 🙂
    Yes, I personally think they could gain a lot from making pages more valid.

    Ceriak,

    Thank you!

  • Karoly says:

    So what if your website is an SSL website? Then it might be better keeping some js code inline, since nothing gets cached anyway. In that case, at least you can reduce the number of HTTP calls, no?

  • Robert Nyman says:

    Karoly,

    Interesting input! Having it inline in the same page can be an option then, but I'd still recommend CSS code and JavaScript code to be separated in their own blocks.

    Also, JavaScript events should still be applied in an unobtrusive fashion, i.e. not inline on the elements, but by using element id's or classes.

  • Mark Boas says:

    While I agree with your sentiments I don’t agree with the following para:

    Poor accessibility
    When it comes to inline JavaScript code, such as in the above example, it’s applied to an element which doesn’t have any built-in fallback interaction handler (i.e., like a link takes you to the URL specified in its href attribute etc). This means that it won’t work when JavaScript, for one reason or the other, isn’t available.

    Why can you not define an href for non JS users and make callSomeFunction() return false for the JS users? Returning false will ensure the href link isn’t followed through on.

    Cheers

    MarkB

  • Robert Nyman says:

    Mark,

    What I meant was that the event in the example code was used on a <code>span</code> element, i.e. an element that doesn't even have a native click handling functionality (like links and their <code>href</code> attribute).

    If it had been a link element instead, your suggestion would work just fine (although you would still like the code separation for overview, caching etc).

  • Jim says:

    "Doesn’t everyone have JavaScript nowadays?" Good question. GREAT question. A lot of people think that all automobiles now have electric starters. WRONG! There are many who still drive autos that use a hand crank. Thank you for bringing up this critical point. Those of us who want the Unabomber (he hates javascript – can't STAND it)to be able to access our sites will take your sage advice to heart!!

  • Robert Nyman says:

    Jim,

    In the article, I have explained just a few of the common scenarios where JavaScript isn't available for end users, and it is beyond their own control.

    If you're not interested in about being serious with your web development and cater to everyone, too bad.

  • Zafada says:

    I don't agree with you at all concerning inline css and javascript.

    Yeah, it may take a fraction of a second more to load a page, but are we really all that impatient? Another thing, does code need to be pretty?

    My code is ALWAYS rittled with secret numbers, words, etc inline. In fact, if anyone ever read my code they'd have no idea what is going on. I do though, and that's all that matters.

    One thing that pisses me off about programmers is that they all seem to have a 'better' way of doing things. This is where the mind seperates between ego and intelligence and ego is all that's left.

    Back to the code. My css is inline so I don't have to specify over a thousand unique classes for what is sometimes only one word.

    About caching. You can easily have your site load from the server every time rather than lapping up the cache. IE is one of the whores that usually always does this.

    File size. Each html file is over a thousand lines of code and is no more than 50kb.

    I will admit however that I have a simple site for people who use IE and get viruses every time they go to ANY site, and a version for firefox which is high resolution and heavy on bandwidth.

    The heavy version is total 1.7mb. Yes, that's alot for people who live in GA and still have to dial up but not for people like me who see no difference in google response and my response. And the heavy site is 1280 * 1024.

    The simple site isn't done so can't accurately be measured however it can accept any resolution and works in any browser mode. This one will no doubt be indexed by google but the other one is not so likely, which is fine. The heavy site is only for people that adore visual appearance and artistic effects.

    In other words, a site for people who are boring, and a site for people that are not. msnbc.com = boring, ninjai.com = not. That kinda thing.

    I guess my last words are this. Everyone has there own style of programming just like everyone has their own style of drawing. It's because of development teams of 100+ people that we all have to think alike. This is why I'm glad I don't work for anyone and make more money than if I did.

  • Robert Nyman says:

    Zafada,

    It's not just about personal preference, it's about respecting your end users and stop wasting their time as well – why use unnecessary bandwidth?

    When it comes to code being readable, most code in the world is handled by several developers, or handled over to other people – it's a developer's obligation to write good code.

  • Kevin says:

    I find this article and your "proper code" fundamentally lacking.

    First of all, worrying about time to load is pointless if you neglect issues like time to register "onclick" events. We have hundreds of events per page and that does indeed slow things down a bit as well. Also, you should not use "onclick=function" you should use addEventListener or equivalent for what is understood by each browser.

    Also, you complain about in-line scripts, and yet you inline and hardwired the language to English.

    Your mistake is you are looking at this completely from the wrong site, the side you "see" in the browser. But a lot more should be done before anything even reaches the browser in a visible form. That is, you should use what you do not see: a template system. I am sure this is what Google does. Then most issues you note as being a “problem” regarding in-line script go away and in fact are part of the solution. For example, try XSLT and XML to split content and context. You can use XSLT on the server or in the browser.

    Something like:

    &lt?xml version="1.0" encoding="UTF-8"?&gt

    &ltxsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform&quot; &gt

    &ltxsl:template match="/root"&gt

    &lthtml&gt

    &lthead&gt&lt/head&gt

    &ltbody bgcolor="#FFFFFF"&gt

    &ltdiv id="container"&gt

    &ltdiv id="navigation"&gt

    &ltxsl:apply-templates select="links" /&gt

    &lt/div&gt

    &lt/div&gt

    &lt/body&gt

    &lt/html&gt

    &lt/xsl:template&gt

    &ltxsl:template match="links"&gt

    &ltxsl:for-each select="link"&gt

    &lta&gt

    &ltxsl:for-each select="@*"&gt

    &ltxsl:attribute name="{name()}"&gt

    &ltxsl:value-of select="." /&gt

    &lt/xsl:attribute&gt

    &lt/xsl:for-each&gt

    &ltxsl:value-of select="caption" /&gt

    &lt/a&gt

    &lt/xsl:for-each&gt

    &lt/xsl:template&gt

    &lt/xsl:stylesheet&gt

    Then any of these XML will always work (be sure to send proper xml headers from your server), for three different languages with and without scripting included. And you never have to touch the display context XSL file above. This is much easier to maintain than your "solution" since your XML content, the only thing that should change, can be built on the fly:

    &lt?xml version="1.0" encoding="UTF-8"?&gt

    &lt?xml-stylesheet type="text/xsl" href="test_news.xsl"?&gt

    &ltroot&gt

    &ltlinks&gt

    &ltlink id="get-news" href="news-proper-url" onclick="clickme"&gt&ltcaption&gtSee&lt/caption&gt&lt/link&gt

    &lt/links&gt

    &lt/root&gt

    &lt?xml version="1.0" encoding="UTF-8"?&gt

    &lt?xml-stylesheet type="text/xsl" href="test_news.xsl"?&gt

    &ltroot&gt

    &ltlinks&gt

    &ltlink id="get-news" href="another-url"&gt&ltcaption&gtVu&lt/caption&gt&lt/link&gt

    &lt/links&gt

    &lt/root&gt

    &lt?xml version="1.0" encoding="UTF-8"?&gt

    &lt?xml-stylesheet type="text/xsl" href="test_news.xsl"?&gt

    &ltroot&gt

    &ltlinks&gt

    &ltlink id="get-news" href="another-href" onclick="another-clicker"&gt&ltcaption&gtSehen&lt/caption&gt&lt/link&gt

    &lt/links&gt

    &lt/root&gt

  • Kevin says:

    Take "2" with the formulas

    <?xml version="1.0" encoding="UTF-8"?>

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform&quot; >

    <xsl:template match="/root">

    <html>

    <head></head>

    <body bgcolor="#FFFFFF">

    <div id="container">

    <div id="navigation">

    <xsl:apply-templates select="links" />

    </div>

    </div>

    </body>

    </html>

    </xsl:template>

    <xsl:template match="links">

    <xsl:for-each select="link">

    <a>

    <xsl:for-each select="@*">

    <xsl:attribute name="{name()}">

    <xsl:value-of select="." />

    </xsl:attribute>

    </xsl:for-each>

    <xsl:value-of select="caption" />

    </xsl:for-each>

    </xsl:template>

    </xsl:stylesheet>

    <?xml version="1.0" encoding="UTF-8"?>

    <?xml-stylesheet type="text/xsl" href="test_news.xsl"?>

    <root>

    <links>

    <link id="get-news" href="news-proper-url" onclick="clickme"><caption>See</caption></link>

    </links>

    </root>

    <?xml version="1.0" encoding="UTF-8"?>

    <?xml-stylesheet type="text/xsl" href="test_news.xsl"?>

    <root>

    <links>

    <link id="get-news" href="another-url"><caption>Vu</caption></link>

    </links>

    </root>

    <?xml version="1.0" encoding="UTF-8"?>

    <?xml-stylesheet type="text/xsl" href="test_news.xsl"?>

    <root>

    <links>

    <link id="get-news" href="another-href" onclick="another-clicker"><caption>Sehen</caption></link>

    </links>

    </root>

  • Robert Nyman says:

    Kevin,

    How the content is generated – be it XSLT or any other technology – is irrelevant. What matters is what times time for the web browser to render, how content is cached locally between pages in a web site etc. That is how your end users will perceive the content and that is what really makes a difference.

    And if you have hundred of events, something isn't coded properly. Look into event delegation instead, which is really the only correct way of handling events.

  • Kevin says:

    Frist, if you use browser side XSL rendering browsers will cache XSL files, just like CSS. And after the first page loads, for Ecmascript enabled browsers, I can send tiny XML files via AJAX and render using the same stored XSL file. So there is a gain in performace.

    Second, you can also process the exact same XSL file on the server and send only formated HTML, so there need be no browser rendering and thus no performance hit on the client. My code is reuseable with two different methods of delivery.

    Third, hundreds of dom attached events, not "script events", because it is a spreadsheet program, with events per cell, and they are all delegated to about 5 main controlling functions.

    Finally, in your example you have the "id" value "get-news" hard coded twice, in two different files (html and script files). Using XSL I can reference this value once in a database and build my XML content on the fly. My context (what the user sees) XSL file does not even know or care about "id" attributes. Thus one of your arguments to keep changes to a central location is defeated: you have it in two places. I have it in one.

  • Robert Nyman says:

    Kevin,

    Browser-side XSLT? Seriously? It's not a nice thing, performance-wise, and especially not when it comes to inconsistencies between web browsers and their parsers/implementations.

    Hence why JSON has become so popular, for instance.

    And of course it's a performance hit if you need to re-download inline styles and scripts for every page you visit in a web site, as opposed to having it stored in the user's web browser cache. If you transform it into the desired HTML via XLST on the server doesn't really have anything to do with it.

    Then we have accessibility and SEO: you can't just depend on JavaScript and serving small portions (i.e. not complete pages) of code to everyone. For anyone with the capabilities, sure, that's called progressive enhancement, but you need to offer a version that works without that as well.

    Not sure if I misunderstand about events, but if that's the case, why attach hundreds of events to each cell? I guess/hope you only have five actual event handlers, and that you let the events bubble up to them.

    About a central location being "defeated": as with all code when it comes to CSS and JavaScript, naturally you have hooks for you or anyone else to interact with it; things that might also be exposed via an API, for Firefox extensions etc.

    I also think you misunderstand the central location idea: it's that ALL presentation code is in one single place and that ALL interaction code is in one single place.

    Conclusively: if you love XSLT and your spreadsheet application, great. But for building public web sites, there are a lot more factors to consider.

  • Robert Nyman says:

    Kevin,

    I’m happy for your sake that you have fallen in love with XSLT – most of the world have moved on to other approaches; nothing wrong with it, but I can’t really see why it would be the ultimate solution to any factor in good web development.

    Have you actually studied this or is this just a feeling you have?

    Since you mentioned YSlow, are you familiar with the performance work Yahoo have been doing? Have you read their recommendation Make JavaScript and CSS External (where anything inline really only could possibly apply to start pages of companies like Google, but given the reoccurring searches people do, not even there). What I write about in this blog post is common knowledge amongst web professionals all over the world.

    Have you ever read about Unobtrusive Javascript? That web site and material about that is by Christian Heilmann, one of the world’s leading authorities on web development, and high up within Yahoo.

    About YSlow grade on this web site: if you had actually taken the time to look what HTTP requests, CSS and scripts that are affected, none of it stems from this web site – it’s about code served from, amongst others, Google and Flickr, who have decided not to offer expire headers and minifying. And CDNs aren’t even applicable unless for very very high traffic web sites.

    According to Alexa, 99% of the world’s web sites are slower than robertnyman.com, which I would say is a pretty good indication of the performance of this web site.

    Overall, I like discussing these things, they’re far from black and white, but I feel that your tone and approach has been disrespectful from the get-go. Therefore, I agree that we end this now, it will definitely not make anyone of us happier.

  • Kevin says:

    I clearly said that XSL can be done both in a browser and on the server. Which means I can deliver XSL to browser that supports it, and HTML to browsers that don't. This talk about different parsers is not germane. And while browser detection is often unreliable, that is overall mitigated by writing lean and testing the XSL so it is compatible almost always, even if sent with a false positive, so it is still not germane. Even on slow connections. And our own web sites often do not have any scripts, exactly so they are available to almost everyone, including ADA compliance. So I know how to make sure sites work for everyone.

    Overall, I agree that user performance is important.

    However, the argument that HTML is the heavy part of downloading bandwidth with inline scripts is a tempest in a teapot. Have you actually studied this or is this just a feeling you have? Most of the bandwidth these days is in downloading script and css files, not in html content, even with inline scripts.

    I also just tested this page with YSlow. It got a "Grade B" including: Grade B Make fewer HTTP requests, Grade F on Use a Content Delivery Network. Grade C on Minify JavaScript and CSS. Seems like a lot of wasted bandwidth. How ironic.

    Your argument is also not even germane about caches. You can turn off caching in a browser. I have mine to clear the cache on shutdown. So cache reliance is not guaranteed. And I have to reload your scripts again anyway tomorrow. Thus, you have saved me little unless I browse your site extensively today. Maybe I am not "a normal user", but that is just the point, you can never encompass all user behaviors.

    I also find it a performance hit using the very scripts on this page showing me my "comments" as I type. As I type more and more there starts to be a lag between what I type (I am a very fast typist) on my keyboard and when it appears on the screen. I suppose you think it is smart to limit my bandwidth and not show me a "preview" page, but I find the developing lag very annoying. So I turned of scripts just to type here. Even more annoying there is not a "page preview" option for when I turn off scripts.

    And you missed my point about separation of content from context. It was about maintaining a single piece of code, one that does each task, in only one place, not two, as just good design. And no, mixing them the way you did is not needed. And exposed hooks should be generic in scripts, should be based on the type of element making the call, and else should not know or care any more about the context of that element. Hence one should never ever hard code an "id" value as a constant in a script. You only do so because of your desire to "save bandwidth" which really is a straw man leading you down a road of overall bad design.

    Anyway, I will leave this as we just disagree.

  • […] article est une « craduction »(1) de l’excellent article Why Inline CSS And JavaScript Code Is Such A Bad Thing dans lequel Robert Nyman explique pourquoi il est bon de sĂ©parer la structure HTML, la […]

  • […] article est une « craduction »(1) de l’excellent article Why Inline CSS And JavaScript Code Is Such A Bad Thing dans lequel Robert Nyman explique pourquoi il est bon de sĂ©parer la structure HTML, la […]

  • Sure says:

    HTML file size

    If you need it you need it … you still load the .js or .css file. Fail, size is the same

    Lack of caching

    LOL – there`s nothing more to say

    Poor accessibility

    "This means that it won’t work when JavaScript, for one reason or the other, isn’t available." – Javascript does not work when javascript is not available , good one, good and bright …. FAIL

    Difficult code maintenance

    "When it comes to making changes to the code, I’m sure every web developer would agree "… That you search for the element in the page. Who uses 800 html pages anymore ? Seriously if you have 10 pages that display a menu and you do not include that menu as a template you`re just plain stupid. You don`t have to change 50 pages, you only have to change the page in which your element is located. And again … FAIL.

    FYI ooCSS is the way to go – all margins widths heights sizes should be inline (why ? because your size if often based on some calculations and differs from browser to browser – hacks are stupid)

  • Robert Nyman says:

    Sure,

    Interesting to hear that you believe you are in the position to completely discard the results of some of the best performance specialists in the world, working for Google, yahoo! etc.

  • Sure says:

    What is even more interesting is that 99% of those that think inline is bad are designers. They read it somewhere and did not understand the difference of 0.001 of a milisecond. With my background in actual programming I am , I am in a position to say that

  • Robert Nyman says:

    Sure,

    All the members of the exceptional performance team at Yahoo! and Google are designers, thus not knowing technology? Yes, sounds very likely…

  • […] it in the following unobtrusive way, in an external javascript […]

  • […] code CSS et Javascript au milieu du HTML c’est pas bien ! — Traduction de l’article Why Inline CSS And JavaScript Code Is Such A Bad Thing de Robert […]

  • […] code CSS et Javascript au milieu du HTML c’est pas bien ! – Traduction de l’articleWhy Inline CSS And JavaScript Code Is Such A Bad Thing de Robert […]

  • Doug says:

    Bull. I worked with a person that created a Javascript file for every page. It was inline but wasn’t maintainable either! If you re-use it, yes, but if you are writing a simple 4 line function that is very particular for a a page there is NO reason to add it to a global library, and have a js file for every case of this is not very maintainable either.

    That’s just the start of my disagreement with this blog.

  • Robert Nyman says:

    Doug,

    You have very valid reasons in the blog post why it matters, so I’m not going to reiterate them here. I’m not saying if there is usage in only one page at one time that you have to have it. But in my experience, that one use case quickly grows to more pages and soon you have the same code scattered all over.

  • […] Why Inline CSS And JavaScript Code Is Such A Bad Thing There are many, many others. As always, it's best to search for them yourself. Knowing how to find information is just as if not more important than knowing the information. Be sure to read all pages linked in this post; they have further information that should prove useful. When asking for help, make sure you follow Eric Raymond's and Jon Skeet's guidelines for prompt, accurate responses. Please answer any questions I ask; they're not rhetorical (probably). Any posted code is intended as illustrative example, rather than a solution to your problem to be copied without alteration. Study it to learn how to write your own solution. Misson, not Mission. Reply With Quote + Reply to Thread « Previous Thread | Next Thread » […]

  • I really didn’t faced any problem of page lod with inline css and JS as you stated. However I am not certain enough whether its true or not.

  • […] as paragraph or list elements, then set the layout using only CSS in external style sheets (not inline). Be sure to read all pages linked in this post; they have further information that should […]

  • […] For javascript novices, even this function is a bit overwhelming.  More experienced javascript coders will look at it and say “eww, inline javascript.”  How aweful! […]

  • […] Javascript coders will look at it and say “Eww, inline Javascript.”  <a href=”http://robertnyman.com/2008/11/20/why-inline-css-and-javascript-code-is-such-a-bad-thing/“>How […]

  • Domina X says:

    Speed wins… therefore I opt-in for putting everything neatly in between the “head” tags. That spares 2 more requests and 2 more downloads. In the end, this adds up to 4 requests in total which I spare upon each visitor’s page-load.

    That quickly sums up to a few seconds that aren’t wasted, making the site-browsing experience fast and furious, instead of the usual “wait for the javascript files and css to load, things will look totally different in a few secs” annoyance.

    Anyway, I’ll step of my soapbox now. The article is cool. Keep things like that comming!

  • Robert Nyman says:

    Domina X,

    Speed does win, but an option could be to include the JavaScript files at the bottom of the page then.

  • […] code CSS et Javascript au milieu du HTML c’est pas bien ! – Traduction de l’articleWhy Inline CSS And JavaScript Code Is Such A Bad Thing de Robert […]

  • […] Inline scripting is bad. The first thing bothering me when I looked at my template was the heavy use of in-line javascript. As a rule of thumb content code (HTML), mark-up code (CSS) and interaction code should always be separated. It makes everything a lot more readable and maintainable, especially in the long run. […]

  • […] Difficult maintainability and lack of caching. […]

  • Boyko says:

    Hey, nice write-up. It helped me, thanks much!

  • […] Why inline (..) JavaScript is such a bad thing TL;DR Readability, Maintainability, Accessibility, Performance, Caching.. Viele GrĂĽĂźe, lotti __________________ Empfehlenswerte Links: RedBeanPHP | JavaScript Patterns | AngularJS (I've been doing it wrong) […]

  • […] (???????inline CSS,JavaScript?????????STYLE?SCRIPT??????????????????HTML???style?????CSS???????onclick??????JavaScript??????????Why inline CSS and JavaScript code is such a bad thing) […]

  • lux says:

    times changing 🙂 look at react

  • Ben W says:

    Are there any advantages to inline JS?

  • Jacob Koshy says:

    I came here with the dilemma of whether I should go for inline css or external because performance is my biggest concern too. I think It’s better to go with inline after having read this. Thanks for this post, Robert!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.