使用 jQuery 在屏幕上居中显示一个 DIV

How do I go about setting a <div> in the center of the screen using jQuery?

转载于:https://stackoverflow.com/questions/210717/using-jquery-to-center-a-div-on-the-screen

csdnceshi62
csdnceshi62 Agree, JavaScript method isn't that friendly at all. Especially cross browser.
接近 8 年之前 回复
csdnceshi70
笑故挽风 If you are centering a div on the screen, you may be using FIXED positioning. Why not just do this: stackoverflow.com/questions/2005954/…. The solution is pure CSS, doesn't require javascript.
9 年多之前 回复
csdnceshi72
谁还没个明天 Here is one more plugin. alexandremagno.net/jquery/plugins/center
9 年多之前 回复
csdnceshi75
衫裤跑路 This is more of a CSS question than a jQuery question. You can use jQuery methods to help you find the cross-browser positioning and to apply the proper CSS styles to an element, but the essence of the question is how to center a div on the screen using CSS.
大约 12 年之前 回复

26个回答

I like adding functions to jQuery so this function would help:

jQuery.fn.center = function () {
    this.css("position","absolute");
    this.css("top", Math.max(0, (($(window).height() - $(this).outerHeight()) / 2) + 
                                                $(window).scrollTop()) + "px");
    this.css("left", Math.max(0, (($(window).width() - $(this).outerWidth()) / 2) + 
                                                $(window).scrollLeft()) + "px");
    return this;
}

Now we can just write:

$(element).center();

Demo: Fiddle (with added parameter)

csdnceshi79
python小菜 Why use $(this).outerHeight() instead of this.outerHeight()?
4 年多之前 回复
csdnceshi76
斗士狗 This is fantastic, however... how would I make this a toggle? ...so that I can revert the centering in a different scenario? aka.. $(element).nocenter();
5 年多之前 回复
csdnceshi60
℡Wang Yan thanks mate, Im declare my custom code to center any element, buts now when I read your function, really is very nice, ease ..Im like it very much, I will use this Now ^_^...nice..
6 年多之前 回复
csdnceshi77
狐狸.fox To use fixed positioning instead of absolute, just remove the + $(window).scrollTop() and + $(window).scrollLeft(). (And, of course, change "absolute" to "fixed").
大约 7 年之前 回复
csdnceshi50
三生石@ jQuery already has a center function.. Why don't you change the name!
接近 8 年之前 回复
weixin_41568208
北城已荒凉 Instead of this.outerHeight() should be $(this).outerHeight() sameas $(this).outerWidth(). Otherwise you probably get "outerHeight is not a function" error. (stackoverflow.com/questions/947692/…)
接近 8 年之前 回复
csdnceshi52
妄徒之命 This is a great piece of code that I am now using to help with my custom fixes to the jQuery UI Dialog functionality (auto height + max height = jQuery UI Dialog no like). I modified the code slightly so that if the element being centered doesn't fit into the entire window, the top and left are set to the maximum values required to ensure that the top and left of the element are always visible. This works great for things like dialog boxes so the user can always access the title bar of the dialog box to move and close it. The fork of his code is here: jsfiddle.net/m6D72
大约 8 年之前 回复
csdnceshi51
旧行李 I would also suggest adding support so that when the window is resized it'll adjust the element on the page. Currently it stays with the original dimensions.
8 年多之前 回复
csdnceshi70
笑故挽风 The code in the answer should use "position: fixed" since "absolute" is calculated from the first relative parent, and the code uses window to calculate the center.
8 年多之前 回复
csdnceshi57
perhaps? I believe you should subtract half the height of the div you want to center, ie add this to the "top" code: - (this.outerHeight() / 2)
8 年多之前 回复
csdnceshi55
~Onlooker One problem with this is that if the element is higher or wider than the window then it will end up being placed with a negative top or left positioning meaning the user will not be able to scroll and see the whole thing. You should set top and left to 0 if they end up being negative.
8 年多之前 回复
csdnceshi63
elliott.david What if I dont want to center in the containing <div> instead of <body>? Maybe you should change window to this.parent() or add a parameter for it.
8 年多之前 回复
csdnceshi78
程序go This plugin/function works amazingly. I'm wondering, though, if it's possible to also add corner alignment options such as .bottomRight() or .leftTop() or something similar?
接近 9 年之前 回复
weixin_41568110
七度&光 Why isn't this a native part of jQuery's functionality?
9 年多之前 回复
weixin_41568183
零零乙 But outherHeight and outerWidth are only supported by Firefox, right?
9 年多之前 回复
weixin_41568196
撒拉嘿哟木头 I found that this worked great except in IE7/IE8 compatibility mode, where my element was shunted to the right by a fair bit. molokoloco's below solution worked cross-browser for me.
10 年多之前 回复
csdnceshi69
YaoRaoLov One change I'd suggest: You should use this.outerHeight() and this.outerWidth() instead of just this.height() and this.width(). Otherwise, if the object has a border or padding, it will end up slightly off-center.
10 年多之前 回复

I put a jquery plugin here

VERY SHORT VERSION

$('#myDiv').css({top:'50%',left:'50%',margin:'-'+($('#myDiv').height() / 2)+'px 0 0 -'+($('#myDiv').width() / 2)+'px'});

SHORT VERSION

(function($){
    $.fn.extend({
        center: function () {
            return this.each(function() {
                var top = ($(window).height() - $(this).outerHeight()) / 2;
                var left = ($(window).width() - $(this).outerWidth()) / 2;
                $(this).css({position:'absolute', margin:0, top: (top > 0 ? top : 0)+'px', left: (left > 0 ? left : 0)+'px'});
            });
        }
    }); 
})(jQuery);

Activated by this code :

$('#mainDiv').center();

PLUGIN VERSION

(function($){
     $.fn.extend({
          center: function (options) {
               var options =  $.extend({ // Default values
                    inside:window, // element, center into window
                    transition: 0, // millisecond, transition time
                    minX:0, // pixel, minimum left element value
                    minY:0, // pixel, minimum top element value
                    withScrolling:true, // booleen, take care of the scrollbar (scrollTop)
                    vertical:true, // booleen, center vertical
                    horizontal:true // booleen, center horizontal
               }, options);
               return this.each(function() {
                    var props = {position:'absolute'};
                    if (options.vertical) {
                         var top = ($(options.inside).height() - $(this).outerHeight()) / 2;
                         if (options.withScrolling) top += $(options.inside).scrollTop() || 0;
                         top = (top > options.minY ? top : options.minY);
                         $.extend(props, {top: top+'px'});
                    }
                    if (options.horizontal) {
                          var left = ($(options.inside).width() - $(this).outerWidth()) / 2;
                          if (options.withScrolling) left += $(options.inside).scrollLeft() || 0;
                          left = (left > options.minX ? left : options.minX);
                          $.extend(props, {left: left+'px'});
                    }
                    if (options.transition > 0) $(this).animate(props, options.transition);
                    else $(this).css(props);
                    return $(this);
               });
          }
     });
})(jQuery);

Activated by this code :

$(document).ready(function(){
    $('#mainDiv').center();
    $(window).bind('resize', function() {
        $('#mainDiv').center({transition:300});
    });
);

is that right ?

UPDATE :

From CSS-Tricks

.center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%); /* Yep! */
  width: 48%;
  height: 59%;
}
weixin_41568134
MAO-EYE The CSS assumes you know the size (percentages at least) of the centered div, whereas the jQuery works whatever.
接近 7 年之前 回复
csdnceshi63
elliott.david IMHO the CSS trick is beginning to be the prefered way.
大约 7 年之前 回复
weixin_41568131
10.24 Your function worked perfectly fine for a vertical center. It does not appear to work for a horizontal center.
8 年多之前 回复

I'm expanding upon the great answer given by @TonyL. I'm adding Math.abs() to wrap the values, and also I take into account that jQuery might be in "no conflict" mode, like for instance in WordPress.

I recommend that you wrap the top and left values with Math.abs() as I have done below. If the window is too small, and your modal dialog has a close box at the top, this will prevent the problem of not seeing the close box. Tony's function would have had potentially negative values. A good example on how you end up with negative values is if you have a large centered dialog but the end user has installed several toolbars and/or increased his default font -- in such a case, the close box on a modal dialog (if at the top) might not be visible and clickable.

The other thing I do is speed this up a bit by caching the $(window) object so that I reduce extra DOM traversals, and I use a cluster CSS.

jQuery.fn.center = function ($) {
  var w = $(window);
  this.css({
    'position':'absolute',
    'top':Math.abs(((w.height() - this.outerHeight()) / 2) + w.scrollTop()),
    'left':Math.abs(((w.width() - this.outerWidth()) / 2) + w.scrollLeft())
  });
  return this;
}

To use, you would do something like:

jQuery(document).ready(function($){
  $('#myelem').center();
});
csdnceshi69
YaoRaoLov I like your improvements; however, there is still one issue I found depending on the exact behavior you are looking for. The abs will work great only if the user is fully scrolled to the top and left, otherwise the user will have to scroll the browser window to get to the title bar. To solve that problem I opted to do a simple if statement such as this: if (top < w.scrollTop()) top = w.scrollTop(); along with the equivalent for left. Again, this provides different behavior that may or may not be desirable.
大约 8 年之前 回复
weixin_41568131
10.24 Looks good, but it looks like oWin instead of w is a typo...
大约 8 年之前 回复

Please use this:

$(window).resize(function(){
    $('.className').css({
        position:'absolute',
        left: ($(window).width() - $('.className').outerWidth())/2,
        top: ($(window).height() - $('.className').outerHeight())/2
    });
});

// To initially run the function:
$(window).resize();

I would like to correct one issue.

this.css("top", ( $(window).height() - this.height() ) / 2+$(window).scrollTop() + "px");

Above code won't work in cases when this.height (lets assume that user resizes the screen and content is dynamic) and scrollTop() = 0, example:

window.height is 600
this.height is 650

600 - 650 = -50  

-50 / 2 = -25

Now the box is centered -25 offscreen.

I dont think having an absolute position would be best if you want an element always centered in the middle of the page. You probably want a fixed element. I found another jquery centering plugin that used fixed positioning. It is called fixed center.

The transition component of this function worked really poorly for me in Chrome (didn't test elsewhere). I would resize the window a bunch and my element would sort of scoot around slowly, trying to catch up.

So the following function comments that part out. In addition, I added parameters for passing in optional x & y booleans, if you want to center vertically but not horizontally, for example:

// Center an element on the screen
(function($){
  $.fn.extend({
    center: function (x,y) {
      // var options =  $.extend({transition:300, minX:0, minY:0}, options);
      return this.each(function() {
                if (x == undefined) {
                    x = true;
                }
                if (y == undefined) {
                    y = true;
                }
                var $this = $(this);
                var $window = $(window);
                $this.css({
                    position: "absolute",
                });
                if (x) {
                    var left = ($window.width() - $this.outerWidth())/2+$window.scrollLeft();
                    $this.css('left',left)
                }
                if (!y == false) {
            var top = ($window.height() - $this.outerHeight())/2+$window.scrollTop();   
                    $this.css('top',top);
                }
        // $(this).animate({
        //   top: (top > options.minY ? top : options.minY)+'px',
        //   left: (left > options.minX ? left : options.minX)+'px'
        // }, options.transition);
        return $(this);
      });
    }
  });
})(jQuery);

This is great. I added a callback function

center: function (options, callback) {


if (options.transition > 0) {
   $(this).animate(props, options.transition, callback);
} else { 
    $(this).css(props);
   if (typeof callback == 'function') { // make sure the callback is a function
       callback.call(this); // brings the scope to the callback
   }
}

This is untested, but something like this should work.

var myElement = $('#myElement');
myElement.css({
    position: 'absolute',
    left: '50%',
    'margin-left': 0 - (myElement.width() / 2)
});

To center the element relative to the browser viewport (window), don't use position: absolute, the correct position value should be fixed (absolute means: "The element is positioned relative to its first positioned (not static) ancestor element").

This alternative version of the proposed center plugin uses "%" instead of "px" so when you resize the window the content is keep centered:

$.fn.center = function () {
    var heightRatio = ($(window).height() != 0) 
            ? this.outerHeight() / $(window).height() : 1;
    var widthRatio = ($(window).width() != 0) 
            ? this.outerWidth() / $(window).width() : 1;

    this.css({
        position: 'fixed',
        margin: 0,
        top: (50*(1-heightRatio)) + "%",
        left: (50*(1-widthRatio))  + "%"
    });

    return this;
}

You need to put margin: 0 to exclude the content margins from the width/height (since we are using position fixed, having margins makes no sense). According to the jQuery doc using .outerWidth(true) should include margins, but it didn't work as expected when I tried in Chrome.

The 50*(1-ratio) comes from:

Window Width: W = 100%

Element Width (in %): w = 100 * elementWidthInPixels/windowWidthInPixels

Them to calcule the centered left:

 left = W/2 - w/2 = 50 - 50 * elementWidthInPixels/windowWidthInPixels =
 = 50 * (1-elementWidthInPixels/windowWidthInPixels)
共26条数据 1 3 尾页
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问