{"id":8167,"date":"2010-12-21T12:30:06","date_gmt":"2010-12-21T19:30:06","guid":{"rendered":"http:\/\/css-tricks.com\/?p=8167"},"modified":"2014-01-28T14:11:18","modified_gmt":"2014-01-28T21:11:18","slug":"more-sidebar","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/more-sidebar\/","title":{"rendered":"Load More Sidebar Content When There Is Room"},"content":{"rendered":"

One classic layout conundrum is how much stuff<\/em> to put in a sidebar. Ideally the height of the main content area and the sidebar are about the same, to avoid either area having a large blank area which can be strange looking and a waste of good web real estate. Go light on sidebar content and short content pages may be just about right but long content pages have a lot of unused sidebar space. Go heavy on sidebar content and those long content pages are looking good but short content pages are pushed down awkwardly far.<\/p>\n

One solution is to pick some kind of happy medium and just roll with it. Another is to get technical and dynamically load the appropriate amount of sidebar content to fit the space available. Let’s look at how you might do that.<\/p>\n

<\/p>\n

\n\"\"
Classic problem.<\/figcaption><\/figure>\n
\n\"\"
Possible solution.<\/figcaption><\/figure>\n

Testing Heights<\/h3>\n

We literally need to measure the height of content here, so that’s JavaScript territory. I’ll be using jQuery. So let’s say we have:<\/p>\n

<section id=\"main-content\">\r\n<\/section>\r\n\r\n<aside>\r\n<\/aside><\/code><\/pre>\n

First we’ll “cache” those elements so we don’t need to select them more than once. <\/p>\n

var \r\n   mainContent = $(\"#main-content\"), \r\n   aside       = $(\"aside\");<\/code><\/pre>\n

We are going to need to repeatedly test the height of the aside<\/code> (sidebar) so we don’t need to cache that height, but let’s make a variable for the height of the main content area which will not be changing. <\/p>\n

var height = mainContent.outerHeight();<\/code><\/pre>\n

Now we’ll run a little test and and see if the sidebar has any room for more content or not (in otherwords, has a lower height value than the main content area):<\/p>\n

if (height > aside.outerHeight()) {\r\n  \/\/ load in more sidebar content\r\n}<\/code><\/pre>\n

Loading in the modules<\/h3>\n

Using a JavaScript library like jQuery makes Ajax loading of content pretty easy. If you hade a file called sidebarmodule.php<\/code> which contained the markup for an additional piece of sidebar material, you could load it in like this:<\/p>\n

$.get(\"sidebarmodule.php\", function(data) {\r\n\t\r\n  \/\/ Create sidebar box\r\n  $(\"<div \/>\", {\t\r\n    \"class\"  : \"sidebar-box\",\r\n    \"html\"   : data\r\n\t\t\r\n  \/\/ Fade in new module\r\n  }).hide().appendTo(aside).fadeIn();\r\n\t\t\r\n});<\/code><\/pre>\n

But that only handles a single module. I like the idea of having a bunch of modules ready to be inserted as needed, and also keeping them contained within one file for simplification. So let’s make the sidebarmodule.php smarter and be able to return the correct module based on a GET parameter. <\/p>\n

<?php \r\n\r\n  $module = $_GET['module'];\r\n\r\n  if ($module > 3) { echo \"No more modules\"; return; }\r\n\t\r\n  echo \"<h3>Sidebar Box #$module<\/h3>\";\r\n\t\r\n  switch($module) {\r\n\t\r\n    case 1: ?>\r\n      <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.<\/p>\r\n    <?php break;\r\n\t\t\t\r\n    case 2: ?>\r\n      <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.<\/p>\r\n\t\t\t<?php break;\r\n\r\n    case 3: ?>\r\n      <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.<\/p>\r\n\t\t\t<?php break;\r\n\r\n    default:\r\n      \/\/ Shouldn't ever get here, but just in case output some kind of error\r\n      echo \"<p class='error'>No more modules<\/p>\";\r\n  }\r\n?><\/code><\/pre>\n

Now we’ll pass that integer parameter along when we make the Ajax request to specify which one we’d like returned. Notice how we’ve only created three modules as well? Let’s make sure that we don’t do anything if we get back a response that there isn’t any more modules left:<\/p>\n

var module = 1;\r\n\r\n$.get(\"sidebarmodule.php\", { \"module\": module }, function(data) {\r\n  \r\n  if (data != \"No more modules\") {\r\n    \r\n    module++;\r\n\r\n    \/\/ appending and whatnot\r\n\r\n  }\r\n\r\n});<\/code><\/pre>\n

A few cleanups to do<\/h3>\n

We’re going to need to recursively do this Ajax request for more modules when we run a test and verify there is room for more modules. So what we’ll do is abstract it into a function, then call that function again if need be. We also need to ensure that the recursion stops if we’ve run out of modules, so we’ll set up a done<\/code> variable that is a stopper if we get the “No more modules” response from the script. <\/p>\n

Lastly, we’ll set up a buffer variable for the height. If the sidebar is only shorter than the main content by like 3 pixels, we really don’t need another whole module, so we’ll set this buffer to like 80 pixels so another module isn’t loaded unless the sidebar is shorter by at least that.<\/p>\n

Here is the whole shebang:<\/p>\n

var mainContent = $(\"#main-content\"),         \/* \"Caching\" *\/\r\n    height      = mainContent.outerHeight(),\r\n    aside       = $(\"aside\"),\r\n    module      = 1,                           \/* Start with the first, increments *\/\r\n    buffer      = 80,                          \/* To prevent sidebar from growing way taller than main content if it's only barely shorter *\/\r\n    done        = false;                       \/* If no more modules to be had *\/ \r\n       \r\nfunction getMoreContent() {\r\n\t\t\r\n  $.get(\"sidebarmodule.php\", { \"module\": module }, function(data) {\r\n\t\t\r\n    if (data != \"No more modules\") {\r\n\t\t\r\n      \/\/ Increment # so next time it will grab a differnet module\r\n      module++;\r\n\t\t\r\n      \/\/ Create sidebar box\r\n      $(\"<div \/>\", {\r\n\t\t\t\r\n        \"class\"  : \"sidebar-box\",\r\n        \"id\"     : \"sidebar-box-\" + module,\r\n        \"html\"   : data,\r\n        \"css\"    : {\r\n          \"position\": \"relative\",\r\n          \"left\": 25\r\n        }\r\n\t\t\t\r\n      \/\/ Fancy revealing of new content\r\n      }).hide().appendTo(aside).fadeIn(200, function() {\r\n        $(this).animate({\r\n          \"left\": 0\r\n        });\r\n      });\r\n\t\t\t\r\n      \/\/ If after getting new module, sidebar is still too short, start over\t\t\t\t\t\r\n      if ((height > (aside.outerHeight() + buffer)) && !done) {\r\n        getMoreContent();\r\n      }\r\n\t\t\r\n    }\r\n\t\r\n  });\r\n\r\n}\r\n\r\n\/\/ Initial test\t\t\t\r\nif (height > (aside.outerHeight() + buffer)) {\r\n  getMoreContent();\r\n}<\/code><\/pre>\n

Notes on Usage<\/h3>\n

I’m not yet using this idea on this site, but I’m going to think about it, as it’s a pretty good example of a site that could benefit from it. One of the considerations is content that requires JavaScript in it, for example the Poll on this site. It’s still certainly possible to use, it just needs to be made sure that JavaScript events are bound to the incoming elements and thus requires a little more tinkering and thought.<\/p>\n

SEO experts may also want to weigh in here. I have no idea the implications of this. Does Google (or other search bots) see this dynamically added content? I would think not, but sidebar content is likely not important for that anyway, and may in fact be good that Google doesn’t see it (higher percentage of content on the page related to actual topic of page).<\/p>\n

Demo & Download<\/h3>\n

Note there is some PHP at play here, so don’t expect to download this to your desktop and have it work, it’s gotta be somewhere the PHP can actually run.<\/p>\n

View Demo<\/a>   Download Files<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"

One classic layout conundrum is how much stuff to put in a sidebar. Ideally the height of the main content area and the sidebar are about the same, to avoid either area having a large blank area which can be strange looking and a waste of good web real estate. Go light on sidebar content […]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[4],"tags":[],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":325921,"url":"https:\/\/css-tricks.com\/a-dynamically-sized-sticky-sidebar-with-html-and-css\/","url_meta":{"origin":8167,"position":0},"title":"A Dynamically-Sized Sticky Sidebar with HTML and CSS","date":"November 20, 2020","format":false,"excerpt":"Creating page content that sticks to the viewport as you scroll, something like a jump-to-anchor menu or section headings, has never been easier. Throw a position: sticky into your CSS ruleset, set the directional offset (e.g. top: 0) and you\u2019re ready to impress your teammates with minimal effort. Check out\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/11\/sticky-sidebar.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":2451,"url":"https:\/\/css-tricks.com\/design-refresh\/","url_meta":{"origin":8167,"position":1},"title":"Design Refresh","date":"March 27, 2009","format":false,"excerpt":"It was time for another design refresh! The best part about this one, for me, was that all the work I did last time made this one very easy to do. As usual, it's not extremely drastic. Evolutionary, not revolutionary. The old one wasn't bad, I just felt playing and\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/csstricks-uploads\/mar2009design.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":316124,"url":"https:\/\/css-tricks.com\/refreshing-sidebar-for-2020\/","url_meta":{"origin":8167,"position":2},"title":"Refreshing Sidebar for 2020","date":"July 2, 2020","format":false,"excerpt":"The new design for Sidebar is lovely. I like how it goes even deeper with the sticky elements than the last design. But even more notably, Sacha Greif has been posting five links per day to Sidebar since 2012. That's a remarkable achievement.","rel":"","context":"In "Link"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/07\/sidebar-io.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":316417,"url":"https:\/\/css-tricks.com\/memorize-scroll-position-across-page-loads\/","url_meta":{"origin":8167,"position":3},"title":"Memorize Scroll Position Across Page Loads","date":"July 9, 2020","format":false,"excerpt":"Hakim El Hattab tweeted a really nice little UX enhancement for a static site that includes a scrollable sidebar of navigation. https:\/\/twitter.com\/hakimel\/status\/1262337065670316033 The trick is to throw the scroll position into localStorage right before the page is exited, and when loaded, grab that value and scroll to it. I'll retype\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/07\/localstorage-sidebar-scroll.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":3945,"url":"https:\/\/css-tricks.com\/design-refresh-version-5\/","url_meta":{"origin":8167,"position":4},"title":"Design Refresh (Version 5)","date":"September 8, 2009","format":false,"excerpt":"The new design has been rolled out. Nothing to shockingly different I hope, just a refresher. It's kind of hard to say, but I think this is the 5th significant iteration of the design at this point. The lines are fuzzy since the design evolves in between those iterations quite\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/csstricks-uploads\/oldv4.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":4855,"url":"https:\/\/css-tricks.com\/scrollfollow-sidebar\/","url_meta":{"origin":8167,"position":5},"title":"Scroll\/Follow Sidebar, Multiple Techniques","date":"November 30, 2009","format":false,"excerpt":"Really simple concept today folks! A sidebar that \"follows\" as you scroll down a page. There are a number of ways to go about it. We'll cover two: CSS and JavaScript (jQuery) with a bonus CSS trick. View Demo \u00a0 Download Files CSS The easiest way to handle this is\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/csstricks-uploads\/scrollingsidebar.png?resize=350%2C200","width":350,"height":200},"classes":[]}],"featured_media_src_url":null,"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/8167"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=8167"}],"version-history":[{"count":10,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/8167\/revisions"}],"predecessor-version":[{"id":161307,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/8167\/revisions\/161307"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=8167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=8167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=8167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}