3

I am seeing a strange issue with mouse position in a page on my web application. I thought the position of a particular element on the page will be the same irrespective of the browser it is rendered in. I was hoping to use the position values from the client with some screen capturing functionality executed on the server.

However what I am seeing is that every time when I select a part of the page, ​the top and left position ​changes with respect to the browser. I have tested the top and left of the browser by using several JavaScript properties, but the left and top for a fixed position seems to be different for different browsers (difference of a few pixels).

// Detect if the browser is IE or not.
// If it is not IE, we assume that the browser is NS.
var IE = document.all ? true : false;

// If NS -- that is, !IE -- then set up for mouse capture
if (!IE) document.captureEvents(Event.MOUSEMOVE);

// Set-up to use getMouseXY function onMouseMove
document.onmousemove = getMouseXY;

// Temporary variables to hold mouse x-y pos.s
var tempX = 0;
var tempY = 0;

// Main function to retrieve mouse x-y pos.s

function getMouseXY(e) {
    if (!e) e = window.event;
    if (e.pageX || e.pageY) {
        tempX = e.pageX;
        tempY = e.pageY;
    } else if (e.clientX || e.clientY) {
        tempX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        tempY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }
    // catch possible negative values in NS4
    if (tempX < 0) {
        tempX = 0;
    }
    if (tempY < 0) {
        tempY = 0;
    }
    // show the position values in the form named Show
    // in the text fields named MouseX and MouseY

    document.Show.clientX.value = e.clientX;
    document.Show.clientY.value = e.clientY;
    document.Show.pageX.value = e.pageX;
    document.Show.pageY.value = e.pageY;
    document.Show.scrollLeft.value = document.body.scrollLeft;
    document.Show.scrollTop.value = document.body.scrollTop;

    document.Show.MouseX.value = tempX;
    document.Show.MouseY.value = tempY;
    return true;
}
html {
    font-family:arial;
    font-size:12px;
    margin:0px;
    padding:0px;
}
<body>
    <br/>
    <br/>
    <br/>
    <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="cursor:pointer;background:red;">.</span>

    <div style="position:absolute;top:200px;left:200px;width:800px;height:800px;">
        <form name="Show">
            <input type="text" name="clientX" value="0" size="8">e.clientX
            <br>
            <input type="text" name="clientY" value="0" size="8">e.clientY
            <br>
            <input type="text" name="pageX" value="0" size="8">e.pageX
            <br>
            <input type="text" name="pageY" value="0" size="8">e.pageY
            <br>
            <input type="text" name="scrollLeft" value="0" size="8">scrollLeft
            <br>
            <input type="text" name="scrollTop" value="0" size="8">scrollTop
            <br>
            <input type="text" name="MouseX" value="0" size="8">Left
            <br>
            <input type="text" name="MouseY" value="0" size="8">Top
            <br>
        </form>
    </div>
</body>

Please look at the mouse top and left returned when you hover over the red box in various browsers.

Why are different browsers returning different top/left values? I need this to be returning same values for all browsers. It would be great if some one can provide insight into this behaviour and suggest ways in which I can circumvent this issue. Thanks in advance.

dev.bv
  • 980
  • 9
  • 16
Alley
  • 31
  • 2

3 Answers3

1

You need to reset your css always to avoid this issue, as known, each browser has its own margin and padding default values and you have to reset them and define your own and same default values for all browsers, in your case you need at least this:

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}

I modified your example http://jsfiddle.net/QAc5L/ by including reset.css file from http://meyerweb.com and it works perfectly in firefox and chrome.

Fares M.
  • 1,538
  • 1
  • 17
  • 18
  • Thank you so much. I see the css is working on your page. I created a complex page jsfiddle.net/bnLLm/25 with two tables to find the top and left position of the table. But the css what you have applied is not working in this page to get the top and left position. Can you please take a look at this? The actual page that I am working on, has a complex design with multiple charts and tables. Every time when I select a part of the report the top and left position changes with respect to the browser. – Alley May 20 '14 at 05:15
1

I thought the position of a particular element on the page will be the same irrespective of the browser it is rendered in

You are wrong, it can depend on the browser it is rendered on. Different browsers use different rendering engines following the same specification for rendering. So although they are supposed to look same the specification is not working to make all implementations look pixel-perfectly same. And along with this there are implementation differences as well.

There are loose ends in the specification as well, decisions left to browser developers or rendering engine developers like what should be the default size of a input field is probably not specified in any specification mainly because they are usually out of scope. So if you have an input field in the beginning of the page its size will affect everything that is coming after that in a static layout if you consider position.

If you have perfect control of the page then you can control it with css to look the exact same in all browsers. That is what css developers mean by cross-browser pixel perfect css and is quite easy. But if you cant expect this on any page in general.

With that said what you are trying to do is not clear for me, if you could explain your exact requirement may be someone could help you. Or if you can control the css of the pages you can just control the css to make it look the same everywhere.

Also make sure you mention the exact differences and name+version of browsers when you report an issue, making sure others can replicate the issue following the question.

UPDATE

I just had a look at your page. I assume you are coding the pages with tables yourself.

In the sample page you created you have a button at the top, the size of the button and the space it takes depends on the text in it, the default borders,padding,margin applied to it etc. So you can set all these values explicitly in your css or use a general reset css. Still then there can be very slight differences that may come out of font rendering used. But an easy way to circumvent this would be to set an explicit height for the element.

There is no single solution for this, its upto you to decide. Another easy way would be to set a fixed height to the div which is the parent of this button say 70px or so.

In a nutshell, you have to find out the elements thats acting different across browsers and do something about it using explicit css.

Also note that rendering engines also takes a look at your DTD specified. Right now you are using a transitional DTD

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

You should change it to strict DTD or use the HTML 5 style DTD, This will tell most browsers to behave well.

So change your DTD, use a reset css and then handpick the misbehaving elements to teach them some manners with css.

sabithpocker
  • 15,274
  • 1
  • 42
  • 75
  • Thanks Sabith. The capture functionality is as follows: User can select a part of the report by drawing a rectangle in the screen. Then it calculates the top,left,width and height of that rectangle related to that page. In server side again, it loads the page in a hidden browser and capture the region using this coordinates.The functionality works in IE8 as the hidden browser is close to IE8, but fails in other browsers. Please check the link to view the demo of my application. Please click on the "capture a region" button and drag to select the region. – Alley May 21 '14 at 15:48
0

As every browser has their own unique settings, it affects on page, like padding, margin will affects of page design, if you want to use same factors on each browsers, you need to overwrite it in your page so it will look same on each browser. You can try following css to overwrite your browser style. Following css will also supports for html5 tags

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}
Laxmikant Dange
  • 7,606
  • 6
  • 40
  • 65