Center a popup window on screen?
Asked Answered
S

20

330

How can we center a popup window opened via JavaScript's window.open function on the center of screen (the exact x and y coordinates of which will depend on the current screen resolution)?

Snipe answered 1/11, 2010 at 11:16 Comment(0)
A
529

SINGLE/DUAL MONITOR FUNCTION (credit to http://www.xtf.dk - thank you!)

UPDATE: It will also work on windows that aren't maxed out to the screen's width and height now thanks to @Frost!

If you're on dual monitor, the window will center horizontally, but not vertically... use this function to account for that.

const popupCenter = ({url, title, w, h}) => {
    // Fixes dual-screen position                             Most browsers      Firefox
    const dualScreenLeft = window.screenLeft !==  undefined ? window.screenLeft : window.screenX;
    const dualScreenTop = window.screenTop !==  undefined   ? window.screenTop  : window.screenY;

    const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
    const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

    const systemZoom = width / window.screen.availWidth;
    const left = (width - w) / 2 / systemZoom + dualScreenLeft
    const top = (height - h) / 2 / systemZoom + dualScreenTop
    const newWindow = window.open(url, title, 
      `
      scrollbars=yes,
      width=${w / systemZoom}, 
      height=${h / systemZoom}, 
      top=${top}, 
      left=${left}
      `
    )

    if (window.focus) newWindow.focus();
}

Usage Example:

popupCenter({url: 'http://www.xtf.dk', title: 'xtf', w: 900, h: 500});  

CREDIT GOES TO: http://www.xtf.dk/2011/08/center-new-popup-window-even-on.html (I wanted to just link out to this page but just in case this website goes down the code is here on SO.)

Artiodactyl answered 31/5, 2013 at 15:40 Comment(21)
After some playing around, this does not work as well as I thought. The simpler, excepted answer works much better. This only works if the launching page is maximized.Boole
Why would you need it to work on minimised windows? They won't be visible?Dan
Sorry. not minimized, but smaller than full screen.Artiodactyl
Perhaps try a smaller width and height? PopupCenter('http://www.xtf.dk','xtf','200','300');Artiodactyl
Does not work for me with screens that are not the same size, and not really at all in ChromeSchumann
Does not work if you want to open a popup from iframeAland
Doesn't work on triple monitor setup, always put the window on left edge of screenIdeation
Original question posted in 2010, original solution posted in 2010. My comment on original solution about not working on dual monitor posted in 2013, my answer for dual monitor posted in 2013. Your comment about triple monitor in 2015. You now need to answer for a triple monitor solution in 2015. At this rate, we will have an answer for 5 monitors in 2020, 6 monitors in 2025, 7 monitors in 2030... let's keep this cycle going!Artiodactyl
@TonyM I have updated the answer. Yes the cycle needs to go on!Snipe
maybe for readibility: if (window.focus) { should be: if (newWindow.focus) {Farandole
@TonyM +1 solution, works for me Thanks :) in some of case like special chars in url, it would be good if encode url with encodeURI(url) or encodeURIComponent(url) as per needs.Misti
newWindow.focus() causes it to fail if multiple windows are opened. Example, I have a grid, each row has a link that calls this method. If the user neglects to close the opened window and immediately opens another link, it fails.Develop
You should use window.screenX/window.screenY instead of screen.left/screen.top for FirefoxBeleaguer
I would suggest to use window.screen instead of screen directly to avoid the error message by linter on no-restricted-globals ( @RubenStolk , @tony-m )Plosion
What's the point of checking if (window.focus)? Shouldn't you check that the new popup window has a focus method instead?Pothead
Don't be confused like I was: if you're testing this with the debugging tools open and taking up half of your screen, the calculated "top" value can go negative resulting in it pressing against the top of your screen. Close your debugging tools and it will work normally.Townsfolk
What is the point of dualScreenTop? In my experience dual screen only messes up the x-axis (or is this only because my screens are next to each other?)...Canzone
@TonyM this gives a flow error on document.documentElement.clientWidth (lack of null check) and also prompts a WebStorm fix for !== undefined instead of != undefined to prevent coercive type checking.Lavernlaverna
@TonyM also on your var width and var height declaration you're missing a window declaration. It's throwing an ESLint error for no-restricted-globals. This is the screen.width and screen.height declaration respectively.Lavernlaverna
This does not work on all screens and only works if the broswer is taking up the whole screen, I posted an answer that works for me every timeAnnulate
Despite all the complexity and the many edits, this doesn't work. The logic around computing a systemZoom level assumes that the browser window takes up the entire screen. When this assumption is violated, the function believes that we are zoomed in (equivalent to systemZoom < 1), and consequently puts the window in the wrong place - often way over on one edge of the screen if the parent window is small.Forelli
M
355

try it like this:

function popupwindow(url, title, w, h) {
  var left = (screen.width/2)-(w/2);
  var top = (screen.height/2)-(h/2);
  return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
} 
Manifestative answered 1/11, 2010 at 11:18 Comment(9)
This function doesn't work on a dual monitor setup. I've posted a single and dual monitor solution below.Artiodactyl
I would like to confirm this : var left = (screen.width/2)-(w/2); var top = (screen.height/2)-(h/2); Isn't it will return left=0 and top=0??? Assuming w is equal to screen.width and h is equal to screen.height...Am I right or wrong here?Beverleybeverlie
@Beverleybeverlie w/h refer there to the size of the popup, not the screen.Neoplasty
Thanks @Manifestative ...Also Use title blank in IE..Neither it will give errorLaos
what's wrong with your maths? (screen.width / 2) - (w / 2) = (screen.width - w) / 2 => 2 calculations instead of 3Thickset
my two pennies worth: var left=((screen.width-w)*0.5)|0, top=((screen.height-h)*0.5)|0;Jab
Doesn't center on my second monitor (which is UP from the main one). Answer for dual screen fails as well.Unpeople
This won't work if you want to center window in the middle of the browser, rather than the middle of the screen (if for example, the user has their browser resized to half size). To center within the browser replace screen.width & screen.height with window.innerWidth & window.innerHeightAntiparallel
All the boolean specs are 'no' by default, so they can be deleted.Schmuck
S
154

Due to the complexity of determining the center of the current screen in a multi-monitor setup, an easier option is to center the pop-up over the parent window. Simply pass the parent window as another parameter:

function popupWindow(url, windowName, win, w, h) {
    const y = win.top.outerHeight / 2 + win.top.screenY - ( h / 2);
    const x = win.top.outerWidth / 2 + win.top.screenX - ( w / 2);
    return win.open(url, windowName, `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${y}, left=${x}`);
}

Implementation:

popupWindow('google.com', 'test', window, 200, 100);
Scissile answered 27/8, 2015 at 23:54 Comment(6)
This seems to be the technique used by Facebook for the popup on a share button.Kangaroo
This worked perfectly for me on dual screen. Even when moving or resizing the window, it says central to the window it's opened from. This should be the accepted answer. Thanks.Comeback
I agree with @OliB -- this works perfectly and solved a recent development issue we had! Should be the accepted answer for 2019.Copra
Made a modification to extend the capabilities of this function here. It includes option to set width and height to percentage or ratio. You can also change the options with an object (easier to manage than a string)Freckly
It does not work for me. I have a 3 monitor setup. Upper left and right are standard monitors and bottom left is my laptop's. When the window is on the laptop then popup window is centered but not on any of my standard monitors.Iinde
This worked for me, but prefer to use window.top.inner(Height|Width) so that if a portion of the page is taken up by something like dev-tools that pane will be ignored and the content will centered against the web pagePreeminent
C
22

Source: http://www.nigraphic.com/blog/java-script/how-open-new-window-popup-center-screen

function PopupCenter(pageURL, title,w,h) {
  var left = (screen.width/2)-(w/2);
  var top = (screen.height/2)-(h/2);
  var targetWin = window.open (pageURL, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
  return targetWin;
} 
Chambertin answered 1/11, 2010 at 11:18 Comment(4)
Broken for users with multiple monitors. If I try this from a browser window on my right-hand monitor, it creates a popup at the left edge of that monitor, instead of in the center.Forelli
You will probably want to refer to this answer to start getting a handle on how multiple monitors can be detected in javascript: https://mcmap.net/q/100643/-testing-for-multiple-screens-with-javascriptChambertin
Alternatively, you can take a look at the answer above, which approaches the problem in a different, probably easier, manner: https://mcmap.net/q/98432/-center-a-popup-window-on-screenChambertin
I've already got my own answer at https://mcmap.net/q/98432/-center-a-popup-window-on-screen that handles multiple monitors cleanly. (Though yes, CrazyTim's approach of just centering relative to the parent window is perfectly reasonable too.)Forelli
A
20

If you want to center it on the frame you are currently in, I would recommend this function:

function popupwindow(url, title, w, h) {
    var y = window.outerHeight / 2 + window.screenY - ( h / 2)
    var x = window.outerWidth / 2 + window.screenX - ( w / 2)
    return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=' + w + ', height=' + h + ', top=' + y + ', left=' + x);
} 

Similar to Crazy Tim's answer, but doesn't use window.top. This way, it will work even if the window is embedded in an iframe from a different domain.

Aleph answered 20/1, 2016 at 16:25 Comment(1)
Yeah, CrazyTim's use of window.top struck me as a bit odd, too. I guess the one advantage(?) of his approach is that you can spawn popups from within other popups and they'll still get positioned in the center of the parent window. If you wanted to do that, for some reason...Forelli
A
13

It works very well in Firefox.
Just change the top variable to any other name and try again

        var w = 200;
        var h = 200;
        var left = Number((screen.width/2)-(w/2));
        var tops = Number((screen.height/2)-(h/2));

window.open("templates/sales/index.php?go=new_sale", '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+tops+', left='+left);
Attenuate answered 29/11, 2012 at 10:0 Comment(2)
It's totally unnecessary to do Number(...).Thrombophlebitis
This, like many other answers on this page, is broken for users with multiple monitors. If I try this from a browser window on my second monitor, it creates a popup at the left edge of my screen instead of in the center.Forelli
C
7

Facebook use the following algorithm to position their login popup window:

function PopupCenter(url, title, w, h) {
  var userAgent = navigator.userAgent,
      mobile = function() {
        return /\b(iPhone|iP[ao]d)/.test(userAgent) ||
          /\b(iP[ao]d)/.test(userAgent) ||
          /Android/i.test(userAgent) ||
          /Mobile/i.test(userAgent);
      },
      screenX = typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft,
      screenY = typeof window.screenY != 'undefined' ? window.screenY : window.screenTop,
      outerWidth = typeof window.outerWidth != 'undefined' ? window.outerWidth : document.documentElement.clientWidth,
      outerHeight = typeof window.outerHeight != 'undefined' ? window.outerHeight : document.documentElement.clientHeight - 22,
      targetWidth = mobile() ? null : w,
      targetHeight = mobile() ? null : h,
      V = screenX < 0 ? window.screen.width + screenX : screenX,
      left = parseInt(V + (outerWidth - targetWidth) / 2, 10),
      right = parseInt(screenY + (outerHeight - targetHeight) / 2.5, 10),
      features = [];
  if (targetWidth !== null) {
    features.push('width=' + targetWidth);
  }
  if (targetHeight !== null) {
    features.push('height=' + targetHeight);
  }
  features.push('left=' + left);
  features.push('top=' + right);
  features.push('scrollbars=1');

  var newWindow = window.open(url, title, features.join(','));

  if (window.focus) {
    newWindow.focus();
  }

  return newWindow;
}
Cupbearer answered 25/1, 2018 at 8:6 Comment(1)
This (somewhat complicated and unexplained) function seems to position the popup in the middle of the parent browser window, rather than the middle of the screen. That's not quite what was asked for, but okay... but there are other answers here already that position in the middle of the parent window, and they're way simpler than this. Why all the complexity?Forelli
O
6

My recommendation is to use top location 33% or 25% from remaining space, and not 50% as other examples posted here do, mainly due to the window header. This will make it look better and more comfortable to the user.

Complete code:

function OpenPopupCenter(pageURL, title, w, h) {
    var left = (screen.width - w) / 2;
    var top = (screen.height - h) / 4; /* for 25%, divide by 4. for 33%, divide by 3, etc. */
    var targetWin = window.open(pageURL, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);

    return targetWin;
}
<button onclick="OpenPopupCenter('http://www.google.com', 'TEST!?', 800, 600);">Click here</button>
Ordovician answered 9/5, 2013 at 10:15 Comment(1)
Like many, many other answers here, this is broken for multi-monitor users. If I test this out in a browser window on my right-hand monitor, the popup window appears at the left edge of that monitor, not in the center.Forelli
P
4

You can use css to do it, just give the following properties to the element to be placed in the center of the popup

element{

position:fixed;
left: 50%;
top: 50%;
-ms-transform: translate(-50%,-50%);
-moz-transform:translate(-50%,-50%);
-webkit-transform: translate(-50%,-50%);
 transform: translate(-50%,-50%);

}
Prolate answered 8/7, 2015 at 9:53 Comment(2)
"position: sticky" will likely produce better results when you start trying to tweak margins, size, and overall behavior.Naresh
This has no bearing at all on the question asked, which was about window.open popup windows, not about modals. There's no way CSS is in any way relevant here.Forelli
M
4

My version with ES6 JavaScript.
Works well on Chrome and Chromium with dual screen setup.

function openCenteredWindow({url, width, height}) {
    const pos = {
        x: (screen.width / 2) - (width / 2),
        y: (screen.height/2) - (height / 2)
    };

    const features = `width=${width} height=${height} left=${pos.x} top=${pos.y}`;

    return window.open(url, '_blank', features);
}

Example

openCenteredWindow({
    url: 'https://stackoverflow.com/', 
    width: 500, 
    height: 600
}).focus();
Mosier answered 14/5, 2019 at 17:17 Comment(2)
works perfect in 2022Francyne
Like many other answers on this page, this doesn't work on a multi-monitor setup if the browser you are triggering the popup from is not the leftmost & topmost screen. I just tried it and the popup appears at the left edge of my monitor.Forelli
M
3

Here is an alternate version of the aforementioned solution...

const openPopupCenter = (url, title, w, h) => {
  const getSpecs = (w, h, top, left) => {
    return `scrollbars=yes, width=${w}, height=${h}, top=${top}, left=${left}`;
  };

  const getFirstNumber = (potentialNumbers) => {
    for(let i = 0; i < potentialNumbers.length; i++) {
      const value = potentialNumbers[i];

      if (typeof value === 'number') {
        return value;
      }
    }
  };

  // Fixes dual-screen position
  // Most browsers use window.screenLeft
  // Firefox uses screen.left
  const dualScreenLeft = getFirstNumber([window.screenLeft, screen.left]);
  const dualScreenTop = getFirstNumber([window.screenTop, screen.top]);
  const width = getFirstNumber([window.innerWidth, document.documentElement.clientWidth, screen.width]);
  const height = getFirstNumber([window.innerHeight, document.documentElement.clientHeight, screen.height]);
  const left = ((width / 2) - (w / 2)) + dualScreenLeft;
  const top = ((height / 2) - (h / 2)) + dualScreenTop;
  const newWindow = window.open(url, title, getSpecs(w, h, top, left));

  // Puts focus on the newWindow
  if (window.focus) {
    newWindow.focus();
  }

  return newWindow;
}
Mall answered 19/4, 2016 at 15:42 Comment(2)
This... isn't as broken as some other answers on this page, but it's still a bit confused. It (at least when used in any modern browser) opens a popup at the center of the parent browser window, not the center of the screen. But... maybe it used to do something different in old versions of Firefox? The screen.left property in Firefox isn't just a Firefox version of window.screenLeft; they're the coordinates of fundamentally different things (left screen edge and left window edge, respectively). The comment hints the author believed the two equivalent, but they aren't!Forelli
(Also, a minor grumble: I have no idea which "aforementioned solution" is referenced by the first line of this answer and so dunno which elements of this solution came from where!)Forelli
F
3

(this was posted in 2020)

An extension to CrazyTim's answer

You can also set the width to a percentage (or a ratio) for a dynamic size. Absolute size is still accepted.

function popupWindow(url, title, w='75%', h='16:9', opts){
    // sort options
    let options = [];
    if(typeof opts === 'object'){
        Object.keys(opts).forEach(function(value, key){
            if(value === true){value = 'yes';}else if(value === false){value = 'no';}
            options.push(`${key}=${value}`);
        });
        if(options.length){options = ','+options.join(',');}
        else{options = '';}
    }else if(Array.isArray(opts)){
        options = ','+opts.join(',');
    }else if(typeof opts === 'string'){
        options = ','+opts;
    }else{options = '';}

    // add most vars to local object (to shorten names)
    let size = {w: w, h: h};
    let win = {w: {i: window.top.innerWidth, o: window.top.outerWidth}, h: {i: window.top.innerHeight, o: window.top.outerHeight}, x: window.top.screenX || window.top.screenLeft, y: window.top.screenY || window.top.screenTop}

    // set window size if percent
    if(typeof size.w === 'string' && size.w.endsWith('%')){size.w = Number(size.w.replace(/%$/, ''))*win.w.o/100;}
    if(typeof size.h === 'string' && size.h.endsWith('%')){size.h = Number(size.h.replace(/%$/, ''))*win.h.o/100;}

    // set window size if ratio
    if(typeof size.w === 'string' && size.w.includes(':')){
        size.w = size.w.split(':', 2);
        if(win.w.o < win.h.o){
            // if height is bigger than width, reverse ratio
            size.w = Number(size.h)*Number(size.w[1])/Number(size.w[0]);
        }else{size.w = Number(size.h)*Number(size.w[0])/Number(size.w[1]);}
    }
    if(typeof size.h === 'string' && size.h.includes(':')){
        size.h = size.h.split(':', 2);
        if(win.w.o < win.h.o){
            // if height is bigger than width, reverse ratio
            size.h = Number(size.w)*Number(size.h[0])/Number(size.h[1]);
        }else{size.h = Number(size.w)*Number(size.h[1])/Number(size.h[0]);}
    }

    // force window size to type number
    if(typeof size.w === 'string'){size.w = Number(size.w);}
    if(typeof size.h === 'string'){size.h = Number(size.h);}

    // keep popup window within padding of window size
    if(size.w > win.w.i-50){size.w = win.w.i-50;}
    if(size.h > win.h.i-50){size.h = win.h.i-50;}

    // do math
    const x = win.w.o / 2 + win.x - (size.w / 2);
    const y = win.h.o / 2 + win.y - (size.h / 2);
    return window.open(url, title, `width=${size.w},height=${size.h},left=${x},top=${y}${options}`);
}

usage:

// width and height are optional (defaults: width = '75%' height = '16:9')
popupWindow('https://www.google.com', 'Title', '75%', '16:9', {/* options (optional) */});

// options can be an object, array, or string

// example: object (only in object, true/false get replaced with 'yes'/'no')
const options = {scrollbars: false, resizable: true};

// example: array
const options = ['scrollbars=no', 'resizable=yes'];

// example: string (same as window.open() string)
const options = 'scrollbars=no,resizable=yes';
Freckly answered 16/4, 2020 at 18:54 Comment(1)
I don't see the value of this answer; compared to CrazyTim's answer, this one is just adding a bunch of arbitrary extra functionality about sizing the popup window that ultimately isn't relevant to the question asked. (It's also pretty long and not trivial to make sense of, such that even if I did for some reason want any of this functionality, making sense of the function here and assuring myself it's bug-free would probably take me longer than just rolling my own logic to compute a percentage width or whatever.)Forelli
A
1

The accepted solution does not work unless the browser takes up the full screen,

This seems to always work

  const popupCenterScreen = (url, title, w, h, focus) => {
    const top = (screen.height - h) / 4, left = (screen.width - w) / 2;
    const popup = window.open(url, title, `scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`);
    if (focus === true && window.focus) popup.focus();
    return popup;
  }

Impl:

some.function.call({data: ''})
    .then(result =>
     popupCenterScreen(
         result.data.url,
         result.data.title, 
         result.data.width, 
         result.data.height, 
         true));
Annulate answered 15/1, 2021 at 16:4 Comment(1)
Broken for users with multi-monitor setups. If I try this on my right monitor, the popup appears at the left edge of the screen instead of in the center.Forelli
G
0
function fnPopUpWindow(pageId) {
     popupwindow("hellowWorld.php?id="+pageId, "printViewer", "500", "300");
}

function popupwindow(url, title, w, h) {
    var left = Math.round((screen.width/2)-(w/2));
    var top = Math.round((screen.height/2)-(h/2));
    return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, '
            + 'menubar=no, scrollbars=yes, resizable=no, copyhistory=no, width=' + w 
            + ', height=' + h + ', top=' + top + ', left=' + left);
}
<a href="javascript:void(0);" onclick="fnPopUpWindow('10');">Print Me</a>

Note: you have to use Math.round for getting the exact integer of width and height.

Gaulin answered 3/5, 2015 at 12:29 Comment(1)
Like the majority of answers here, this is broken for users with multiple monitors. If I try this out from a browser open on my right-hand monitor, the popup appears at the left edge of the screen instead of in the center.Forelli
P
0

This hybrid solution worked for me, both on single and dual screen setup

function popupCenter (url, title, w, h) {
    // Fixes dual-screen position                              Most browsers      Firefox
    const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX;
    const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY;
    const left = (window.screen.width/2)-(w/2) + dualScreenLeft;
    const top = (window.screen.height/2)-(h/2) + dualScreenTop;
    return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
}
Peeling answered 22/2, 2019 at 11:54 Comment(1)
Nope, this is broken. The logic here assumes that window.screenLeft and window.screenTop give the coordinates of the top-left corner of the screen (relative to the left edge of the leftmost screen and the top edge of the topmost screen) but in fact they give the coordinates of the top-left corner of the browser window (again relative to the leftmost/topmost screen). The result is that if you try this with a non-maximised browser, the popup appears in wildly different places depending upon the parent window position, and isn't in the center of anything.Forelli
F
0

The following approach will work in multi-monitor environments and/or when the browser window that the popup is triggered from is not maximised. It also adjusts the vertical position to account for the height of the address bar.

function centeredPopup(url, width, height) {
    const topBarHeight = (outerHeight - innerHeight);
    const top = screen.availTop + screen.availHeight / 2 - height / 2 - topBarHeight / 2;
    const left = screen.availLeft + screen.availWidth / 2 - width / 2;
    window.open(url, "_blank", `popup=true, width=${width}, height=${height}, top=${top}, left=${left}`);
}

Explanation and lots of caveats

Other answers on this page fail in multi-monitor environments when the browser window from which the popup is triggered is not on the primary monitor. Browsers will only let you spawn a popup on the same screen as the monitor that the triggering window is on, but the top and left arguments to window.open express the coordinates of the popup in the entire combined area of all screens, treated as a single giant 2D space. When computing the coordinates for the popup, then, we need to compute how far it should be from the top-left of the current screen and then add on to that the coordinates of the top-left of the current screen, which we approximately get with screen.availTop and screen.availLeft.

(Some other answers use window.screenLeft and window.screenTop for this, but this is wildly wrong; these properties give the coordinates of the top-left of the browser window relative to the top-left of the primary screen, but the browser window might not be maximised and therefore its top-left corner could be at any point on the current screen.)

A nuance is that availLeft, availTop, availWidth, and availHeight give the top-left corner and size of the "available" region of the current screen. This region is what remains after you exclude any OS bars that windows aren't allowed to overlap, like the taskbar (if pinned) in Windows or the dock in Ubuntu. The center of this region won't necessarily be exactly identical to the true center of the screen but should be close (and may be what your users would prefer anyway). Positioning in a window in the true center of the screen while supporting multiple monitors is hard (but see the end of the answer for possible tweaks to kinda do so).

The availTop and availLeft properties of screen used above are not standardized - but will nonetheless work in all browsers according to MDN.

Another nuance not accounted for by other answers is the height of the bits of the browser window that are above (or below) the page frame, like the URL bar. The height argument to window.open just specifies the size of the frame within the browser window that the page will render it, and is not inclusive of the URL bar; the true height of the popup window will therefore be greater than this. Failing to account for this results in popups being rendered below the center of the screen. We attempt to account for this here by computing the height of these bars in the current window (by subtracting window.innerHeight from window.outerHeight) and then blindly assuming that their height will be the same in the popup. This is actually probably an overcorrection most of the time, since popup windows have a tweaked UI with a smaller address bar (at least in Chrome on my machine), but overcorrecting for the address bar size at least leads to us positioning the popup above the center of the screen instead of below, which looks nicer.

Possible tweaks

To really position in the center of the screen and not the "available" region...

If for some reason you are particular about truly wanting to put the popup in the center of the screen, I see some possible tactics you could use, but they all have horrible downsides which is why I do not recommend them above.

One way would be to call getScreenDetails and then use the top, left, height, and width properties of the currentScreen instead of screen.availTop, screen.availLeft, screen.availHeight, screen.availWidth. However, getScreenDetails is not currently available in Firefox and requires the user to grant the website a scary-sounding permission to "Manage windows on all your displays" on Chrome. I imagine that for approximately 100% of developers these drawbacks make this alternative a non-option, and grossly worse than just using the screen.availXXX properties.

If you'd like to at least get the positioning exact sometimes, you could check if screen.isExtended === false, and if so, position the popup relative to screen origin (0, 0) (instead of (screen.availLeft, screen.availTop)) and height/width screen.height and screen.width (instead of screen.availWidth and screen.availHeight). If screen.isExtended is true or undefined, you'd fall back to the logic at the start of my answer. screen.isExtended isn't available in some browsers (e.g. Firefox) though, so this fix roughly only helps single-monitor Chrome and Edge users.

Finally, you could also attempt to heuristically guess where the true top and left edges of the screen are. For instance, if screen.availLeft or screen.availTop are less than 100, probably the actual left or top edge of the screen is at 0 and you could tweak the code above to assume this.

I don't think any of these are good ideas, but wanted to outline options in case you are fanatical about putting your popup in the center of the screen and not just the available area.

To more accurately adjust for the height of the address bar

You can spawn the popup (with e.g. const popup = window.open(...), then check the top bar height a while after it's spawned (popup.outerHeight - popup.innerHeight) and adjust the positioning accordingly using popup.moveTo. (moveTo docs)

There are once again nasty problems with such a trick that in my view make it inadvisable, though. It takes some time for popup.outerHeight to return anything other than 0, so you can't do this synchronously. Also, if your popup is cross-origin, the Same Origin Policy will block you from reading its height. In my opinion it is best to simply live with the imperfections of the simple centeredPopup function at the start of my answer rather than try to fix them with hacks like this, but that's your call.

Forelli answered 7/2 at 19:22 Comment(2)
according to your own link at developer.mozilla.org/en-US/docs/Web/API/ScreenDetailed/… the property availTop is not available on firefoxHypercatalectic
@Hypercatalectic the availTop property of the ScreenDetailed interface is not available in Firefox, but that's not what we're using when we access window.screen.availTop. Instead we're accessing the property described in the "Note" on the linked page: "A non-standard implementation of the availTop property is available on the Screen interface in all browsers."Forelli
M
-1

I had an issue with centering a popup window in the external monitor and window.screenX and window.screenY were negative values (-1920, -1200) respectively. I have tried all the above of the suggested solutions and they worked well in primary monitors. I wanted to leave

  • 200 px margin for left and right
  • 150 px margin for top and bottom

Here is what worked for me:

 function createPopupWindow(url) {
    var height = screen.height;
    var width = screen.width;
    var left, top, win;

    if (width > 1050) {
        width = width - 200;
    } else {
        width = 850;
    }

    if (height > 850) {
        height = height - 150;
    } else {
        height = 700;
    }

    if (window.screenX < 0) {
        left = (window.screenX - width) / 2;
    } else {
        left = (screen.width - width) / 2;
    }

    if (window.screenY < 0) {
        top = (window.screenY + height) / 4;
    } else {
        top = (screen.height - height) / 4;
    }

    win=window.open( url,"myTarget", "width="+width+", height="+height+",left="+left+",top="+top+"menubar=no, status=no, location=no, resizable=yes, scrollbars=yes");
    if (win.focus) {
        win.focus();
    }
}
Mythos answered 28/5, 2020 at 12:53 Comment(2)
Broken for me - just creates a full-screen popup window.Forelli
(I spot a missing comma before menubar in the windowFeatures string but fixing that doesn't fix the brokenness I observe above.)Forelli
B
-1

This would work out based on your screen size

<html>
<body>
<button onclick="openfunc()">Click here to open window at center</button>
<script>
function openfunc() {
windowWidth = 800;
windowHeight = 720;
 var left = (screen.width - windowWidth) / 2;
            var top = (screen.height - windowHeight) / 4;
            var myWindow = window.open("https://www.google.com",'_blank','width=' + windowWidth + ', height=' + windowHeight + ', top=' + top + ', left=' + left);
}
</script>
</body>
</html>
Belaud answered 26/6, 2020 at 18:59 Comment(1)
Like so many of the answers on this page, this is broken in the case where the user has a multi-monitor setup. I just tried it out on my right-hand monitor and it spawned the popup at the left edge of the screen, not in the center.Forelli
N
-1

Image For Popup Code. updated on 2023 javascript for dual screen

const fucntionPop =()=>{

const popupWidth = 600;
const popupHeight = 700;

const dualScreenLeft = window.screenLeft || window.screenX || 0;
const dualScreenTop = window.screenTop || window.screenY || 0;

const screenWidth = window.screen.width;
const screenHeight = window.screen.height;

const left = (screenWidth - popupWidth) / 2 + dualScreenLeft;
const top = (screenHeight - popupHeight) / 2 + dualScreenTop;
const popupFeatures = `width=${popupWidth},height=${popupHeight},left=${left},top=${top}`;

return window.open(
  `http://localhost:3001/?token=${getToken()}&apiKey=${getApiKey()}`, // replace with your URL
  '_blank',
   popupFeatures
);

}
Nail answered 5/12, 2023 at 7:19 Comment(1)
This is broken; the popup doesn't end up positioned in the center of the screen but rather in some location dependent upon the position of the parent window. You're assuming, I think, that window.screenLeft and window.screenTop give the coordinates for the top-left corner of the screen, but actually they (perhaps perversely, given their names) give the coordinates for the top-left corner of the browser window; all the logic using them is nonsensical with this in mind. It just happens to kinda work when the parent window is maximised, but you can't rely on that.Forelli
J
-7

.center{
    left: 50%;
    max-width: 350px;
    padding: 15px;
    text-align:center;
    position: relative;
    transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -o-transform: translateX(-50%);   
}
Juanitajuanne answered 8/6, 2019 at 6:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.