SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    23,598
    Mentioned
    411 Post(s)
    Tagged
    6 Thread(s)

    Calculating margins

    I saw a question elsewhere that got me thinking about doing this in JS: have a div on screen that always has twice as much margin on the right as on the left (so the div is always "off center", so to speak). To my amazement, I managed to put together some code that seems to do the job, though I'll bet there are much better ways to do this. So, as a learning exercise, I was wondering if anyone can demonstrate how this code could be improved or made more robust. (I tested it on all the latest Mac browsers, but didn't bother with IE, so I don't know if it works there or not.)

    Here's a live example: http://cdpn.io/LIizc

    Code javascript:
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
     
    <style media="all">
    body {margin: 0; padding: 0;}
    div {width: 600px; height: 600px; background: red; }
     
    </style>
     
    </head>
    <body>
     
    <div id="test"></div>
     
    <script>
    function resize() 
    {
        var div = document.getElementById("test");
        var windowWidth  = document.documentElement.clientWidth;
        var remainder = windowWidth - div.clientWidth;
        div.style.marginRight = remainder * 2/3 + "px";
        div.style.marginLeft = remainder * 1/3 + "px";
    }
    window.onresize = resize;
    resize();
    </script>
    </body>
    </html>

  2. #2
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,313
    Mentioned
    178 Post(s)
    Tagged
    8 Thread(s)
    Hi Ralph,

    Two things that occurred to me:
    1. Do you need to set both the left and the right margin? I think setting just the left would have the same effect.
    2. I would move the assignment of the div variable out of the function. That way you avoid querying the DOM every time the onresize event fires.
    That would leave you with this:

    Code JavaScript:
    function resize(){
      var windowWidth  = document.documentElement.clientWidth,
          remainder = windowWidth - div.clientWidth;
      div.style.marginLeft = remainder * 1/3 + "px";
    }
     
    var div = document.getElementById("test");
    window.onresize = resize;
    resize();

    If you wanted to make this more generic, you could pass in a reference to the element that needs repositioning:

    Code JavaScript:
    function resize(elem){
      var windowWidth  = document.documentElement.clientWidth,
          remainder = windowWidth - elem.clientWidth;
      elem.style.marginLeft = remainder * 1/3 + "px";
    }
     
    var div = document.getElementById("test");
    window.addEventListener('resize', function(){
      resize(div);
    });
    resize();

    If you were to do this with jQuery:

    Code JavaScript:
    jQuery.fn.resize = function () {
      this.css("margin-left", ( $(window).width() - this.width() ) * 1/3 + "px");
      return this;
    }  
     
    var $div = $("#test");
    $(window).on("resize", function(){
      $div.resize();
    });
    $div.resize();

    I quite like the $div.resize(); syntax. But this alone wouldn't be a reason to include jQuery.

    Hope that helps.

  3. #3
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    23,598
    Mentioned
    411 Post(s)
    Tagged
    6 Thread(s)
    Thanks Pullo. I really appreciate the reply.

    Quote Originally Posted by Pullo View Post
    Do you need to set both the left and the right margin?
    D'uh, how obvious! That's embarrassing.

    I would move the assignment of the div variable out of the function. That way you avoid querying the DOM every time the onresize event fires.
    Ah yes, I do need reminders about things like that.

    There generic options are definitely preferable. I still find it hard to think in those terms, but these examples are great for getting the hang of them. Presumably the second option needs to end with resize(div); rather than just resize();?

    It's always nice to see how it's done in jQuery, too.

    It's really satisfying to learn from simple examples like this, so I hope you don't mind me peppering you with them. I've been looking at books for a while now, but TBH, I can barely stand to open their pages now. It's a lot more fun just to pick a simple task, try work out how it's done, and then ask a question like this.

  4. #4
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,313
    Mentioned
    178 Post(s)
    Tagged
    8 Thread(s)
    Hey, no probs

    Quote Originally Posted by ralph.m View Post
    Presumably the second option needs to end with resize(div); rather than just resize();?
    Oh yes, well spotted.

    Quote Originally Posted by ralph.m View Post
    It's always nice to see how it's done in jQuery, too.
    Yeah, I quite like the jQuery syntax.
    Here's another nice snippet in a similar vein which centres an element in the middle of the screen.

    Code JavaScript:
    jQuery.fn.center = function () {
      this.css("position","absolute");
      this.css("top", ( $(window).height() - this.height() ) / 2+$(window).scrollTop() + "px");
      this.css("left", ( $(window).width() - this.width() ) / 2+$(window).scrollLeft() + "px");
      return this;
    }  
     
    $("#myDiv").center();

    Quote Originally Posted by ralph.m View Post
    It's really satisfying to learn from simple examples like this, so I hope you don't mind me peppering you with them.
    Absolutely not.

    Quote Originally Posted by ralph.m View Post
    It's a lot more fun just to pick a simple task, try work out how it's done, and then ask a question like this.
    That's exactly how I feel, then, as you start improving, you can start answering questions along the way to consolidate what you have already learnt.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •