使用jQuery垂直水平居中一个div

36

我正在使用这个脚本来使我的div水平垂直居中。

当页面加载时,div会垂直居中,但直到我调整浏览器大小才能水平居中。

我做错了什么?

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

63

我通常使用这个“技巧”:

$(function() {
    $('.className').css({
        'position' : 'absolute',
        'left' : '50%',
        'top' : '50%',
        'margin-left' : -$('.className').width()/2,
        'margin-top' : -$('.className').height()/2
    });
});

更新:

我正在更新解决方案,如用户Fred K所建议的那样,使用.outerWidth().outerHeight()来实现更精确的居中。

$(function() {
    $('.className').css({
        'position' : 'absolute',
        'left' : '50%',
        'top' : '50%',
        'margin-left' : -$('.className').outerWidth()/2,
        'margin-top' : -$('.className').outerHeight()/2
    });
});

以下是来自 jQuery 文档 (.outerWidth(), .outerHeight()) 的一些额外说明:

  • 与尺寸相关的 API(包括 .outerWidth())返回的数字在某些情况下可能是小数。代码不应假设它是整数。此外,当用户缩放页面时,尺寸可能不正确;浏览器没有公开的 API 可以检测这种情况。

  • 当元素的父元素处于隐藏状态时,.outerWidth() 报告的值不能保证准确。为获得准确的值,请先显示父元素,然后再使用 .outerWidth()。


更新 2:

简单的更新,展示了如何在存在具有不同大小的相同 class 标签的多个元素中,在 css() 方法内使用 this

$(function() {
    $('.className').css({
        'position' : 'absolute',
        'left' : '50%',
        'top' : '50%',
        'margin-left' : function() {return -$(this).outerWidth()/2},
        'margin-top' : function() {return -$(this).outerHeight()/2}
    });
});

2
这对我有效,但只有当我用('.classname')替换(this)时才有效,可能是因为我正在将一个div居中放置在另一个div中,而“this”当前是窗口大小。你如何让“this”成为你正在操作的元素? - Doug Cassidy
1
如果$(this)不改变尺寸,这是一个好的解决方案。但是对于响应式设计元素来说,情况就不同了,如果它们由于屏幕尺寸减小而改变大小,则此方法会失败。 - Jānis Gruzis
使用 outerWidth()outerHeight() 确保获取中心。 - Fred K
@FredK 谢谢你的建议,我已经更新了解决方案。 - Dim13i
1
@mabi 当然,如果class标签不够具体,可以在css()方法中传递一个函数作为参数,以避免使用each()方法。我会添加一个快速更新。 - Dim13i
显示剩余2条评论

20

使用此代码进行居中:

$.fn.center = function () {
   this.css("position","absolute");
   this.css("top", ( $(window).height() - this.height() ) / 2  + "px");
   this.css("left", ( $(window).width() - this.width() ) / 2 + "px");
   return this;
}

$('yourElem').center();

5
肯定是更好的解决方案。 - jwize

10

将处理程序代码包装在一个函数中,这样您就可以调用该函数,无论是在页面加载时还是作为 $(window).resize() 的处理程序。

/* use as handler for resize*/
$(window).resize(adjustLayout);
/* call function in ready handler*/
$(document).ready(function(){
    adjustLayout();
    /* your other page load code here*/
})

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

}

这很棒,但是在页面第一次加载时它不起作用。它停留在页面的左侧。然后,当我开始调整页面大小时,它跳到页面的中间。有什么想法为什么会这样? - Pavel Binar
1
@Pavel 在 jsfiddle.net 上创建一个演示,以复制问题。 - charlietfl
2
$(window).resize(adjustLayout).resize(); 应该可以消除所提到的问题。 - Tim G

3

与您的代码片段相关,您需要先设置位置:

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

也许你可以通过一个静态的CSS样式来设置位置属性。

1

根据@dimi的回答,对于多个元素效果更好

$(".className").each(
    function () {
       $( this ).css("position","absolute");
       $( this ).css("left","50%");
       $( this ).css("margin-left", - $( this ).outerWidth()/2 );
       $( this ).css("top","50%");
       $( this ).css("margin-top", - $( this ).outerHeight()/2 );
       return this;
    }
);

0

我的class为center的div需要水平居中并且其位置是固定的。我使用以下简短代码实现:

$(window).on('resize load', function () {
    $('.center').each(function () {
        $(this).css({
            'margin-left': ($('body').width() - $(this).width()) / 2
        });
    });
});

你也可以使用同样的策略来进行水平对齐。请注意,它一次性处理加载和调整大小事件,因此该 div 始终位于中间。


0

我最近一直在尝试将一个盒子放置在浏览器窗口的中间。我创建了下面的代码。jQuery脚本非常长,因为我考虑了html和body标签的所有填充和边距,如果有人设置了它们。如果不关心背景,则只需设置winwidth、winheight、toppx、leftpx和“#container”。其余部分可以删除。

<!DOCTYPE html>
<html>
<head>
    <title>Test of centre of container</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <style>
        html {
            background-color: #444;
            margin: 30px;
        }
        #wrapper {
            background-color: #777;
            width: 75%;
            margin: 0 auto;
            padding: 0;
        }
        #container {
            background-color: #ddd;
            border-radius: 10px;
            box-shadow: 0 0 2px #222;
            width: 200px;
            height: 100px;
            position: absolute;
            vertical-align: middle;
        }
        #extext {
            text-align: center;
            padding: 0;
        }
    </style>
</head>
<body>
    <script>
        function setDimensions() {
            var winwidth = $(window).width();
            var winheight = $(window).height();
            var htmlmv = parseInt($("html").css("margin-top")) + parseInt($("html").css("margin-bottom"));
            var htmlpv = parseInt($("html").css("padding-top")) + parseInt($("html").css("padding-bottom"));
            var htmlmh = parseInt($("html").css("margin-left")) + parseInt($("html").css("margin-right"));
            var htmlph = parseInt($("html").css("padding-left")) + parseInt($("html").css("padding-right"));
            var bodymv = parseInt($("body").css("margin-top")) + parseInt($("body").css("margin-bottom"));
            var bodypv = parseInt($("body").css("padding-top")) + parseInt($("body").css("padding-bottom"));
            var bodymh = parseInt($("body").css("margin-left")) + parseInt($("body").css("margin-right"));
            var bodyph = parseInt($("body").css("padding-left")) + parseInt($("body").css("padding-right"));
            var vspace = htmlmv + htmlpv + bodymv + bodypv;
            var hspace = htmlmh + htmlph + bodymh + bodyph;
            var wrapheight = winheight - vspace;
            var wrapwidth = winwidth - hspace;
            $("#wrapper").height(wrapheight);
            // $("#wrapper").width(wrapwidth);

            var toppx = (winheight - parseInt($("#container").css("height"))) / 2;
            var leftpx = (winwidth - parseInt($("#container").css("width"))) / 2;
            $("#container").css("top", toppx.toString() + "px");
            $("#container").css("left", leftpx.toString() + "px");
        }

        $(document).ready(function () {
            setDimensions();
        });
        $(window).resize(function () {
            setDimensions();
        });
    </script>
    <div id="wrapper">
        <div id="container">
            <p id="extext">Example text</p>
        </div>
    </div>
</body>
</html>





编辑: 我在CSS Tricks网站上找到了更好的解决方案,它只使用CSS :). 代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>
        Test centring!
    </title>
    <style>
        body div {
            background-color: red;
            box-shadow: 0 0 15px #222;
            border-radius: 10px;
            padding: 10px;
            margin: -150px auto auto -200px;
            width: 380px;
            height: 280px;
            position: absolute;
            top: 50%;
            left: 50%;
            text-align: center;
            line-height: 140px;
        }
        body div h2 {
            color: yellow;
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
    <div>
        <h2>
            Example text<br />
            Example Text
        </h2>
    </div>
</body>
</html>

0
我使用JQuery.center插件来让我的DOM元素居中。代码将类似于这样:
$("#child").center()

如果您需要相对于其他父级居中,先前的代码将相对于其直接父级进行居中,可使用以下代码:

$("#child").center($("#parent"))

如果您需要其他形式的集中化,我们提供定制选项。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接