title: Chrome gives wrong element width
body: <p>I'm making a tooltip class in Mootools that depends on getting the width of the tooltip element to centre it over the target. </p>
  
  <p>It works nicely in all browsers except Chrome, which comes up with two wildly different numbers for the element width on each reload of the page. When I set a width of 100 and height 20 in the CSS, the Chrome web dev inspector shows the dimensions correctly. But when I refresh the page Chrome logs out a mad figure like 1904, and my element is positioned far away to the side.</p>
  
  <p>I've tried using these different ways of getting the width, either hiding the tooltip with display:none or z-index:</p>
  
  <ul>
  <li>getDimensions()</li>
  <li>getSize()</li>
  <li>getStyle('width')</li>
  <li>element.offsetWidth</li>
  </ul>
  
  <p>all with similar results. Can any kind person suggest a workaround, or tell me why Chrome is behaving in this way?</p>
  
  <p>Thanks!
  Fred</p>
  
  <p>Here's my JS:</p>
  
  <pre><code>Tooltip = new Class({
  
      Implements: Events,
      Implements: Options,
  
      options: {
          target: '',                                 // Single element or array of elements
          tip: ''                                     // Element to show          
      },
  
      initialize: function(options) {
          this.setOptions(options);
          this.setValues();
          this.attachEvents();
      },
  
      setValues: function() {     
          this.target = this.options.target;
          this.tip = this.options.tip;
          this.tip.setStyle('z-index', -1);                                                   // Hide tip element
          if (this.target == null || this.tip == null) return;                    // We don't have required elements, so return
          this.showing = false;
          this.tipMousedOver = false;
          this.tipDimensions = this.tip.getSize();            // Getting width
          console.log(this.tip);
          console.log(this.tipDimensions.x);
          console.log(this.tip.offsetWidth);
  
          this.tipFx = new Fx.Morph(this.tip, {
              duration: 350,
              transition: Fx.Transitions.Sine.easeIn,
              link: 'cancel',
              onComplete: function() {
                  if (this.showing) this.showing = false;
                  else this.showing = true;
              }.bind(this)
          });
      },
  
      attachEvents: function() {
  
          this.tip.addEvent('mouseenter', function(e) {
              this.tipMousedOver = true;
              document.removeEvents('click');
          }.bind(this));
  
          this.tip.addEvent('mouseleave', function(e) {
              document.addEvent('click', this.bodyClick.bind(this));  
          }.bind(this));
  
          if (typeOf(this.target) == 'element') {
              this.target.addEvent('click', this.toggleTip.bind(this));
          } else {
              this.target.each(function(item, index){
                  item.addEvent('click', this.toggleTip.bind(this));
              }.bind(this));
          }
  
      },
  
      toggleTip: function(e) {
          e.stopPropagation();
          if (!this.showing) {
              // HIdden, so show
              var posn = e.target.getPosition();
              var vPosn = posn.y;
              var hPosn = posn.x;
              var targetWidth = e.target.getSize().x;
              this.tip.setStyle('z-index', 1);
              this.tip.setStyle('top', vPosn - (this.tipDimensions.y + 10));
              this.tip.setStyle('left', (hPosn + targetWidth /2) - (this.tipDimensions.x / 2));       // Positions middle of tip over middle of target
              console.log('targetWidth: ' + targetWidth + ' tipDimensions.x: ' + this.tipDimensions.x);
              this.tipFx.start({'opacity': [0, 1]});
              document.addEvent('click', this.bodyClick.bind(this));
          } else {
              // Visible, so hide
              if (!this.tipMousedOver) {
                  this.tipFx.start({'opacity': 0});
                  this.tip.setStyle('z-index', 1);
                  document.removeEvent('click', this.bodyClick);
              }       
          }
      },
  
      bodyClick: function(e) {
          this.tipFx.start({'opacity': 0});
          this.tip.setStyle('z-index', 1);
          document.removeEvents('click', this.bodyClick);
      }
  
  });
  
  
  
  window.addEvent('domready', function(){
  
      new Tooltip({
          target: $('comments-list').getElements('.shareLink'),
          tip: $('shareTip')
      });
  
  });
  </code></pre>
  
  <p>HTML:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
  &lt;head&gt;
  
      &lt;script src="js/mootools-core-1.3.2-full-compat.js"&gt;&lt;/script&gt;
      &lt;script src="js/mootools-more-1.3.2.1.js"&gt;&lt;/script&gt;
  
  &lt;script src="comments_new_click.js"&gt;&lt;/script&gt;
  
  &lt;link href="comments_new.css" type="text/css" rel="stylesheet"&gt;
  &lt;/head&gt;
  &lt;body&gt;
  
      &lt;ul id="comments-list"&gt;
          &lt;!-- START COMMENT ITEM --&gt;
          &lt;li id="CommentKey-f8b1-45f2-b4f6-68ba740ca9c3" class="commentItem"&gt;
                  &lt;div class="commentTop clrd"&gt;
                      &lt;span class="badges"&gt;
                          &lt;img style="width: 32px; height: 32px;" src="" alt="" title=""&gt;
                          &lt;img style="width: 32px; height: 32px;" src="" alt="" title=""&gt;
                      &lt;/span&gt;
                      &lt;a class="avatar" href="javascript:;" title=""&gt;
                          &lt;img src="" alt="Photo of editor1"&gt;
                      &lt;/a&gt;                
                      &lt;a class="username" href="javascript:;" title=""&gt;And Finally&lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="commentBody clrd"&gt;
  
                      &lt;div class="commentOver"&gt;
                          &lt;div class="submDateAndTime"&gt;26 April 2011&lt;/div&gt;
                      &lt;/div&gt;                  
  
                      &lt;div class="commentSide"&gt;
                          &lt;div class="likeDislike"&gt;
                              &lt;a class="pluck-like alreadyvoted" href="javascript:;" title=""&gt;Like&lt;/a&gt;
                              &lt;span class="pluck-score"&gt;00000&lt;/span&gt;
                              &lt;a class="pluck-dislike" href="javascript:;" title=""&gt;Dislike&lt;/a&gt; 
                          &lt;/div&gt;
                      &lt;/div&gt;                  
  
                      &lt;div class="commentText"&gt;
                          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur a sapien vitae enim sagittis sodales at sit amet leo. Aenean cursus euismod blandit. Suspendisse potenti. Pellentesque vestibulum nisi id dui aliquet consequat. Nulla egestas tortor vel metus dapibus luctus. Nullam rhoncus ullamcorper lorem, non vehicula nulla euismod viverra. Morbi tempus dui ut ipsum interdum ut dapibus est venenatis. 
                      &lt;/div&gt;
  
                  &lt;/div&gt;
                  &lt;div class="commentBottom clrd"&gt;
  
                      &lt;div class="getReplies"&gt;
                          &lt;a href="javascript:;" title="Show replies to this comment"&gt;See Replies&lt;/a&gt;
                          &lt;span&gt;2&lt;/span&gt;
                      &lt;/div&gt;
  
                      &lt;!-- To delete --&gt;
                      &lt;div style="display:block;clear:both;float:none;height:0"&gt;&lt;/div&gt;
  
                  &lt;/div&gt;
  
                  &lt;!-- REPLIES --&gt;
                  &lt;div id="nestedcommentslist-CommentKey:f8b1-45f2-b4f6-68ba740ca9c3" class="repliesWrapper"&gt;&lt;/div&gt;
                  &lt;!-- END REPLIES --&gt;
  
          &lt;/li&gt;
          &lt;!-- END COMMENT ITEM --&gt;
                  &lt;!-- START COMMENT ITEM --&gt;
          &lt;li id="CommentKey-f8b1-45f2-b4f6-68ba740ca9c3" class="commentItem"&gt;
                  &lt;div class="commentTop clrd"&gt;
                      &lt;span class="badges"&gt;
                          &lt;img style="width: 32px; height: 32px;" src="http://z.x.co.uk/ver1.0/Content/images/store/5/6/3262-4af5-8654-ef59a25b24e1.Full.png" alt="" title=""&gt;
                          &lt;img style="width: 32px; height: 32px;" src="http://z.x.co.uk/ver1.0/Content/images/store/5/6/3262-4af5-8654-ef59a25b24e1.Full.png" alt="" title=""&gt;
                      &lt;/span&gt;
                      &lt;a class="avatar" href="javascript:;" title=""&gt;
                          &lt;img src="http://z.x.co.uk/ver1.0/Content/images/store/13/3/f175-45b8-931b-28619aadfd2a.Small.png" alt="Photo of editor1"&gt;
                      &lt;/a&gt;                
                      &lt;a class="username" href="javascript:;" title=""&gt;And Finally&lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="commentBody clrd"&gt;
  
                      &lt;div class="commentOver"&gt;
                          &lt;div class="submDateAndTime"&gt;26 April 2011&lt;/div&gt;
                      &lt;/div&gt;                      
  
                      &lt;div class="commentText"&gt;
                          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur a sapien vitae enim sagittis sodales at sit amet leo. Aenean cursus euismod blandit. Suspendisse potenti. Pellentesque vestibulum nisi id dui aliquet consequat. 
                      &lt;/div&gt;
  
                  &lt;/div&gt;
                  &lt;div class="commentBottom clrd"&gt;
  
                          &lt;div class="getReplies"&gt;
                              &lt;a href="javascript:;" title="Show replies to this comment"&gt;See Replies&lt;/a&gt;
                              &lt;span&gt;2&lt;/span&gt;
                          &lt;/div&gt;
  
                          &lt;div class="share"&gt;
                              &lt;a href="javascript:;" class="abuse" title=""&gt;Report abuse&lt;/a&gt;
                              &lt;a href="javascript:;" class="shareLink" title=""&gt;Share&lt;/a&gt;
                          &lt;/div&gt;
  
                          &lt;!-- To delete --&gt;
                          &lt;div style="display:block;clear:both;float:none;height:0"&gt;&lt;/div&gt;
  
                  &lt;/div&gt;
                  &lt;!-- REPLIES --&gt;
                  &lt;div id="nestedcommentslist-CommentKey:f8b1-45f2-b4f6-68ba740ca9c3" class="repliesWrapper"&gt;&lt;/div&gt;
                  &lt;!-- END REPLIES --&gt;
  
          &lt;/li&gt;
          &lt;!-- END COMMENT ITEM --&gt;
      &lt;/ul&gt;
  
      &lt;div id="shareTip" class="popup"&gt;Share and things&lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>CSS:</p>
  
  <pre><code>body {
    font-family: Arial,Helvetica,sans-serif;
    font-size: 62.5%;
  }
  
  #comments-list {
      width: 480px;
      margin: 20px auto;
      border: 1px solid #ccc;
      list-style-type: none;
      padding: 0;
  }
  
  .commentItem {
      margin-left: 0;
      padding-left: 0;
      font-size: 13px;
  }
  
  .avatar {
      margin-right: 5px;
  }
  
  .avatar img {
      width: 45px;
      height: 45px;
  }
  
  .commentTop {
      position: relative;
      padding: 5px;
      min-height: 48px;
      background: #e8e8eb;
  }
  
  .username {
      position: absolute;
      top: 5px;
      height: 1em;
      font-size: 14px;
      text-decoration: none;
  }
  
  .badges {
      float: right;
  }
  
  .badges img {
      margin-left: 2px;
  }
  
  .commentBody {
      padding: 5px;
      background: #f3f2f2;
  }
  
  .commentText {
      margin-right: 75px;
      line-height: 16px;
  }
  
  .commentOver {
      clear: both;
      float: none;
      height: 14px;
      padding: 0 3px 10px 0;
  }
  
  .submDateAndTime {
      float: left;
      color: #777;
      font-size: 11px;
  }
  
  .getReplies {
      float: left;
      padding: 0;
  }
  
  .getReplies a {
      background-color: #ED9430; /* Put elsewhere */
    background-image: url("http://z.x.co.uk/images/comments-wide.png");
    background-position: -508px -245px;
    background-repeat: no-repeat;
    display: block;
    float: left;
    height: 20px;
    text-indent: -9999px;
    width: 60px;
  }
  
  .getReplies span {
    background-image: url("http://z.x.co.uk/images/comments-wide.png");
    background-position: -569px -245px;
    background-repeat: no-repeat;
    display: block;
    float: left;
    font-size: 14px;
    font-weight: bold;
    height: 21px;
    padding-left: 2px;
    text-align: center;
    width: 41px;
    line-height: 19px;
  }
  
  .commentBottom {
      padding: 5px;
      background: #f3f2f2;
  }
  
  .share {
      float: right;
  }
  
  .popup {
      position: absolute;
      border: 1px solid #ccc;
      padding: 10px;
      background: #fff;
      z-index: 1;
  }
  
  .hidden {
      display: none;
  }
  
  #shareTip {
      width: 100px;
      height: 20px;
      overflow: hidden;
  }
  </code></pre>
  
  <p>=======================================</p>
  
  <h1>LATER</h1>
  
  <p>For anyone else coming across a similar problem, I found it went away when I measured the tip element right before showing it, instead of when the object's initialised. So I changed my reveal method to:</p>
  
  <pre><code>toggleTip: function(e) {
      e.stopPropagation();
      if (!this.showing) {
          // HIdden, so show
          var posn = e.target.getPosition();
          var targetPosnY = posn.y;
          var targetPosnX = posn.x;
          var targetWidth = e.target.getSize().x;
          var targetHeight = e.target.getSize().y;
          var tipSize = this.tip.getSize();
          var tipPosnY = targetPosnY - (tipSize.y + 10);
          var tipPosnX = targetPosnX - (targetWidth / 2);
          this.tip.setStyle('z-index', 1);
          this.tip.setPosition({x: tipPosnX, y: tipPosnY});
          this.tipFx.start({'opacity': 1});
          document.addEvent('click', this.bodyClick.bind(this));
      } else {
          // Visible, so hide
          if (!this.tipMousedOver) {
              this.tipFx.start({'opacity': 0});
              this.tip.setStyle('z-index', 1);
              document.removeEvent('click', this.bodyClick);
          }       
      }
  },
  </code></pre>
  
  <p>I also found that setPosition() is a more reliable way of positioning the element than setStyle().</p>