How do I implement external navbars in HTML5?
August 24, 2013 2:12 PM   Subscribe

For a website, I want to have one nav.html file and include it across the site to provide a write-once horizontal navbar at the top of each page. Is there a way of doing this without server-side stuff like PHP?

The site will be in HTML5 / CSS3 and JavaScript. No frames, no Flash.

It will be a bonus if it's possible for the nav to use things like drop-down menus, and to highlight what the current page is.

This is for a client who has asked me to have a look, but I am not an expert web developer (I have tried a few things like import or include, but I get cross-site warnings in Chrome or no working CSS). The client will do most of the maintenance and just doesn't want to involve PHP (although I understand it would be pretty easy to do). My Google-fu is failing, and I can't tell if it's because I am asking the wrong question or if it really is not possible.
posted by milkb0at to Computers & Internet (9 answers total) 4 users marked this as a favorite
I haven't tried it myself since all my sites are php but have you tried

<object name="nav" type="text/html" data="nav.html"></object>
posted by missmagenta at 2:26 PM on August 24, 2013 [1 favorite]

(oh and I think you might need to declare the nav css in nav.html for it to work and be styled)
posted by missmagenta at 2:33 PM on August 24, 2013

JavaScript can fetch it using AJAX and then insert it into the page.

If the site is served by Apache, and Server Side Includes are turned on, you can use them.
posted by jsturgill at 2:34 PM on August 24, 2013

There are a couple of ways you can do this with that toolset.

If you want a solution that works without Javascript, you can use an IFRAME tag to refer to an external navigation HTML page. This bends the rules about frames, but since it keeps the frame in the flow of the page, I think it'll work for what you're looking for and is IMHO the best option for what you're looking for as it minimizes the amount of code you'll need to repeat across all the pages that have this navigation. You'll need to style the IFRAME such that it's borderless if you don't want a frame to show around it, and you should probably add an overflow: none style to it so that it doesn't scroll. You'll also want to make sure that any links inside the HTML file inside the IFRAME have a target="_top" attribute, so that they open in the main window. Also make sure that your navigation page is served via HTTPS if your requesting page is also served by HTTPS, or you'll get mixed content warnings.

If you'd rather avoid IFRAMEs, you can also use Javascript to fetch a file containing the HTML snippet you want on the page using AJAX. Then you can just stuff the string containing HTML into a DOM element of your choosing using innerHTML. The main issue with the Javascript solution is that it's extremely likely that your navigation will appear to "pop in" after the page has loaded, whereas if you use IFRAMEs, the included HTML file should be cached and would appear almost instantly with the rest of the page.

Also, one note about using AJAX, the file you fetch *must* come from the same server that the requesting page is on, or it won't work due to the same-origin security policy browsers implement for XMLHTTPRequest. If that's a no-go, the IFRAME solution is the only thing I can think of that would work.
posted by Aleyn at 2:41 PM on August 24, 2013 [1 favorite]

I have tried "object" but that hasn't worked with CSS (although I could try putting the CSS into nav.html) or with fancier things like jQuery UI.

I think the client's main problem with PHP (and perhaps AJAX?) is that he doesn't want to have to rely on Apache. That way he can do an offline web app and keep everything local.

I didn't think people still used iframes, but that's worth a look, thanks.
posted by milkb0at at 2:57 PM on August 24, 2013

Adobe Dreamweaver can do this with its "Library" feature.
posted by Lanark at 3:12 PM on August 24, 2013

There are also tools for generating static websites.

The one I'm a little familiar with is Jekyll, which has some momentum, but there might be others more suited to your needs. It's a basic concept that you have one or more "layouts" that are instantiated with different contents. You can also do more sophisticated things, like pagination, CSS preprocessing, custom tags, sitemap generation, etc, etc. Jekyll is somewhat geared, at least by default, for a blog-like structure, but the tool is quite flexible.

With this setup, you don't need anything special on the server. However, it is a special tool with its own learning curve, and the generated code will simply copy your navbar to every page, so realistically, whoever maintains the site would need to know how to use the static site generator.

By the way, CSS should work fine in an OBJECT tag, but rules from the "parent" page won't be applied to the navbar. It can point out its own stylesheet though, just like any other page. The OBJECT is basically its own little browser frame.
posted by mbrock at 3:17 PM on August 24, 2013 [1 favorite]

The other issue with the AJAX strategy described above is that you need to have a webserver running. If the client really wants to be able to just open the files directly ("That way he can do an offline web app and keep everything local"), AJAX requests won't work against a file:/// protocol. I've had that one bite me in the past and it took me forever to figure out.
posted by heresiarch at 9:19 AM on August 25, 2013

jQuery will do AJAX client-side includes with zero hassles--the caveat being that it must come from a server.
Make sure you style the div 'yourdivname' with the appropriate CSS. (Absolute positioning, sizing, background graphics, whatever your thing is.) $(function(){}) is the startup function in jQuery. Anything between the brackets is run when the page finishes loading.

As heresiarch points out this will most certainly not work for local browsing, but for that there are things like HTML to JavaScript converters to generate functions you can run on startup:

fn_that_returns_my_compiled_html() = function() {
     return ('<b>Obviously the answer is Ghostbusters II</b>');

posted by ostranenie at 6:35 PM on August 26, 2013

« Older Cheating: Clueless girlfriend edition   |   Videos or Articles About Adult Opinions of... Newer »
This thread is closed to new comments.