Edit in JSFiddle

/**
 *  Note: DOM Utiltity and Drag/Resize units are enclosed.
 */
(function Tips(ns, undefined){
      "use strict"
      ns = ns || 'TIPS';
      var  tipContentClass  = 'tipContent'
          ,tipHeaderClass   = 'header'
          ,tipBodyClass     = 'tbody'
          ,tipElClass       = 'hastooltip'
          ,tipDataId        = 'data-tipid'
          ,tipCreateHeader  = 'data-tipheader'
          ,tipCreateText    = 'data-tiptext'
           //-> initialize DOM utility and Drag unit
          ,Utils            = DOMUtil()
          ,DResize          = DragResize(false)
          ,tipTestRE        = RegExp(tipElClass,'i')
          ,z                = 1
          ,d                = document
          ,w                = window
          ,$$               = Utils.$
          ,docbody          = d.body || d.documentElement
          ,cloneStore       = {}
          ,silentError      = true
          ,tips             = { 'create':   createTip
                               ,'refresh':  refreshTipContent
                               ,'settings': {  'silenterror': function(tf){
                                                                tf = tf && tf === 'false' ? false : true;
                                                                silentError = tf;
                                                              }
                                              ,'dragcontent': DResize
                                              ,'autofix'    : false }
                              }
      ;

      if (!document.querySelector){
            var allElements = d.getElementsByTagName('*');
            for (var i=0;i<allElements.length;(i=i+1)){
              tipTestRE.lastIndex = 0;
              if (tipTestRE.test(allElements[i].className)){
                  allElements[i].onmouseover = null;
                  allElements[i].title = 'no tooltip: upgrade your browser!';
              }
            }

            alert('Your browser doesn\'t support all of the program to show tooltips in this page. '+
                  'A browser upgrade is strongly advised.\n'+
                  'Usable browsers are: Firefox >= 4, Chrome, Opera >=10, Safari or Internet Explorer >=8.');
            return {create: function(){alert('no tooltips available: upgrade your browser');}};
      }

      /** Program **/
      function unit(unit,val){
        val = val || this || '0';
        unit = unit || 'px';
        return String(val)+unit;
      }

      Number.prototype.unit = Number.prototype.unit || unit;

      function init(fromRoot,singleMode){

         function findTip(el){
           return $$('^#'+el.id+' .'+tipContentClass);
         }

         function setHoverstate(e){
            e = e || event;
            var forEl = this.originator || this;
            var thereAreHoveredChildren = /over/i.test(e.type)
                                          ? true
                                          : /out/i.test(e.type) ? false
                                          : chkHoveredChildren(forEl);
            forEl.ishovered = thereAreHoveredChildren ? true : false;
         }

         function initOnLoad(){
           var els = $$(tipElClass.dot())
               ,i  = 0
           ;
           for(;i<els.length;i++){
            Utils.listen(els[i],'mouseover', showTip, null);
           }
         }

         function inits(fromElement,forElement){
          fromElement.id = fromElement.id || Utils.randomId();

          var els = forElement ? [fromElement] : $$('^#'+fromElement.id+' .'+tipElClass)
              ,i = 0
              ,el
              ,head;

          for(;i<els.length;i++){
             el = els[i];

             if (el.tipdone){continue;}

             /* direct creation from data-attributes */
             var createFromData = el.getAttribute(tipCreateText);
             if (createFromData){
              head = el.getAttribute(tipCreateHeader);
              var tipobj = {};
              el.className = el.className.replace(tipTestRE,'');

              if (head){
                tipobj.head = head;
              }
              tipobj.text = createFromData;
              el.removeAttribute(tipCreateHeader);
              el.removeAttribute(tipCreateText);
              createTip(el,tipobj,true);
              return true;
             }
             /* end data-attribute creation */

             var external = $$('#'+el.getAttribute(tipDataId))
                ,tip      = external ? external : findTip(el);

             if (!tip) {
               continue;
             }
             el.tip         = tip;
             el.ishovered   = false;
             tip.isopen     = false;
             tip.originator = el;
             tip.id         = tip.id || Utils.randomId();
             head           = $$('^#'+tip.id+' .'+tipHeaderClass);

             Utils.listen(el,'mouseout',hideTip,null,null);
             Utils.listen(el,'mouseover',setHoverstate,null,null);
             Utils.listen(el.tip,'mouseover',setHoverstate,null,null);
             Utils.listen(el.tip,'mouseout', setHoverstate,null,null);
             if (head){
              Utils.listen(el,'click',fixTip,true,null); //->IE <9 nobubble
              Utils.listen(head,'click'
                     ,function(){Utils.invokeHandler(el,'click');}
                     ,null);
             }
             el.tipdone = true;
           }
         }
         if (fromRoot){
           inits(fromRoot,singleMode);
         } else {
           initOnLoad();
         }
      }

      function minimize(){
        var tclone = this.parentNode.parentNode
           ,txtEl  = $$('^#'+tclone.id+' .'+tipBodyClass)
           ,header = this.parentNode
        ;
        if (/triangledown/i.test(this.className)){
          txtEl.style.position                    = '';
          txtEl.style.top                         = '';
          tclone.style.height                     = '';
          tclone.style.backgroundColor            = '';
          this.parentNode.style.borderBottomColor = '';
          txtEl.style.borderTopColor              = '';
          this.className                          = 'triangleup';
          tclone.style.height                     = '';
        } else {
          tclone.style.width                      = tclone.clientWidth.unit();
          txtEl.style.position                    = 'absolute';
          Utils.hide(txtEl);
          tclone.style.backgroundColor            = '#acaeca';
          this.parentNode.style.borderBottomColor = '#acaeca';
          txtEl.style.borderTopColor              = '#acaeca';
          this.className                          = 'triangledown';
          tclone.style.height                     =  header.clientHeight.unit();
        }
      }

      function createFixed(originalTip, originator){
        var tipclone      = originalTip.cloneNode(false) //->MAN, if true IE < 9 copies handlers too!
           ,bodytext
           ,closeImg      = d.createElement('span')
           ,minImg        = d.createElement('span')
           ,resizeImgY    = d.createElement('span')
           ,resizeImgX    = d.createElement('span')
           ,dragImg       = d.createElement('span')
           ,el
           ,head
           ,nestedtips
           ,hchildren
        ;
        tipclone.id = 'fixClone_'+ originalTip.id;
        tipclone.innerHTML = originalTip.innerHTML; //-> IE<9: get rid of all the handlers
        docbody.appendChild(tipclone);
        head                 = $$('^#'+tipclone.id+' .'+tipHeaderClass);
        tipclone.bodytext    = $$('^#'+tipclone.id+' .'+tipBodyClass);
        tipclone.head        = head;
        tipclone.bodytext.id = tipclone.bodytext.getAttribute('id') || Utils.randomId();
        tipclone.style.width = tipclone.offsetWidth.unit();
        tipclone.setAttribute('data-resizeMaxHeight',800);
        tipclone.setAttribute('data-resizeMaxWidth',800);
        tipclone.style.maxWidth  = '800px';
        tipclone.style.maxHeight = (tipclone.bodytext.scrollHeight+tipclone.head.offsetHeight).unit(); //'800px';

        nestedtips = $$('#'+tipclone.id+' .'+tipElClass);
        if (nestedtips){
         if (!nestedtips.length) {nestedtips = [nestedtips];}
         while (el = nestedtips.pop()){
          Utils.listen(el,'mouseover',showTip,null,null);
         }
        }
        head.className    += ' fix';
        dragImg.className  = 'draghandle';
        hchildren          = head.childNodes;
        closeImg.className = 'fixedcloser moreclickspace';
        closeImg.innerHTML = ' ';
        minImg.className   = 'triangleup';
        minImg.innerHTML   = '';
        dragImg.innerHTML = ' ';
        head.appendChild(minImg);
        head.appendChild(closeImg);
        head.appendChild(dragImg);

        if (tipclone.bodytext.scrollHeight+16 > tipclone.offsetHeight) {
          resizeImgY.setAttribute('data-resizeEl',tipclone.id);
          resizeImgY.className= 'resizehandleY';
          resizeImgX.setAttribute('data-resizeEl',tipclone.id);
          resizeImgX.className= 'resizehandleX';
          resizeImgX.innerHTML = '&nbsp;'
          resizeImgY.innerHTML = '&nbsp;'

          tipclone.bodytext.appendChild(resizeImgY);
          tipclone.appendChild(resizeImgX);
          tipclone.bodytext.style.marginRight = '1px';

          resizeImgY.resizehandler = function(){
           var resizeEl = $$('#'+this.getAttribute('data-resizeEl'))
              ,bodyTxt = $$('^#'+resizeEl.id+' .'+tipBodyClass)
              ,head    = $$('^#'+resizeEl.id+' .'+tipHeaderClass);
           if (bodyTxt) {
             bodyTxt.style.maxHeight = (resizeEl.clientHeight-(head.offsetHeight)).unit();
             bodyTxt.style.height = 'auto';
           }
          };
        }

        dragImg.setAttribute('data-moveEl',tipclone.id);
        head.setAttribute('data-moveEl',tipclone.id);
        createTip(
            closeImg
           ,{text:'close this box <br />(<b class="'+tipElClass+' white" '+
                  'data-tipid="closerNotes" '+
                  'data-tipwidth="300">Notes</b>)'}
           ,true);
        minImg.setAttribute('data-tipwidth',100);
        originator.fixclone = tipclone;

        Utils.listen(closeImg,'click', function(e){
          var tclone       = this.parentNode.parentNode;
          tclone.savedTop  = tclone.offsetTop || null;
          tclone.savedLft  = tclone.offsetLeft;
          Utils.hide(tclone);
          return false;
         }, null, null
        );
        tipclone.savedTop  = tipclone.offsetTop;
        tipclone.savedLeft = tipclone.offsetLeft;
        Utils.listen(minImg,'click',minimize,null, null);
        originalTip.id     = originalTip.id || Utils.randomId();
        //->store the clone for reuse
        cloneStore[tipclone.id] = $$('^#'+originalTip.id+' .'+tipHeaderClass).innerHTML;
        originalTip.blur();
        return originator.fixclone;
      }

      function findClone(forTipHeader){
         for (var l in cloneStore){
           if (cloneStore[l] === forTipHeader){
            return $$('#'+l);
           }
         }
         return null;
      }

      function fixTip(e){
        e = e || event;

        if (!this.tip){
            return true;
        }
        this.tip.id  = this.tip.id || randomId();

        var tip      = this.tip
           ,origHead = $$('^#'+this.tip.id+' .'+tipHeaderClass)
           ,created  = findClone(origHead.innerHTML) || tip.originator.fixclone
           ,tipclone = created || createFixed(tip,tip.originator)
           ,top0     = tipclone.savedTop === null ?  0 : tipclone.savedTop
           ,head     = $$('^#'+tipclone.id+' .'+tipHeaderClass)
           ,scrlTop  = docbody.scrollTop || d.documentElement.scrollTop;

        tipclone.className = tipclone.className.replace(/fadein/gi,'').replace(/^\s+|\s+$/,'');
        tipclone.style.opacity = '1.0';

        //-> restore saved position
        tipclone.style.top  = ( Number(top0) ).unit();
        tipclone.style.left = ( tipclone.savedLft || tip.offsetLeft ).unit();

        //-> scroll to fixed tip if necessary
        if (scrlTop > top0 ){
            docbody.scrollTop = d.documentElement.scrollTop = top0;
        }
        tipclone.style.zIndex = Utils.z.incr();
        if (created){
          head.style.backgroundColor = 'green';
        }
        if ($$('^#'+tipclone.id+' .triangledown')){
          setTimeout( function(){
             head.style.backgroundColor = '';
             Utils.invokeHandler($$('^#'+tipclone.id+' .triangledown'),'click');
            }
            ,500
           );
        } else {
          setTimeout( function(){
             head.style.backgroundColor = '';
            }
            ,300
           );
        }
        //->hide original tip
        tip.originator.ishovered = false;
        Utils.hide(tip);
      }

      function refreshTipContent(tipEl,nwContent,directShow){
        tipEl = tipEl.tip || tipEl;

        var head   = $$('^#'+tipEl.id+' .'+tipHeaderClass)
           ,body   = $$('^#'+tipEl.id+' .'+tipBodyClass)
           ,cloned = $$('#fixClone_'+tipEl.id)
        ;
        if (nwContent.head){
          if (!head){
            head = d.createElement('span');
            head.className = tipHeaderClass;
            tipEl.insertBefore(head,tipEl.childNodes[0]);
            Utils.listen(tipEl.originator,'click',fixTip,null,null);
            Utils.listen(head,'click',function(){Utils.invokeHandler(tipEl.originator,'click');},null,null);
          }
          head.innerHTML = nwContent.head || '?';
        }
        if (nwContent.text){
          body.innerHTML = nwContent.text;
        }
        //-> also refresh the clone (fixed tooltip)
        if (cloned){
          // ->prevent overwrite of header items (iow text refresh only)
          $$('^#'+cloned.id+' .'+tipHeaderClass).firstChild.nodeValue = nwContent.head;
          $$('^#'+cloned.id+' .'+tipBodyClass).innerHTML = nwContent.text;
          cloned.style.width = tipEl.offsetWidth.unit();
          cloned.style.height = tipEl.offsetHeight.unit();
        }
        return true;
      }

      function createTip(fromEl,obj,noInit){
        tipTestRE.lastIndex = 0;
        if (tipTestRE.test(fromEl.className)){
          return true;
        }

        fromEl.className  += ' '+tipElClass;
        var container  = d.createElement('span')
            ,head      = (obj.head ? d.createElement('span') : null)
            ,txt       = d.createElement('span')
            ,nestedTips
        ;

        container.className = tipContentClass;
        txt.className       = tipBodyClass;

        if (head) {
          head.className = tipHeaderClass;
          head.innerHTML = obj.head;
          container.appendChild(head);
        }
        container.id  = Utils.randomId();
        txt.id = Utils.randomId()
        txt.innerHTML = obj.text;
        fromEl.setAttribute(tipDataId,container.id);
        container.appendChild(txt);
        docbody.appendChild(container);
        Utils.hide(container);

        nestedTips = $$('#'+txt.id+' .'+tipElClass);
        if (nestedTips){
          nestedTips = !nestedTips.length ? [nestedTips] : nestedTips;
          for (var i=0;i<nestedTips.length;(i=i+1)){
            Utils.listen(nestedTips[i],'mouseover',showTip,null,null);
          }
        }
        Utils.listen(fromEl,'mouseover',showTip,null,null);
        //->show immediatly (!noInit) or not
        if (!noInit){
          init(fromEl,true);
          Utils.invokeHandler(fromEl,'mouseover');
        } else {
          init(fromEl,true);
        }
        return container.id;
      }

     function chkHoveredChildren(el){
       var  tip = el.tip
           ,children = tip ? $$('#'+tip.id+' .'+tipElClass) : []
           ,hasOpenChildren = false
       ;
       if (children){
         children = children.length ? children : [children];
         for (var i=0;i<children.length;(i=i+1)) {
          if (children[i].tip && (children[i].tip.originator.ishovered || children[i].tip.isopen)){
            return true;
          }
          if (children[i].tip && $$('^#'+children[i].tip.id+' .'+tipElClass)){
            hasOpenChildren = chkHoveredChildren(children[i]);
          }
         }
       }
       return hasOpenChildren;
     }

     function hideTip(e){
        e = e || event;
        var srcEl  = e.srcElement || e.target
           ,tip    = (findTipFromChild(srcEl)).tip
           ,tclose = function(){
                     var bodytxt = $$('^#'+tip.id+' .'+tipBodyClass) || {};
                     Utils.hide(tip);
                     tip.style.width = '';
                     bodytxt.scrollTop = 0;
                     tip.isopen = false;
            }
           ,wait   = function(){
                      var cannotclose = tip.originator.ishovered || chkHoveredChildren(tip.originator);
                      if (!cannotclose){
                       tip.className = tip.className.replace(/fadein/gi,'fadeout').replace(/^\s+|\s+$/,'');
                       setTimeout(tclose,200);
                      } else {
                       setTimeout(wait,200);
                      }
            }
        ;
        tip.originator.ishovered = false;
        return setTimeout(wait,200);
      }

      function tipRelatedDimensions(el) {
        var  postop  = Utils.findPos(el,null)
            ,posleft = Utils.findPos(el,true)
        ;
        return {
                 top:       postop
                ,left:      posleft
                ,height:    el.offsetHeight
                ,bottom:    postop+el.offsetHeight
                ,width:     posleft+el.offsetWidth
                ,docbottom: ((w.innerHeight || d.documentElement.clientHeight)+
                             (w.pageYOffset || d.documentElement.scrollTop))-16  // 16 = scrollbar space
                ,docright:  ((w.innerWidth  || d.documentElement.clientWidth) +
                             (w.pageXOffset || d.documentElement.scrollLeft))-16
                ,tipright:  0
                ,tipbottom: 0
        };
      }

      function tipCreationError(tipEl){
       if (silentError){
        tipEl.className = tipEl.className.replace(tipElClass,'');
        tipEl.setAttribute('title','tip creation failed!'); //-> FF doesn't show it because of it's stupid bubbling shit!
        if (tipEl.removeEventListener){
          var h;
          while (h = Utils.handlerCache[tipEl.id].mouseover.pop()){
           tipEl.removeEventListener('mouseover',h,false);
          }
        }
        return true;
       }

        var datax = [], attribs = tipEl.attributes, attrib;
        for (var i=0;i<attribs.length; (i = i+1)){
         if (/data\-/i.test(attribs[i].name)){
           datax.push('<i>'+attribs[i].name+'</i>: "'+tipEl.getAttribute(attribs[i].name)+'"');
         }
        }
        tipEl.className = tipEl.className.replace(tipElClass,'');
        tipEl.setAttribute('data-tipwidth',300);
        var linkToTechnicalHowTo =
              ['(see also: <span class="'+tipElClass+'" ',
               'data-tipid="technical" data-tipwidth="400">',
               'techical how to</span>)'].join('');
        createTip(tipEl,{text:[ '<p>We tried to create a tooltip '
                               ,'but failed to do so, sorry. '
                               ,'Check your HTML/ECMA-code</p>'
                               ,'<p>Possible relevant attributes where:</p>'
                               ,'<p>',datax.join('<br />'),'</p>'
                               ,'<p>',linkToTechnicalHowTo,'</p>'].join('')
                         ,head: 'An error occured'},false);
        silentError = 'true'; //->reporting an error is always explicit
        return true;
      }

      function showTip(e){
        e = e || event;

        if (d.onthemove){ return false; }

        var originator = e.srcElement || e.target;

        var tipEl = (originator.tip || (RegExp(tipElClass,'i').test(originator.className))
                     ? originator
                     : findTipFromChild(originator));

        if (!tipEl) { console.log('tja ...'); return true; }

        if (!tipEl.tip) {

          init(tipEl,true);

          if (!tipEl.tip) {//->no hopes, couldn't create tooltip
            tipCreationError(tipEl);
            return true;
          }
        }

        //-> if a clone is open, show that
        if (tipEl.fixclone && tipEl.fixclone.offsetTop>=-10){
           return fixTip.call(tipEl,e);
        }

        var tip    = tipEl.tip
           ,post   = Utils.findPos(tipEl,null)
           ,posl   = Utils.findPos(tipEl,true)
           ,maxw   = Math.floor((w.innerWidth  || docbody.clientWidth)/3)
           ,dims   = tipRelatedDimensions(tipEl)
           ,tipw   = Number(tipEl.getAttribute('data-tipwidth')) || null
           ,clkspce= /moreclickspace/i.test(tipEl.className);
        ;

        tip.scrolledup     = false;
        tip.style.width    = tipw ? tipw.unit() :
                              tip.offsetWidth > maxw
                               ? maxw.unit()
                               : tip.offsetWidth;
        tip.style.position = 'absolute';
        tip.style.left     = (dims.left-1).unit();
        tip.style.top      = (dims.top+dims.height-(clkspce ? -3 : 1)).unit();

        dims.tipbottom = Utils.findPos(tip,null) + tip.offsetHeight;
        dims.tipright  = Utils.findPos(tip,true) + tip.offsetWidth;

        if (dims.tipbottom > dims.docbottom){ //->move in sight (up)
            while ( (dims.tipbottom = Utils.findPos(tip,null) + tip.offsetHeight)
                      >= dims.top ){
             tip.style.top = ( tip.offsetTop-8 ).unit();
            }
            tip.scrolledup = true;
        }

        if (dims.tipright >= dims.docright){ //->move in sight (left)
            while ((dims.tipright = Utils.findPos(tip,true) + tip.offsetWidth)
                    >= dims.docright-8){
              tip.style.left = (tip.offsetLeft-8).unit();
            }
            if (tip.scrolledup){
              tip.style.top = (dims.top-tip.offsetHeight).unit();
            }
        }

        if (Utils.findPos(tip,null) < (dims.top+dims.height-4) ){ //->move above originator
          tip.style.top = (dims.top-tip.offsetHeight).unit();
        }

        if (tip.offsetTop < 0){ //->move in sight (down)
          while(tip.offsetTop < 0){
            tip.style.top = (tip.offsetTop+10).unit();
          }
        }
        tip.style.zIndex = Utils.z.incr();
        tip.isopen = true;
        setTimeout(function(){
            if (/fadeout/i.test(tip.className)){
             tip.className = tip.className.replace(/fadeout/gi,'fadein').replace(/^\s+|\s+$/,'');
            } else {
              tip.className += ' fadein';
            }
           },10);
        return true;
      }

      function findTipFromChild(el){
         var reTipClass = RegExp(tipElClass,'i');
         if (el.tip) {return el}
         while (el = el.parentNode){
            reTipClass.lastIndex = 0;
            if (el.tip || reTipClass.test(el.className)) {
             return el;
            }
         }
         return null;
      }

      //->initialize the whole stuff
      init(null,null);

      //->return a create method (all other methods are private)
      //  and a few setting properties
      //return tips;
      // no! we will put it in the given namespace
      w[ns] = tips;

/** ------------------------------ a few DOM utilities --------------------------------- **/
      function DOMUtil(){

        String.prototype.trimall = String.prototype.trimall ||
         function() {return this.replace(/^\s+|\s+$/,'').replace(/\s+/g,' ');}

        String.prototype.dot = String.prototype.dot ||
         function() {return '.'+this;}

        var w            = window
           ,d            = document
           ,handlerCache = {}
           ,z            =
                (function(){
                  var z = 0;
                  return {
                      incr: function(){z += 1; return z;}
                     ,toString: function(){return Number(z);}
                  };
                })()
        ;
        function hide(el){
          if (!el) {return true;}
          el.style.top = '-5000px';
        }

        function listen(el,etype,fn,nobubble,stopdefault){
            nobubble = nobubble || false;
            stopdefault = stopdefault || false;
            el.id = el.id || randomId();

            if (!handlerCache[el.id]){
              handlerCache[el.id] = {};
            }
            if (!handlerCache[el.id][etype]){
               handlerCache[el.id][etype] = [];
            }

            var fnwrap = function(e){
                  e = e || event;
                  if (nobubble) {
                    Utils.noBubbles(e);
                  }
                  if (stopdefault){
                    Utils.noDefault(e);
                  }
                  return fn.apply(el,Array.prototype.slice.call(arguments));
                }
            ;
            if (el.attachEvent) {
             el.attachEvent('on' + etype, fnwrap);
            } else {
             el.addEventListener(etype, fnwrap, false); //-> just bubble
            }
            handlerCache[el.id][etype].push(fnwrap);
        }

        function getEl(selector,root) {
          root = root || document;
          if (!selector || /nul/i.test(selector)) {return null;}
          var single  = /^\^/.test(selector)
             ,qselect = single ? 'querySelector' : 'querySelectorAll'
             ,nlist
             ,result  = []
             ,i       = 0;

          selector    = single ? selector.substr(1) : selector;
          nlist       = root[qselect](selector);

          if (nlist && (single || nlist.length === 1) ){
            return nlist.length ? nlist[0] : nlist; }

          if (nlist){
           for (;i<nlist.length;(i=i+1)){
            result.push(nlist[i]);
           }
           if (result.length){
            return result.length === 1 ? result[0] : result;
           }
          }
          return null;
        }

        function invokeHandler(el, etype){
          if (!el){return true;}
          if (el.fireEvent) {
            (el.fireEvent('on' + etype));
          }
          else {
            var evObj = d.createEvent('Events');
            evObj.initEvent(etype, true, false);
            el.dispatchEvent(evObj);
          }
        }

       function noDefault(e) {
            if (e.preventDefault){
              e.preventDefault();
            } else {
              e.returnValue = false;
            }
       }

        function noBubbles(e){
          if (e.stopPropagation){
              e.stopPropagation();

          } else {
              e.cancelBubble = true;
          }
        }

        function findPos(el,left){
          var which = left ? 'offsetLeft' : 'offsetTop'
             ,pos   = 0
             ,st    = findScrPos(el,left);
          while ( el ){
              pos += el[which] || 0;
              el = el.offsetParent;
          }
          return pos - st;
        }

        function findScrPos(el,left){
          var which = left ? 'scrollLeft' : 'scrollTop'
             ,pos   = 0;
          while( (!/body/i.test(el.tagName) && el) ){
            pos += el[which] || 0;
            el = el.parentNode;
          }
          return pos || 0;
        }

        function randomId(){
          return 'R_'+(Math.floor( Math.random()*10000 )+1000).toString(16);
        }

        function getCS(el,sProp,toInt){
          var elem = el;
          if (elem.currentStyle) {
            return toInt ? parseInt(elem.currentStyle[sProp],10) : elem.currentStyle[sProp] || 0;
          } else if (w.getComputedStyle) {
            var compStyle = w.getComputedStyle(elem, null)[sProp];
            return toInt ? parseInt(compStyle,10) : compStyle || 0;
          }
          return String(elem.style[sProp]||0);
        }

        return {
                 listen:        listen
                ,invokeHandler: invokeHandler
                ,noBubbles:     noBubbles
                ,noDefault:     noDefault
                ,findPos:       findPos
                ,randomId:      randomId
                ,getCS:         getCS
                ,hide:          hide
                ,handlerCache:  handlerCache
                ,$:             getEl
                ,z:             z
        };
      }; //-> Utils *end

      /** ------------------------------ drag object (sealed) ------------------------------ **/
      function DragResize(dragcontent){
        var currentDragbox = null
           ,d              = document
           ,w              = window
           ,docbody        = d.body || d.documentElement
           ,action
           ,savedcoords
           ,savedpos
           ,elHandle
           ,elRaw
           ,dragContent    = dragcontent
        ;

        function chkAction(el){
            var move   = elRaw.getAttribute('data-moveEl')
               ,resize = elRaw.getAttribute('data-resizeEl');
            return move || resize || false;
        }

        function dragInit(e){
          e = e || event;

          elRaw    = e.srcElement || e.target;

          if ( !chkAction(elRaw) ){
            return false; //-> solves the FF no title problem!
          }

          var moveEl, resizeEl;

          if (!elRaw.moveEl || !elRaw.resizeEl){
            moveEl   = elRaw.getAttribute('data-moveEl') || elRaw.moveEl;
            resizeEl = elRaw.getAttribute('data-resizeEl') || elRaw.resizeEl;
            ;

            if (moveEl){
              action = 'drag';
              elRaw.moveEl = $$('#'+moveEl);
            }
            if (resizeEl){
              action = 'resize'
              elRaw.resizeEl = $$('#'+resizeEl);
            }
          }

          elHandle = elRaw.moveEl || elRaw.resizeEl || undefined;

          if (!elHandle){
            return true;
          }

          Utils.noDefault(e);

          savedcoords = savedcoords || getCoords(e,null,null);
          var elTop    = Utils.findPos(elHandle,null)
             ,elLeft   = Utils.findPos(elHandle,true)
             ,elHeight = elHandle.offsetHeight
             ,elWidth  = elHandle.offsetWidth
          ;

          if (!elHandle.dragInitDone){
            createDragBox(elHandle);
          }

          elRaw.relatedTo = elHandle;
          elHandle.style.position = 'absolute';

          if (elHandle.hoverbox.dragStarted){return true;}

          currentDragbox              = elHandle.hoverbox;
          currentDragbox.style.top    = (elTop-currentDragbox.borderWidth).unit();
          currentDragbox.style.left   = (elLeft-currentDragbox.borderWidth).unit();
          currentDragbox.style.height = elHeight.unit();
          currentDragbox.style.width  = elWidth.unit();
          currentDragbox.style.cursor = Utils.getCS(elRaw,'cursor');
          currentDragbox.coords       = [elTop,elLeft];
          currentDragbox.dragStarted  = true;
          elHandle.style.zIndex       = Utils.z.incr();
          currentDragbox.style.zIndex = Utils.z+1;

          if (elRaw.resizeEl){
            currentDragbox.maxwh =
              [ Number(elHandle.getAttribute('data-resizeMaxWidth') || docbody.clientWidth)
               ,Number(elHandle.getAttribute('data-resizeMaxHeight') || docbody.clientHeight)];
            currentDragbox.minwh = [200,100];
          }
        }

        function getCoords(e,top,left){
          top = top || d.body.scrollTop || d.documentElement.scrollTop;
          left = left || d.body.scrollLeft || d.documentElement.scrollLeft;

          var  y = e.pageY || e.clientY+top
              ,x = e.pageX || e.clientX+left
          ;
          return [y,x];
        }

        function doResize(e){

          if (!currentDragbox || elRaw.moveEl || !elRaw.resizeEl ||
               (currentDragbox.relatedTo.offsetHeight < Math.floor(currentDragbox.relatedTo.offsetHeight*0.2)
              || currentDragbox.relatedTo.offsetWidth < Math.floor(currentDragbox.relatedTo.offsetWidth*0.2)))
          { return true; }

          Utils.noDefault(e);

          d.onthemove = true; // don't trigger other tooltips whilst resizing

          var topBndry     = d.body.scrollTop || d.documentElement.scrollTop
             ,boxw         = currentDragbox.clientWidth
             ,boxh         = currentDragbox.clientHeight
             ,leftBndry    = d.body.scrollLeft || d.documentElement.scrollLeft
             ,rightBndry   = (leftBndry+d.documentElement.clientWidth)
             ,coords       = getCoords(e,topBndry,leftBndry) || savedcoords
             ,distanceY    = coords[0] - savedcoords[0]
             ,distanceX    = coords[1] - savedcoords[1]
             ,atBoundryRgt = currentDragbox.offsetLeft+currentDragbox.offsetWidth + distanceX > rightBndry
             ,atMaxHeight  = boxh+distanceY >= currentDragbox.maxwh[1]
             ,atMaxWidth   = boxw+distanceX >= currentDragbox.maxwh[0]
             ,atMinHeight  = boxh+distanceY <= 100
             ,atMinWidth   = boxw+distanceX <= 200
             ,atmax        = atMaxHeight && atMaxWidth
             ,atmin        = atMinHeight && atMinWidth
             ,direction    = /s\-/.test(Utils.getCS(elRaw,'cursor')) ? 'y' : 'x';
          ;

          //->custom post hoc resize handler
          if (elRaw.resizehandler && !elRaw.resizeHandlerDone){
            Utils.listen(elRaw,'resize',elRaw.resizehandler,null);
            elRaw.resizeHandlerDone = true;
          }

          if (direction === 'y'){
            currentDragbox.style.height =  atMaxHeight
                                           ? currentDragbox.maxwh[1].unit()
                                           : atMinHeight
                                             ? '100px'
                                             : (currentDragbox.clientHeight+distanceY).unit();
            elHandle.style.height  = (currentDragbox.offsetHeight - (currentDragbox.borderWidth*2)).unit();
            Utils.invokeHandler(elRaw,'resize');
          } else if (direction === 'x'){
            currentDragbox.style.width  =  atMaxWidth
                                           ?  currentDragbox.maxwh[1].unit()
                                           : atMinWidth
                                             ? '200px'
                                             : atBoundryRgt
                                              ? (currentDragbox.offsetWidth-16).unit()
                                              : (currentDragbox.clientWidth + distanceX).unit();
            elHandle.style.width   = (currentDragbox.offsetWidth - (currentDragbox.borderWidth*2)).unit();
            if (distanceX > 0) {
              elHandle.style.height  =   '';
            }
            currentDragbox.style.height = elHandle.clientHeight.unit();
          }

          if (atmax || atmin){
            savedcoords = coords;
            return stopResize(e);
          }

          savedcoords = coords;
          return false;
        }

        function doDrag(e){
          e = e || event;

          if (!currentDragbox || elRaw.resizeEl) {return false;}

          Utils.noDefault(e);
          d.onthemove = true; // don't trigger other tooltips whilst moving

          var topBndry     = d.body.scrollTop || d.documentElement.scrollTop
             ,leftBndry    = d.body.scrollLeft || d.documentElement.scrollLeft
             ,rightBndry   = (leftBndry+d.documentElement.clientWidth)
             ,coords       = getCoords(e,topBndry,leftBndry) || savedcoords
             ,distanceY    = coords[0]- savedcoords[0]
             ,distanceX    = coords[1]- savedcoords[1]
             ,atBoundryTop = currentDragbox.offsetTop + distanceY <= topBndry
             ,atBoundryLft = currentDragbox.offsetLeft + distanceX <= leftBndry
             ,atBoundryRgt = currentDragbox.offsetLeft+currentDragbox.offsetWidth + distanceX > rightBndry
          ;
          currentDragbox.style.top  =  atBoundryTop
                                       ? (topBndry).unit()
                                       : (currentDragbox.offsetTop+distanceY).unit();
          currentDragbox.style.left =  atBoundryLft
                                       ? (leftBndry).unit()
                                       : atBoundryRgt
                                         ? (rightBndry-currentDragbox.offsetWidth).unit()
                                         : (currentDragbox.offsetLeft+distanceX).unit();

          if (dragContent) {
           currentDragbox.relatedTo.style.top  = (currentDragbox.offsetTop+currentDragbox.borderWidth).unit();
           currentDragbox.relatedTo.style.left = (currentDragbox.offsetLeft+currentDragbox.borderWidth).unit();
          }

          savedcoords = coords;
          return false;
        }

        //->move
        function startdr(e){
          e = e || event;
          return /resize/i.test(action) ? doResize(e) : doDrag(e);
        }

        //->mouseup
        function stopdr(e){
           return /resize/i.test(action) ? stopResize(e) : stopDrag(e);
        }

        function stopResize(e){
          if (!currentDragbox){ return true; }
          var relatedTo              = currentDragbox.relatedTo;
          relatedTo.style.width      = currentDragbox.offsetWidth.unit();
          relatedTo.style.height     = (currentDragbox.offsetHeight-(currentDragbox.borderWidth*2)).unit();
          relatedTo.savedTop         = currentDragbox.offsetTop || null;
          relatedTo.savedLft         = currentDragbox.offsetLeft;
          currentDragbox.dragStarted = false;
          Utils.hide(currentDragbox);
          currentDragbox             = null;
          d.onthemove                = false;
          savedcoords                = null;
          action                     = null;
        }

        function stopDrag(e){
          if (!currentDragbox){ return true; }
          var boxtop                 = (currentDragbox.offsetTop<0
                                        ? 0
                                        : currentDragbox.offsetTop.unit())
             ,relatedTo              = currentDragbox.relatedTo;
          relatedTo.style.top        = boxtop;
          relatedTo.style.left       = currentDragbox.offsetLeft.unit();
          relatedTo.savedTop         = currentDragbox.offsetTop || '0';
          relatedTo.savedLft         = currentDragbox.offsetLeft;
          currentDragbox.dragStarted = false;
          Utils.hide(currentDragbox);
          currentDragbox             = null;
          d.onthemove                = false;
          savedcoords                = null;
          action                     = null;
        }

        function createDragBox(dragEl){
          var hoverbox          = dragEl.cloneNode(false);
          hoverbox.id           = Utils.randomId();
          hoverbox.className    = 'dragresizebox';
          docbody.appendChild(hoverbox);
          hoverbox.borderWidth  = Utils.getCS(hoverbox,'borderTopWidth',true);
          hoverbox.style.width  = dragEl.clientWidth.unit();
          hoverbox.style.height = dragEl.clientHeight.unit();
          hoverbox.style.left   = (dragEl.offsetLeft-hoverbox.borderWidth).unit();
          hoverbox.style.top    = (dragEl.offsetTop-hoverbox.borderWidth).unit();
          hoverbox.relatedTo    = dragEl;
          dragEl.hoverbox       = hoverbox;
          dragEl.dragInitDone   = true;
        }

        //-> add Utils.listeners
        if (!d.dragHandlersDone){
         Utils.listen(d,'mousedown', dragInit, null, null);
         Utils.listen(d,'mouseup',   stopdr, null, null);
         Utils.listen(d,'mousemove', startdr, null, null);
         d.dragHandlersDone = true;
        }

        return {
                 'switch': function(){dragContent = !dragContent; return this;}
                ,'toString': function(){return Number(dragContent);}
               };
      } //-> DragResize *end

})('TIPS',undefined) //->Tips *end
jsfiddle: <a href="http://jsfiddle.net/KooiInc/m2b8Y/embedded" target="_blank">show embedded</a>
<br /><a href="http://testbed.nicon.nl/tooltips2.0" target="_blank">see also ...</a>
<p title="Firefox title-problem resolved" style="font-weight:bold">Firefox doesn't show a title here</p>

<h2>Tooltip 2.0 framework (demo and instruction)</h2>

<p style="font: bold 1.2em verdana, arial">How does this <span class="hastooltip" data-tipid="tipHelp">work?</span></p>

<p><input type="checkbox" onclick="TIPS.settings.dragcontent.switch();"/>
<span class="hastooltip" data-tiptext="check to show content while mo&shy;ving a fix&shy;ed tool&shy;tip, or un&shy;check to use a (de&shy;tach&shy;ed) drag box" data-tipwidth="200">change drag method</span>
</p>

<p><span class="hastooltip" data-tipid="version">Version information</span></p>

<p>A small <span class="hastooltip" data-tiptext="2011-2012">tooltip</span> without a header</p>

<p>A refreshable <span
   class="hastooltip" data-tiptext="click to refresh contents (and add a header)"
   onclick="TIPS.refresh(this,{head: 'Header added', text:'Content refreshed '+(new Date().toLocaleString())+'<br />click to re-refresh'},true);">tooltip</span>

<p><span title="click to create a tooltip" style="color:red; cursor:pointer" id="testCreate" onclick="TIPS.create(this,{'head':'I just have been freshly created','text':'And here your text'});this.style.color='';this.title=''">create a tooltip</span></p>

<p>Error message in tooltip (the tooltip initialisation <span class="hastooltip" data-text="this tooltip won't work" data-header="hithere"onmouseover = "TIPS.settings.silenterror('false')">fails</span> (<code>TIPS.settings.silenterror('false')</code>))

<p>Error message in title (the tooltip initialisation <span class="hastooltip" data-text="this tooltip won't work" data-header="hithere">fails</span>, but it's only reflected in a small title (default setting)


<span style="position:absolute; display:inline-block; right: 20px;margin-top: 0">
  this tip will move into the visible part of the <span class="hastooltip" data-tipid="leftScrolledFirst">screen</span>
</span>
</p>

<div style="height: 2000px">&nbsp;</div>

<div id="scroller" style="position:absolute; bottom:20px;">
 <span class="hastooltip" data-tipid="largeTip">this tooltip may move upward</span> (if this line is @ the bottom of the screen)</div>

<!-- tips here -->
<span class="tipContent" id="foutafvang">
    <span class="header">error handling</span>
    <span class="tbody">the tooltip next to this text (<i>placerat in elementum</i>)
    was not declared the right way and thus will not be generated on hovering the text.
    Instead, an error message is displayed in a custom tooltip.</span>
</span>

<span class="tipContent" id="tipHelp">
    <span class="header">tooltip howTo</span>
    <span class="tbody">
        <ul style="margin-left:-1em">
         <li>You already noticed: moving your mouse pointer over text that looks
           <span class="ttdemo">like this</span> makes a
           <span class="hastooltip" data-tipid="tooltipexplain" data-tipwidth="250">tooltip</span> appear.
           You can make it disappear by moving your mouse away</li>
         <li>You can also move your mouse pointer <i>into</i> a tooltip, to copy text or
          in case of a larger tooltip scroll down to read more.</li>
         <li>While your mouse pointer resides
          above a tooltip, the tooltip will not close. This also is true for tooltips within
          tooltips (aka <i>nested</i> tooltips).</li>
         <li>If a tooltip is larger than the current bottom or right border of your screen, it
            will move into vision. If the top of tooltip would be above the top of your screen,
            it scrolls down until it's visible.</li>
         <li>If a tooltip has a header, you can <i>fix</i> it (keep it visible) on your screen by clicking on the originating text
         or the tooltip header</li>
         <li>A thus fixed tooltip can be <i>dragged</i> to another position on your screen by
         keeping your left mousebutton pressed on its header and dragging it around.</li>
         <li>A fixed tooltip can be <i>minimized/&shy;maximized</i>, using the arrow symbol at the right of the header</li>
         <li>A fixed tooltip containing a scrollbar can be <i>resized</i> horizontally (to twice its width)
         by dragging the right border, and vertically (until twice its height or until the
         scrollbar disappears) by dragging the bottom border.
         <li>If you want to use the tooltip framework,
         check this bit of <span class="hastooltip" data-tipid="technical">technical information</span>
         <li>That's all, basically. Enjoy!</li>
        </ul>
    </span>
</span>

<span class="tipContent" id="tooltipexplain">
 <span class="tbody white">
    The tooltip or infotip is a common graphical user interface element. It is used in conjunction with a cursor, usually a pointer. The user hovers the pointer over an item, without clicking it, and a tooltip may appear &#8212; a small "hover box" with information about the item being hovered over.<br />
    (Source: <a class="hastooltip" data-tiptext="[link] opens in new tab/window" href="http://en.wikipedia.org/wiki/Tooltip" target="_blank">wikipedia</a>)
 </span>
</span>

<span class="tipContent" id="technical">
    <span class="header">tooltip howTo (technical)</span>
    <span class="tbody">
        <p>This tooltip framework contains plain vanilla ECMAscript. It delivers
            a <code>TIPS</code> object.
        </p>
        <p>There are three ways to create a tooltip.</p>
        <ul style="margin-left:-1em; margin-top:0">
        <li/>The first (preferred for longer tooltips) method is using a
         <span class="hastooltip" data-tipid="tech2">html div or span</span>
         containing tip text and/or a header element<br />
        <li/>Using <span class="hastooltip" data-tipid="tech4">data-attributes </span>
         is the second (preferred for short tooltips) method
        <li/>The third way is using <span class="hastooltip" data-tipid="tech3">javascript.</span>
        </ul>
        <p>The script is tested in the latest versions of Firefox, Chrome, Opera, Safari,
        Mobile Android and Internet Explorer (v>=8).
        For IE&lt;9 some fancy styling will not render.
        For the mobile Androidbrowser tips are (de)activated by a 'fingerclick'</p>
    </span>
</span>

<span class="tipContent" id="tech4">
    <span class="header">using data attributes</span>
    <span class="tbody">create a <code>&lt;span></code> element with <code>class="hastooltip"</code>
    and 1 or 2 data-attributes:
<pre>&lt;span class="hastooltip"
       <span style="color:green">data-tipheader="a header"
       data-tiptext="some tooltip text"</span>>
 create me!
&lt;/span></pre>
    Which 'in real life' resolves to:
    <span class="hastooltip" data-tipheader="a header" data-tiptext="some tooltip text">create me!</span>
    </span>
</span>

<span class="tipContent" id="tech2">
    <span class="header">html tip repository</span>
    <span class="tbody">
      Create your tip (within your html, make sure the element gets a unique id):
<pre>&lt;span class="tipContent"
      <span style="color:green">id="simpleExternal"</span>>
  &lt;span class="header">
   simple header
  &lt;/span>
  &lt;span class="tbody">
   The actual tip content
  &lt;/span>
&lt;/span></pre>
      Now you can address your tooltip using
      <pre>&lt;span class="hastooltip"
      <span style="color:green">data-tipid="simpleExternal"</span>>
      ...
&lt;/span></pre>
    </span>
</span>

<span class="tipContent" id="tech3">
    <span class="header">using javacript</span>
    <span class="tbody">
        The framework provides a method <code>create</code> in the <code>TIPS</code> namespace, which
        takes 2 arguments: the element you want to create the tip for, and
        an object containing the tip information. Say you have a &lt;span>
        with id "newtip", and you want to show extra information. The code
        looks like this
<pre>TIPS.create(
  document.getElementById('newtip'),
  {
   head: 'this is a new tip',
   body: 'This is extra information'
  }
);</pre>
See the example (red colored text) in this document.
    </span>
</span>


<span class="tipContent" id="leftScrolledFirst">
    <span class="tbody" style="white-space:nowrap">
     <span class="hastooltip" data-tipid="leftScrolledSecond">moved into vision</span>
    </span>
</span>

<span class="tipContent" id="leftScrolledSecond">
    <span class="tbody" style="white-space:nowrap">And this one moved into vision too</span>
</span>


<span class="tipContent" id="extTipTest">
    <span class="header">Hi, I am External</span>
    <span class="tbody">
        Some text, for the hack of it ....
        <p>Sed fermentum metus sed dolor elementum nec pharetra turpis tincidunt. Praesent felis massa, dictum bibendum bibendum ut, accumsan nec metus. Pellentesque lectus felis, rhoncus sed porta vitae, convallis a purus. Curabitur volutpat adipiscing pretium. Duis pulvinar suscipit lectus eu congue. Donec sit amet nibh leo, id suscipit risus. Vivamus sit amet nulla velit, non vehicula lacus. Maecenas aliquet tincidunt dolor non porttitor. Fusce id congue dolor. Cras ipsum libero, molestie ut congue nec, viverra in tellus. Aliquam at risus justo.</p>

<p>Curabitur auctor consequat diam, <span class="hastooltip" data-tipid="deeper">quis placerat ligula rhoncus non</span>. Fusce massa erat, sodales ut rutrum eget, bibendum rhoncus nibh. Sed laoreet molestie consectetur. In quis euismod massa. Cras dapibus turpis elementum ante faucibus lacinia. In tempus ullamcorper quam, at porta dui rhoncus nec. Nam a leo in risus tristique vulputate. Morbi ut luctus enim. Quisque a justo leo. Aliquam vel neque nec eros interdum lobortis sed at justo.</p>
    </span>
</span>

<span class="tipContent" id="deeper">
    <span class="header"><i>Third</i> level</span>
    <span class="tbody">
        This is third level nested ...<br />
        And, why not? A <span class="hastooltip" data-tipid="stilldeeper" data-tipwidth="180"><b>fourth <i>level</i></b></span>
    </span>
</span>

<span class="tipContent" id="stilldeeper">
    <span class="header"><i>Fourth</i> level (head abbreviated)</span>
    <span class="tbody">Well, what'd'ya know ...
    </span>
</span>

<span class="tipContent" id="largeTip">
     <span class="header">Large and scrollable tooltip</span>
       <span class="tbody">
        <h3 style="margin-top:0">this tip scrolls and has nested tooltips</h3>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pretium hendrerit volutpat. Integer felis dui, convallis a scelerisque sit amet, <span class="hastooltip" data-tipid="extTipTest">hendrerit eget dolor</span>. Suspendisse interdum vulputate magna vel aliquam.
       Nulla aliquam tempus est a aliquam. Donec pretium dolor sem. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec suscipit massa ac enim ullamcorper sed luctus ipsum interdum. In hac habitasse platea dictumst. Etiam ullamcorper arcu non sem tincidunt ut vulputate est aliquet.</p>

<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut orci velit, ultrices in tincidunt at, sodales ut mauris. Maecenas in felis sed tellus luctus accumsan. Pellentesque tincidunt eros vitae leo
  <span class="hastooltip" data-tipheader="well ehr" data-tiptext="this is another tooltip, isnt it?">varius</span> sit amet malesuada tellus rhoncus. Vestibulum eget diam mi, non commodo libero. Vivamus sem justo, elementum ac ultrices quis, auctor at purus. Nunc iaculis, nisl sed tempus volutpat, ligula arcu convallis mauris, vitae pulvinar sem tellus et leo. Ut scelerisque aliquet fringilla. Ut pellentesque cursus est sit amet molestie.</p>

<p>Quisque mi nibh, condimentum sed scelerisque eu, dignissim id metus. Proin et orci velit. Sed vel justo tortor. Phasellus vitae tellus nec ligula tristique vestibulum a sed diam. Etiam velit turpis, imperdiet sed posuere quis, iaculis vehicula magna. Nulla ac leo ut quam vulputate fringilla sed quis nunc. Fusce risus augue, posuere ut accumsan nec, viverra eu quam. Suspendisse egestas pretium nunc vitae sagittis. Donec lacus risus, pretium convallis facilisis eu, rhoncus ac orci. Proin mauris nulla, fermentum vitae fringilla vitae, pretium a arcu. Suspendisse laoreet dui id metus condimentum cursus placerat est volutpat. Nulla tincidunt iaculis sapien, imperdiet varius leo molestie ac. Praesent ultricies volutpat nibh, et laoreet lacus aliquam a. Fusce arcu leo, lacinia eu aliquam convallis, lobortis nec tortor. Maecenas risus orci, placerat in elementum non, accumsan quis orci. In iaculis tempus velit, ac consectetur velit mollis at.</p>

<p>Sed fermentum metus sed dolor elementum nec pharetra turpis tincidunt. Praesent felis massa, dictum bibendum bibendum ut, accumsan nec metus. Pellentesque lectus felis, rhoncus sed porta vitae, convallis a purus. Curabitur volutpat adipiscing pretium. Duis pulvinar suscipit lectus eu congue. Donec sit amet nibh leo, id suscipit risus. Vivamus sit amet nulla velit, non vehicula lacus. Maecenas aliquet tincidunt dolor non porttitor. Fusce id congue dolor. Cras ipsum libero, molestie ut congue nec, viverra in tellus. Aliquam at risus justo.</p>

<p>Curabitur auctor consequat diam, quis placerat ligula rhoncus non. Fusce massa erat, sodales ut rutrum eget, bibendum rhoncus nibh. Sed laoreet molestie consectetur. In quis euismod massa. Cras dapibus turpis elementum ante faucibus lacinia. In tempus ullamcorper quam, at porta dui rhoncus nec. Nam a leo in risus tristique vulputate. Morbi ut luctus enim. Quisque a justo leo. Aliquam vel neque nec eros interdum lobortis sed at justo.</p>
</span>

</span>

<span class="tipContent" id="smallExt">
    <span class="tbody">Sed fermentum metus sed dolor.</span>
</span>

<span class="tipContent" id="xhrTest">
   <span class="header">xhr tooltip test</span>
    <span class="tbody"></span>
</span>

<span class="tipContent" id="version">
    <span class="tbody">
        RTM version. See also the
        <a class="hastooltip" data-tiptext="link opens in new window/tab" target="_blank" href="http://tooltips.codeplex.com/">codeplex repository</a>
   </span>
  </span>
</span>


<span class="tipContent" id="closerNotes">
    <span class="header">fixed tooltip usage notes</span>
    <span class="tbody">
        <p>You can drag this box to another position on your screen (move you mouse pointer
        into the header, press and keep its left button down while
        moving the mouse around).</p>
        <p>If you activate the tooltip again and the previously fixed tooltip is still open,
        that [fixed tooltip] will be shown at position where it was closed before.</p>
        <p>A fixed tooltip can be <i>minimized/&shy;maximized</i> using the arrow symbol
        at the left of the pin symbol in the header</p>
    </span>
</span>

    body {
     font: normal 0.8em/1.3em verdana,arial;
    }

    a {
     text-decoration:none;
    }

    pre,code {font-size:1.2em; color: green}

    .noselect {
     -webkit-user-select: none;
     -khtml-user-select: none;
     -moz-user-select: none;
     -ms-user-select: none;
     -o-user-select: none;
     user-select: none;
    }

    .externaltips {
     top: -5000px;
    }

    .tipContent {
     border: 1px solid #c0c0c0;
     border-bottom-right-radius: 5px;
     border-top-right-radius: 5px;
     box-shadow: 2px 2px 8px #999;
     top: -5000px;
     min-width: 50px;
     max-width: 400px;
     max-height: 400px;
     min-height: 1em;
     overflow: hidden;
     padding: 0;
     margin:0;
     position: absolute;
     font-style: normal;
     cursor: default;
     background: #fffff0;
     color: #000;
     opacity: 0;
    }

    .tbody .resizehandleY {
     position: absolute;
     background-color: transparent;
     bottom: 0;
     right: 0;
     left: 0;
     height: 4px;
     cursor: s-resize;
     overflow: hidden;
     z-index: 1000000;
    }

    .tipContent .resizehandleX {
     position: absolute;
     background-color: transparent;
     top: 1em;
     bottom: 0;
     right: 0;
     cursor: e-resize;
     width: 4px;
     z-index: 1000000;
     overflow: hidden;
    }

    .resizehandleX:hover{
      border-right: 3px dotted #999;
    }

    .resizehandleY:hover {
      border-bottom: 3px dotted #999;
    }

    .draghandle {
      position:absolute;
      left: 0;
      height: 12px;
      width: 12px;
      top: 0;
      background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMAQMAAABsu86kAAAABlBMVEVAQED///9pZpXFAAAAAXRSTlMAQObYZgAAABtJREFUCFtjYGJgYGeAAgcFhgMGIBIOgFJMDAAiwQHD+tGJEAAAAABJRU5ErkJggg==);
      background-color: transparent;
      background-position: 8px 4px;
      background-repeat: no-repeat;
      padding: 2px 10px;
    }

    .tbody.white{
     background:white !important;
    }

    .tipContent p {
     margin-top: 0.5em;
    }

    .header {
     text-align: center;
     padding: 2px 5px;
     background-color: #5d5e93;
     color: #fff;
     display: block;
     border-top-right-radius: 5px;
     border-bottom: 1px solid #fff;
     white-space: nowrap;
     overflow: hidden;
     text-overflow: ellipsis;
    }

    .header.fix {
      padding: 2px 40px 2px 28px;
    }

    .dragresizebox {
      /* [!important] to prevent inheritance from parent */
      background: #FFFFF0;
      opacity: 0.2 !important;
      position: absolute;
      cursor: move;
      border: 2px dotted #000 !important;
      border-bottom-right-radius: 5px;
      padding: 0 !important;
      margin: 0 !important;
      -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity:20)";
      filter: alpha(opacity=20); /* IE7 and under */
    }

    .fixedcloser {
     margin: 0 4px 0 15px;
     background: transparent url(http://testbed.nicon.nl/tooltips2.0/fixed.png) no-repeat right center;
     position:absolute;
     right: 1px;
     top: 4px;
     width: 12px;
     height: 12px;
     cursor: pointer;
     cursor: hand;
    }

    .fixedcloser.hastooltip,
    .draghandle.hastooltip{
      border-bottom: none !important;
      margin-bottom: 0;
      cursor: pointer;
      cursor: hand;
    }

    .fixedcloser:hover {
      background-image: url(http://testbed.nicon.nl/tooltips2.0/closefixed.png);
    }

    .tbody {
     overflow-y: auto !important;
     overflow-x: hidden;
     height: auto;
     max-height: 375px;
     min-height: 1em;
     padding: 2px 6px 4px 6px;
     font-style: normal;
     font-size: 0.9em;
     line-height: 1.3em;
     display: block !important;
     margin:0 0 0 -1px;
     white-space: normal;
     border-bottom-right-radius: 5px;
     border-top-right-radius: 5px;
    }

    .resize {
     -webkit-transform: translate(2em) translate(-1em) ;
     -webkit-transition: all 1s ease-in-out;
    }

    .fadein {
      opacity: 1;
      -moz-transition: opacity 0.2s ease-in-out;
      -webkit-transition: opacity 0.3s ease-in-out;
      transition: opacity 0.3s ease-in-out;
    }

    .fadeout {
      opacity: 0;
      -moz-transition: opacity 0.2s ease-in-out;
      -webkit-transition: opacity 0.3s ease-in-out;
      transition: opacity 0.3s ease-in-out;

    }

    .hastooltip, .ttdemo {
     cursor: default;
     border-bottom: 1px solid #000 !important;
     /*IE compensate for the border*/
     margin-bottom: -1px;
    }

    a.hastooltip {
     cursor:pointer;
     cursor:hand;
    }

    .hastooltip:hover {
     color: red;
     border-color: transparent !important;
    }

    .triangledown{
     width: 0;
     height: 0;
     border-left: 6px solid transparent;
     border-right: 6px solid transparent;
     border-top: 6px solid #fff;
     display: inline-block;
     position: absolute;
     cursor: pointer;
     cursor: hand;
     top: 8px;
     right: 18px;
    }

    .triangleup{
     width: 0;
     height: 0;
     border-left: 6px solid transparent;
     border-right: 6px solid transparent;
     border-bottom: 6px solid #fff;
     display: inline-block;
     position: absolute;
     cursor: pointer;
     cursor: hand;
     top: 7px;
     right: 18px;
    }