No iFrames! Dynamically Resize Divs with jQuery.

August 8, 2012

It's no secret that iframes are one of the most hated methods of web page layouts in the web development world — they are horrible for SEO, user experience and (usually) design. I was recently charged with creating a page that needed functionality similar to what iframes would normally provide, and I thought I'd share the non-iframe way I went about completing that project.

Before I get into the nitty-gritty of the project, I should probably unpack a few of the reasons why iframes are shunned. When a search engine indexes a page with iframes, each iframe is accurately recorded as a separate page — iframes embed the content of one we page inside of another, so it makes sense. Because each of those "pages" is represented in a single layout, if a user wanted to bookmark your site, they'd probably have a frustrating experience when they try to return to your site, only to find that they are sent directly to the content in one of the frames instead of seeing the entire layout. Most often, I see when when someone has a navigation bar in one frame and the main content in the other ... The user will bookmark the content frame, and when they return to the site, they have no way to navigate the pages. So what's a developer to do?

The project I was tasked with required the ability to resize only certain sections of a page, while asynchronously shrinking another section so that the entire page would always stay the same size, with only the two sections inside changing size.

Let's look at an example with two divs, side by side on a web page:

iFrame Tutorial

One div will contain a navigation menu to jump to different pages of the website (#sidebar), and the second div will contain all the content for that page (#content). If some of the elements in #sidebar are too long to read with the default width of the div, we want to let the user freely resize the two divs without changing the width of the page.

Our task is straightforward: When #sidebar expands in width, also expand the navigation and shrink #content along with the main content inside #content. If #sidebar shrinks, the navigation, #content and main content would respond accordingly as well:

iFrame Tutorial

It's a relatively easy concept to do with iFrames ... But then you remember that iframes are no longer cool (yes, there was a time long ago when iframes were cool). I decided to turn to my favorite alternative — jQuery — and the fix was actually a lot easier than I expected, and it worked beautifully. Let's run through a step-by-step tutorial.

1. HTML

Lay out your two divs:

<div id="sidebar"> 
<div class="sidebar-menu">
<!-- all your sidebar/navigational items go here -->
</div>
</div>
<div id="content">
<!-- all your main content goes here -->
</div>

2. CSS

Style your divs:

#sidebar {
       width: 49%;
}
#content {
width: 49%;
        float: left;
}

3. jQuery

Now that we have our two divs side by side, let's apply some jQuery magic. To do that, Let's include our jQuery files in the <HEAD> of our document:

<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>

Now that we have the necessary scripts, we can write our function:

<script type="text/javascript">
  $(document).ready(function() {
    $( "#sidebar" ).resizable({      
    });
    $("#sidebar ").bind("resize", function (event, ui) {
            var setWidth = $("#sidebar").width();
            $('#content).width(1224-setWidth);
            $('.menu).width(setWidth-6);
        });
  });
</script>

I know that might seem like an intimidating amount of information, so let's break it down:

   $( "#sidebar" ).resizable({      
   });

This portion simply makes the div with the ID of "sidebar" resizable (which accomplishes 33% of what we want it to do).

   $("#sidebar ").bind("resize", function (event, ui) {

By using the .bind, we are able to trigger other events when #sidebar is called.

            var setWidth = $("#sidebar").width();
            $('#content).width(1224-setWidth);

This is where the magic happens. We're grabbing the current width of #sidebar and subtracting it from the width you want your site to be. This code is what keeps your page stays the same width with only the divs changing sizes.

            $('.menu).width(setWidth-6);

This part of the code that expands the contents in the navigation along with #sidebar.

You can see a working example of iframe-like functionality with jQuery here: http://jqueryui.com/demos/resizable/

The only part you won't find there is the trick to adjust a corresponding div's size to make it grow/shrink with the first ... I had a heck of a time searching that on the web, so hopefully this quick tutorial will help other developers who might be searching for this kind of functionality!

- Cassandra

Comments

August 9th, 2012 at 11:06am

Great tip. Have bookmarked this reference where I can use Div tags. For a current project, I need to dynamically re-size an iframe from a supplier (their content has differing height). They only supply their widget in an iframe. What is the easiest way to do this without having to implement too much code on both ends?

August 10th, 2012 at 3:12pm

Hi Ian!

I have minimal experience with dynamic iframes, however I just wrote this up pretty quick and tested it. Hopefully this will help:

You can attach an ID to an iframe element just as you can with Divs, like so:

<iframe src="http://softlayer.com" id="iframewidget"> </iframe>

And then apply necessary dynamic resizing via JQuery:

var setHeight = document.body.scrollHeight; // this will get the height of the scrollable area of the browser
 
$('#iframewidget').height(setHeight);

Hope this helps!

November 14th, 2012 at 3:16pm

this tutorial is very helpfully thank you so much

April 7th, 2013 at 6:06pm

Hi Ian,

I would love to not use an iframe but I have a requirement to embed a pdf or tif into a html.
Is it possible to do it without using an iframe or object?

Kind Regards,
Shankar

August 30th, 2013 at 2:14am

I can't seem to get your code to work. For starters, the divs don't float and where is the element with the ".menu" class? Is this the complete code?

Leave a Reply

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • You can enable syntax highlighting of source code with the following tags: <pre>, <blockcode>, <bash>, <c>, <cpp>, <drupal5>, <drupal6>, <java>, <javascript>, <php>, <python>, <ruby>. The supported tag styles are: <foo>, [foo].
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Comments

August 9th, 2012 at 11:06am

Great tip. Have bookmarked this reference where I can use Div tags. For a current project, I need to dynamically re-size an iframe from a supplier (their content has differing height). They only supply their widget in an iframe. What is the easiest way to do this without having to implement too much code on both ends?

August 10th, 2012 at 3:12pm

Hi Ian!

I have minimal experience with dynamic iframes, however I just wrote this up pretty quick and tested it. Hopefully this will help:

You can attach an ID to an iframe element just as you can with Divs, like so:

<iframe src="http://softlayer.com" id="iframewidget"> </iframe>

And then apply necessary dynamic resizing via JQuery:

var setHeight = document.body.scrollHeight; // this will get the height of the scrollable area of the browser
 
$('#iframewidget').height(setHeight);

Hope this helps!

November 14th, 2012 at 3:16pm

this tutorial is very helpfully thank you so much

April 7th, 2013 at 6:06pm

Hi Ian,

I would love to not use an iframe but I have a requirement to embed a pdf or tif into a html.
Is it possible to do it without using an iframe or object?

Kind Regards,
Shankar

August 30th, 2013 at 2:14am

I can't seem to get your code to work. For starters, the divs don't float and where is the element with the ".menu" class? Is this the complete code?

Leave a Reply

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • You can enable syntax highlighting of source code with the following tags: <pre>, <blockcode>, <bash>, <c>, <cpp>, <drupal5>, <drupal6>, <java>, <javascript>, <php>, <python>, <ruby>. The supported tag styles are: <foo>, [foo].
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.