Tag: css

  • Fixed footer auto height content

    While redesigning one of my pet projects – Simplememos – I came across a very pesky issue on layouts. I wanted a simple header/content/footer layout, with some specific behaviors. Header is part of content, content is using up 100% of whatever area is left after positioning footer fixed at bottom. Sounds easy? Well, what if the content has nothing inside? Yes, all of my content inside was absolutely positioned ‘notes’ that meant content had nothing by which it can auto-size itself! I also needed to have proper visual layout for all screen sizes, handle browser resize, maximize, restore for ALL browsers.

    The simple answer, yes I have that layout. Take a look at Simplememos, and feel free to play around in any browser of your choice.

    From what I experienced, played around, researched, and figured out eventually was that there is no CSS way of doing this. My own philosophy is to write less, and let CSS handle the details of my layouts as I have specified. But as many seasoned web players know, browsers come with all variations of CSS interpretations, and then you see all those threads on stack overflow around layouts, you’ll definitely have some fix, but then again it won’t work for your specific case if you had like the one I had.

    I can’t say stack overflow wasn’t of any help. In fact, I gathered many useful points from across a variety of stack overflow posts, replies, code snippets, and eventually I came up with a version that works for my own needs.

    My implementation was quite simple, but is a mix of CSS and JS. I couldn’t avoid JS, unless I go with CSS expressions which in a nutshell is JS to me.

    I created 2 regions as below-
    <div id="content">... my header, content inside ...</div>
    <div id="non-content">... my footer here ...</div>

    My div#non-content auto expands to my footer, since footer is a text. However, my div#content has only absolutely positioned divs, so it has no auto-expand criteria as such. Thus, I jig up jQuery’s document.ready event to dynamically resize div#content

    $(document).ready(
    div#content's height= (browser window's height - div#non-content's height)
    )

    And I also hook the window’s resize event to do the same dynamic height change again.
    $(window).resize(
    // Same code to dynamically resize div#content to occupy 100% of remaining available width
    div#content's height= (browser window's height - div#non-content's height)
    )

    There are some additional things I could have done
    1. Include a spacer image img#spacer-height that is hidden but dynamically resized to occupy maximum available height, and another image img#spacer-width to occupy maximum available width. I have used this for IE6 and below one time to handle overflow:auto for div#content. Without any content, setting width, and height is OK, but IE6 never bothers to show up any scrollbars.
    $('.spacer-width').width= window's width
    $('.spacer-height').height= (window's height - div#non-content's height)

    2. Use tables! This would have been the best option, but sadly FF does not support overflow:auto’s in table cells. As alternatives I didn’t bother to emded div’s, because I had already got to the point where I am having tables, divs, CSS, and JS to resize the div anyways.

    You can see my source in action on my own Simplememos site. If you have pure CSS alternatives, I’ll be more than happy to hear!

    Aside from the above, I must say the experience of using Knockout JS, custom KO bindings, jQuery, and extending jQuery selectors was a rewarding experience. I have these, and quite a number of stack overflow posts open for quite a few months now.

  • Setting tabindex in HTML for arbitrary, disparate elements

    I hit upon a picky need by a user to have specific tab-order for a HTML page. For most part we usually would organize the layout itself to allow for default left to right, top to bottom tabbing of elements. Or we could always explicitly set tabindex to specific order.

    Trouble was, having limited capability to influence the HTML generated by the package, the only option was do some post UI alteration using JS, or CSS only. Not surprisingly, CSS is about formatting, not navigation hence there isn’t any CSS property for tabindexes. The only option in hand was JS, so I was playing with a couple of approaches to look at the problem

    • Request user to live with the default tab order – Not an option 🙂
    • Use CSS – Not possible to set navigational properties such as tabindex
    • Use JS
    • Hack onfocus, onblur to attach/de-attach custom tabindex – didn’t work for set of controls, since one can enter any control using mouse, still custom tab order needs to be maintained. Another issue was controls appearing after custom tabindexed controls didn’t get any focus any more.
    • Use onkeyup, onkeydown events, detect TAB – didn’t work because onkeydown, onblur occurred on element having focus, then onfocus, keyup occurred on element receiving focus. While logically correct, my sample code quickly became a mess of booleans tracking keyup and tab key, then clearing it onfocus, but again similar to previous issue this didn’t work either.
    • From a completely different perspective, surround required elements in containers, like div, span or fieldset. This would automatically take care of tab order, but trouble is the elements I had to work on were in table row cells, and HTML doesn’t allow interleaving of containers (which is logical).
    • Had to work simply across all browsers without differences in implementation. I came across some posts suggesting setting required tab order through java script for all known elements. Another post improved this thought by suggesting to have tabindexes with incremental gaps say 10, so that additional elements could be put in tabindex later on.
    • So my final working approach took both of the above, and mistakes in approach to come up with a very simple solution as below
      <script type="text/javascript" language="javascript" src="prototype-1.7.min.js"></script>
      <script type="text/javascript" language="javascript">
      //<![CDATA[<!--
      // Requires prototype.js
      document.observe("dom:loaded", function() {
      /* Specify elements in order of required tab index, cte= custom tab elements */
      var cte= $('select7', 'select9', 'select10', 'searchkb', 'select8');
      /*
      * Logic to set custom tabindexes for elements
      * First set tabindexes for all known input-able elements in with gaps in between
      * For required elements, set tabindex in that gap range
      */
      var idx= parseInt(1000), incr= parseInt(10); // Begin with any suitable base number, idx= index, incr= suitable increment gap to allow assigning tabindexes in sequence
      $$('input', 'select', 'option', 'textarea').each(function(el) { try { el.writeAttribute('tabindex', idx+=10); } catch(err) { void(0); } });
      var fi= parseInt(cte[0].readAttribute('tabindex')); // fi= tabindex of first element
      cte.each(function (el) { el.writeAttribute('tabindex', fi+=1); }); // Rest of the elements receive sequential tabindex
      });
      //-->]]>
      </script>

    I was leaning on using jQuery’s attr to write tabindex, but for some reason (I know that’s not an excuse) it didn’t work. Perhaps it should, however prototype’s writeAttribute, readAttribute worked, so I ended up using that. Also note that not all elements support tabindex,  though I’ve limited to input-able elements, so setting this throws error which I’ve deftly gobbled up; not a good practice but if someone knows an elegant way to find if element supports some property that would be great. On other hand, I would prefer jQuery, or prototype hiding such intricacies behind their APIs instead of me having to do it since it’s javascript anyways. The try, catch could be altogether removed though.

    BTW, I used YUI’s excellent javascript compressor to minify prototype’s javascript. Google’s CDN didn’t provide a minified prototype.js, I wonder why …?

    I believe my goal of having a simple, yet elegant way to override tabindex, taborder especially if you have no control over HTML was achieved. Perhaps this helps you in some way as well.