Category Archives: HTML

Bootstrap and Affixed Nav for mobile.

Recently I have been working on a new website for my primary contract referrer, I decided to use Bootstrap 3.0 as my base and as an absolute necessity it should look nice on all platforms (even mobile). Note that I am part of this group that doesn’t believe that it should look the same on all browsers, platforms and screens, just that it looks nice.

My first issue was quite interesting as I found that my wonderful iPhone’s default browser doesn’t support position: fixed (See http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html for more detail on this). This means that my nice affix plugin using navbar only worked on normal browsers and not on my iPhone. This I decided was not an acceptable solution, so I started googling, then I googled some more and came up fairly blank. Yes there were a couple of bit’s and pieces here and there that hinted it could be done, but nothing that hit all the targets of: Bootstrap 3.0 Affix Navbar.
So cobbling together some other answers I came up with this: http://codepen.io/SimeonC/pen/lhGjC (or http://cdpn.io/lhGjC for without the code frames).

Once you’ve had a look at the example keep reading for the full breakdown.

Concept

The concept is a combination of the affix plugin as it works normally, and on mobile (in this case smaller screens) we work around the position: fixed by absolutely positioning the navbar at the top all the time. Now this isn’t a perfect solution – I just didn’t want to use more javascript than necessary. You will notice that in the mobile version we do not affix to top when it scrolls down – it is always pinned to the top. My reasoning for this is that though it’s fine for a desktop site to show the menu only later when you’ve scrolled down, as a usability point I find that if I’m using a mobile it’s not to look at the pretty pictures – hence the most important thing on a mobile is navigation around the site. We put our contact us button in the menu so it’s easy to see and click all the time.

Implementation

The demo has 2 main parts to it – the <header> and the <div id=”scroll-wrap”> parts. The HTML is basic, nothing fancy to see there we just place the header element then all our content inside the scroll-wrap element. In the CSS is where the fun starts. As you probably have heard – it’s a bad idea to try change how things are done via browser sniffing as IE 11 for one has started lying about what it is! So to embrace this I design my sites using modernizr and for size of screen rather than type of screen. On smaller screens – to target the iPhones in particular I use media queries to absolutely position the header and then the scroll-wrap for the remaining viewport area. We then use overflow: scroll to make this the scrollable area (Note the use of  -webkit-overflow-scrolling: touch this means the div scrolls nicely on my iPhone). Nice thing about this approach is that the menu stays “Fixed” at the top. If you are using this method do keep in mind that the screen is small – the bigger your fixed area the smaller the screen to read on I’d recommend not using up more than 10-15% of the screen height with fixed elements especially if you set user-scalable to no.

Last Words

Another thing I haven’t demoed here is using bootstraps scrollspy in this situation – a simple solution is to initialise it twice:  $(‘body’).scrollspy(); $(‘#scroll-wrap’).scrollspy();. Though not perfect it does get the effect to work as only one scroll event will fire depending on how the CSS has changed the scroll-wrap.

Admittedly this won’t suit everyone and for some if you are fine with an always absolutely positioned navbar (or similar) on smaller devices you won’t need any of this. For those of those it helps – do leave a message, it’s nice to know the views aren’t all spam-bots!!

Reference: For why browser detection is bad: http://css-tricks.com/browser-detection-is-bad/

Breaking up really long words Cross browser

Best solution for cross browser css only way of stopping really long words from overflowing.

Progress Bar as Submit Button

This is an effect I came across a while ago, it’s a neat way of displaying how many required fields have been filled out in a form. It’s not a necessary implementation but a nice bit of UX design. For an example see here: https://www.panic.com/transmit/buy.html (And if you run a Mac their software is some of the best Dev tools I’ve seen so far).

Partial order

Partially Completed Order

Completed Order

A fully filled out order form

So I worked myself up an AngularJS directive, you can see it in action below, just as a whim – it works automatically by dynamically figuring out which elements need to be filled out and which haven’t been filled out. It took a bit to fiddle through the form controller but in the end it’s a fairly elegant solution. Though I wouldn’t recommend using it excessively large forms due to the overhead that may incur. Enjoy!

AngularJS Table Sort Service

I’ve been meaning to do an angular post for a while having enjoyed the framework immensely. First off, go have a look here http://jsfiddle.net/Xanetia/Azhg7/. It supports multiple direction and column (hold shift and click headers) sorting (actually on any ng-repeat, but a table is the simplest usage). Now all you have to do if you want to use it is copy the factory as in that link, or download the following file (which has a bunch of other useful directives as well) and include the ‘sdevgame’ in your module declaration (eg angular.module(‘myapp’, [‘sdevgame’])): http://www.mediafire.com/?96p8pk72u0h2rfr

To use this table sorting service (or in fact to sort ANY ngRepeat) you have to do the following:

  1. Inject MultiOrder into your controller.
  2. Add ng-click=”modOrder($event, ‘name’)” where ‘name’ is the variable you want to orderBy in the ngRepeat, to the elements that you want to use for ordering. In the jsFiddle above I use the <th> tags to order each column.
  3. Add ” | orderBy: MultiOrder.orderArray” to any ngRepeats you want to order (this even works on multiple as long as the object names are the same).
  4. In your controller setup the following:
    $scope.MultiOrder = MultiOrder;
    $scope.MultiOrder.orderArray = ['-name'];//set the initial order
    $scope.MultiOrder.forceOrder = ['+name'];//set any default forced order
    $scope.MultiOrder.plusSortClass = "green";//these classes are put on the element when the sort is applied
    $scope.MultiOrder.minusSortClass = "blue";
    
    $scope.modOrder = MultiOrder.modOrder;

Note: I haven’t figured a way of dynamically applying the initial sorting class, so if you set the initial order or a force order don’t forget to add the class to the relative order element.

JSfiddle

Just thought that I would post about this great site I found called JSfiddle, great for live demo’s of a bit of web code for javascript or any of it’s forms.

I am going to have a look at changing over my examples and demos to this so that they are easier to have a quick look at. Here’s a quick demo of jQuery Tools minimal tab setup in My JSFiddle. It looks like this has some great other functionality as well, so we’ll see. For example you can embed the results, just not in wordpress due to their iFrame restrictions… (someday I’ll get better hosting)

.validator() required field in IE

Just a quick note, in IE, when working with jQuery Tools validator simply writing <input name=”name” type=”text” required> will not work as IE quite happily changes this to: <input name=”name” type=”text” required=””>.

To get required fields to work simply use required=”required” which does work.

Modal on modal with jQuery Tools

So this one took me a bit more work, it works with the Apple Overlay as shown in jQuery Tools here: http://jquerytools.org/demos/overlay/apple.html Just set up your primary overlay (not the trigger) with the class “apple_overlay”.

Below is the code for the secondary overlay/modal, call the first with the following parameters included {closeOnClick: false, closeOnEsc: false}, should work whatever the previous modal/overlay settings, or even if called straight from the page.

var oldMaskZ = null;
var $oldMask = $(null);
$(document).ready(function(){
	$("a[rel].modal").overlay({
		effect: 'apple',
		oneInstance:false,
		closeOnClick: false,
		closeOnEsc: false,
		zIndex: 10100,
		onLoad: function(){
			if($.mask.isLoaded()) {
				//this is a second overlay, get old settings
				oldMaskZ = $.mask.getConf().zIndex;
				$oldMask = $.mask.getExposed();
				$.mask.getConf().closeSpeed = 0;
				$.mask.close();
			this.getOverlay().expose({
					color: 'darkgrey',
					zIndex: 10090,
					closeOnClick: false,
					closeOnEsc: false,
					loadSpeed: 0,
					closeSpeed: 0
				});
			}else{
				this.getOverlay().expose({
					color: 'darkgrey',
					zIndex: 10090,
					closeOnClick: false,
					closeOnEsc: false
				});
			}
			//Other onLoad functions
		},
		onClose: function(){
			$.mask.close();
			//re-expose previous overlay if there was one
			if($oldMask != null){
				$oldMask.expose({
					color: 'darkgrey',
					zIndex: oldMaskZ,
					closeOnClick: false,
					closeOnEsc: false,
					loadSpeed: 0
				});
				//Assumes the other overlay has apple_overlay class
				$(".apple_overlay").css("zIndex", oldMaskZ + 2);
			}
		}
	});
});

To see the whole thing in action with a modified version of the jQuery Tools Example for the apple overlay go to the JSFiddle example.

EDIT: An important point that I actually did figure out but forgot to update about that Tom has just reminded me (thank!!) is that the first overlay must have the properties {closeOnClick: false, closeOnEsc: false} otherwise the funkyness he mentioned occurs. I have updated the files as well.

Multiply Nested Accordions from jQuery Tools.

So todays challenge was quadruply nested accordions using jQuery tools tabs accordion (http://jquerytools.org/demos/tabs/accordion.html). Also I implemented toggling of each tab individually. To see a demonstration visit this JSFiddle page http://jsfiddle.net/Xanetia/8kz4m/, or download the full source code here: http://www.mediafire.com/?cfi8m4lfp0ji60u. Heres The HTML:

<div class="accordion">
 <h2>Level 1:1</h2>
 <div class="pane">
  <div class="accordion">
   <h2>Level 2 : 1</h2>
   <div class="pane">
    <div class="accordion">
      <h2>Set 1</h2>
      <div class="pane">
       <div class="accordion">
        <h2>Test3</h2>
        <div class="pane">
[Pane Content]

That’s the basic format – I’m sure your capable of closing the tags off! Now onto the interesting part, the jQuery bit, as follows:


//Initialising Accordion
$(".accordion").tabs(".pane", {tabs: '> h2', effect: 'slide', initialIndex: null});

//The click to hide function
$(".accordion > h2").click(function(){
 if($(this).hasClass("current") && $(this).next().queue().length == 0){
  $(this).next().slideUp();
  $(this).removeClass("current");
 }else if(!$(this).hasClass("current") && $(this).next().queue().length == 0){
  $(this).next().slideDown();
  $(this).addClass("current");
 }
});

The first line is the standard jQuery tools accordion caller, the parts to note are that the identifiers are classes. The most important part is:

tabs: '> h2'</span>

This is what prevents clicking on a nested tab changing all levels. Pretty neat and simple!

In the click to hide part the issue is that we are not actually changing what is stored in jQuery as the current index, this is why we both hide and show it. The boolean test


$(this).next().queue().length == 0

Checks to see if the jQuery tools default event has fired (this one is evaluated after) stopping the opened/closed tab from just reverting to its previous state.

That’s all, any questions leave me a comment!