【问题标题】:Using margin:auto to vertically-align a div使用 margin:auto 垂直对齐 div
【发布时间】:2012-09-07 02:17:59
【问题描述】:

所以我知道如果我们使用margin:0 auto;,我们可以将 div 水平居中。 margin:auto auto; 应该按照我认为的方式工作吗?也垂直居中?

为什么vertical-align:middle; 也不起作用?

.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    background:yellow;
    width:200px;
    margin:auto auto;
    padding:10px;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

JSFiddle

【问题讨论】:

  • 强烈建议阅读和实施下面关于 Flexbox 的@zpr 答案。从今天开始,它得到了很好的支持,你的 css 会变得更加干净。
  • if((new Date()).getFullYear() > 2017) useFlexBox = true;

标签: html css centering


【解决方案1】:

2020 年 8 月更新

尽管下面的有用信息仍然值得一读,但我们已经使用 Flexbox 有一段时间了,所以请按照this answer 使用它。


你不能使用:

vertical-align:middle 因为it's not applicable to block-level elements

margin-top:automargin-bottom:auto 因为their used values would compute as zero

margin-top:-50% 因为percentage-based margin values are calculated relative to the width of containing block

事实上,文档流和element height calculation algorithms 的性质使得不可能使用边距来使元素在其父元素中垂直居中。每当垂直边距的值发生变化时,都会触发父元素高度重新计算(重新流动),这反过来又会触发原始元素的重新居中......使其成为无限循环。

您可以使用:

A few workarounds like this 适用于您的场景;这三个元素必须像这样嵌套:

.container {
    display: table;
    height: 100%;
    position: absolute;
    overflow: hidden;
    width: 100%;
}
.helper {
    #position: absolute;
    #top: 50%;
    display: table-cell;
    vertical-align: middle;
}
.content {
    #position: relative;
    #top: -50%;
    margin: 0 auto;
    width: 200px;
    border: 1px solid orange;
}
<div class="container">
    <div class="helper">
        <div class="content">
            <p>stuff</p>
        </div>
    </div>
</div

JSFiddle 根据 Browsershot 可以正常工作。

【讨论】:

  • # 是一种以规则为前缀的技巧,仅由 IE7 及以下版本解释。您可能更愿意将这些规则包含在特定于 IE 的样式表 by using conditional comments 等中。
  • +1 列举原因,基于宽度的边距百分比计算非常令人大开眼界。
  • 我怀疑“无限循环”的说法。
  • 人类早在几年前就已经登上月球了,我们仍然需要处理这个废话。在浏览器中垂直对齐东西,天哪
  • 在 >= IE9 时代,position: absolute; top: 50%; transform: translateY(-50%); 也是可行的,相当受欢迎...(不像top:50%;margin: - $halfHeight 你不必提前知道高度...)
【解决方案2】:

自从 2012 年提出这个问题以来,我们已经在浏览器对 flexbox 的支持方面取得了长足的进步,我觉得这个答案似乎是强制性的。

如果您的父容器的显示是flex,那么margin: auto auto(也称为margin: auto)将使其水平和垂直居中,无论它是否inlineblock 元素。

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
}
#child {
    margin: auto auto;
}
<div id="parent">
    <div id="child">hello world</div>
</div>

请注意,不必绝对指定宽度/高度,例如 example jfiddle,它使用相对于视口的大小。

尽管浏览器对弹性盒的支持在发布时处于历史最高水平,但许多浏览器仍然不支持它或需要供应商前缀。有关更新的浏览器支持信息,请参阅 http://caniuse.com/flexbox

更新

由于这个答案受到了一些关注,我还想指出,如果您使用 display: flex 并希望将所有元素居中,则根本不需要指定 margin容器:

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
    align-items: center; /* vertical */
    justify-content: center; /* horizontal */
}
<div id="parent">
    <div>hello world</div>
</div>

【讨论】:

  • 父{显示:弹性; }子{边距:自动0; } 简直太棒了。
  • 天哪,老兄,你是个摇滚明星,该死的,我不能为你投票不止一次!!!
  • 当您也可能对 fit-content 问题感到困惑时,这是一个很好的答案。通过在容器上设置 flex,内容 div 不需要设置任何属性。
  • 这是迄今为止在 2018 年工作的最佳和优雅的解决方案,谢谢。
  • 我想补充一点,截至 2018 年 5 月,使用此解决方案,文本不会在 IE 11 中垂直居中对齐。
【解决方案3】:

这是我找到的最佳解决方案:http://jsfiddle.net/yWnZ2/446/ 适用于 Chrome、Firefox、Safari、IE8-11 和 Edge。

如果您有声明的heightheight: 1emheight: 50% 等)或者它是浏览器知道高度的元素(例如imgsvgcanvas),那么你需要的垂直居中是这样的:

.message {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    margin: auto;
}

您通常需要指定widthmax-width,这样内容就不会延伸到屏幕/容器的整个长度。

如果您将其用于希望始终在视口中居中与其他内容重叠的模式,请对这两个元素使用 position: fixed; 而不是 position: absolutehttp://jsfiddle.net/yWnZ2/445/

这里有更完整的文章:http://codepen.io/shshaw/pen/gEiDt

【讨论】:

  • 这并不一定会在其父元素中居中。如果你只是想把它放在页面的中心,那就太好了。
  • 只要将position: relative添加到父元素,元素就会在父元素中居中。如果您想了解更多信息,我在 Smashing Magazine 上写了一篇关于该技术的文章:coding.smashingmagazine.com/2013/08/09/…
  • 有时绝对是基于一个或两个以上的父母(相对于身体),而相对可能是祖父母或曾祖父母(相对于父母)。也许那些知道何时或为什么会发生这种情况的人可以更好地控制这种技术——我从来没有真正研究过这些问题,但我知道从绝对到相对切换本身并不是实现这项工作的解决方案。我读了一点你的文章,看起来绝对和相对上升到第一个绝对或相对祖先,对吗?
  • 我有点慢。我刚刚重新阅读了您上面的评论。我没注意到你说要把它添加到parent - 明白了。非常感谢!
  • @commonpike IE8/9 的唯一问题是如果您使用display: table 来处理可变高度的内容。否则,此方法应按预期工作。通读writeup 了解更多详细信息。您应该还可以在 IE8/9 中测试 full view 以查看是否有任何问题。
【解决方案4】:

编辑:现在是 2020 年,我会改用弹性框。

原答案:

HTML

<body>
  <div class="centered">
  </div>
</body>

CSS

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

【讨论】:

  • 不适用于 IE 8 和更早版本的 ie。由于从 9.0 及更高版本开始支持转换属性(带有前缀 -ms-)。 (即 10 不再需要前缀)。
  • 没错,我不关心IE8
  • 作者为他的问题标记了 html5 ☺
【解决方案5】:

我知道这个问题来自 2012 年,但我找到了最简单的方法,我想分享一下。

HTML:

<div id="parent">
     <div id="child">Content here</div>
</div>

和 CSS:

#parent{
     height: 100%;
     display: table;
}    
#child {
     display: table-cell;
     vertical-align: middle; 
}

【讨论】:

    【解决方案6】:

    如果您知道要居中的 div 的高度,您可以将其绝对定位在其父级内,然后将 top 值设置为 50%。这将使子 div 的顶部下降其父级的 50%,即太低。通过将其margin-top 设置为其高度的一半将其拉回。所以现在子 div 的垂直中点位于父 div 的垂直中点 - 垂直居中!

    例子:

    .black {
        position:absolute;
        top:0;
        bottom:0;
        left:0;
        right:0;
        background:rgba(0,0,0,.5);
    }
    .message {
        background:yellow;
        width:200px;
        margin:auto auto;
        padding:10px;
        position: absolute;
        top: 50%;
        margin-top: -25px;
        height: 50px;
    }
    <div class="black">
        <div class="message">
            This is a popup message.
        </div>
    </div>

    http://jsfiddle.net/yWnZ2/2/

    【讨论】:

    • margin-top 不能以相对于元素高度的百分比设置,因此您最终会得到与尺寸相关的修复
    • 这...正是我在回答中所说的? “如果您知道要居中的 div 的高度”。而且我没有说OP应该在margin-top中使用%。
    • 我不同意该解决方案,因为它将您锁定在预定义的元素高度中 - 但您的评论是有道理的。您可能希望在答案中反映这一点
    • 好的,我把你忽略的部分加粗了,希望现在更清楚了。
    • @o.v.:如果元素没有固定的高度,你可以直接使用 JS 获取计算的高度,然后相应地设置负上边距。在我看来,这仍然是垂直居中的最佳方法。
    【解决方案7】:

    这两个解决方案只需要两个嵌套元素。
    第一个 - 相对和绝对定位如果内容是静态的(手动居中)。

    .black {
        position:relative;
        min-height:500px;
        background:rgba(0,0,0,.5);
    
    }
    .message {
        position:absolute;
        margin: 0 auto;
        width: 180px;
        top: 45%; bottom:45%;  left: 0%; right: 0%;
    }
    

    https://jsfiddle.net/GlupiJas/5mv3j171/

    用于流畅的设计 - 使用以下示例代替精确的内容中心:

    .message {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    

    https://jsfiddle.net/GlupiJas/w3jnjuv0/

    您需要设置“最小高度”以防内容超过窗口高度的 50%。您还可以使用移动和平板设备的媒体查询来操纵这个高度。但前提是您使用响应式设计。

    我想如果出于某种原因需要,您可以更进一步,使用简单的 JavaScript/JQuery 脚本来操作最小高度或固定高度。

    第二个 - 如果内容是流畅的,你也可以使用垂直对齐和居中对齐的表格和表格单元 css 属性:

    /*in a wrapper*/  
    display:table;   
    

    /*in the element inside the wrapper*/
    display:table-cell;
    vertical-align: middle;
    text-align: center;
    

    完美地工作和扩展,通常用作响应式网页设计解决方案,带有网格布局和媒体查询,可操纵对象的宽度。

    .black {
        display:table;
        height:500px;
        width:100%;
        background:rgba(0,0,0,.5);
    
    }
    .message {
        display:table-cell;
        vertical-align: middle;
        text-align: center;
    }
    

    https://jsfiddle.net/GlupiJas/4daf2v36/

    我更喜欢表格解决方案来实现精确的内容居中,但在某些情况下,相对绝对定位会做得更好,特别是如果我们不想保持内容对齐的精确比例。

    【讨论】:

      【解决方案8】:

      .black {
          display:flex;
          flex-direction: column;
          height: 200px;
          background:grey
      }
      .message {
          background:yellow;
          width:200px;
          padding:10px;
          margin: auto auto;
      }
      <div class="black">
          <div class="message">
              This is a popup message.
          </div>
      </div>

      【讨论】:

      • 你能和我们分享一下,这个解决方案是怎么回事?另外,我看到底部没有居中的“弹出消息”
      • 我确实错过了一些东西,但现在它已经被改进为将 div 保持在垂直中间。你现在可以检查了。
      【解决方案9】:

      没有一种简单的方法可以让 div 垂直居中,在任何情况下都能做到这一点。

      但是,根据情况,有很多方法可以做到这一点。

      以下是其中几个:

      • 设置父元素的上下边距,例如 padding:20px 0px 20px 0px
      • 使用表格,表格单元格将其内容垂直居中
      • 将父元素的相对位置和要垂直居中的div设置为绝对位置,并将其样式设置为top:50px;底部:50px;例如

      您也可以在 Google 上搜索“css 垂直居中”

      【讨论】:

        【解决方案10】:

        可变高度,上下边距自动

        .black {background:rgba(0,0,0,.5);
        width: 300px;
        height: 100px;
        display: -webkit-flex; /* Safari */
        display: flex;}
        .message{
        background:tomato;
        margin:auto;
        padding:5%;
        width:auto;
        }
        <div class="black">
        <div class="message">
            This is a popup message.
        </div>

        可变高度,上下边距自动

        【讨论】:

          【解决方案11】:

          使用弹性盒:

          HTML:

          <div class="container">
            <img src="http://lorempixel.com/400/200" />
          </div>
          

          CSS:

          .container {
            height: 500px;
            display: flex;
            justify-content: center; /* horizontal center */
            align-items: center;     /* vertical center */
          }
          

          View result

          【讨论】:

            【解决方案12】:

            我认为你可以用 Flexbox 解决这个问题

            .black {
              height : 200px;
              width : 200px;
              background-color : teal;
              border: 5px solid rgb(0, 53, 53);
              /* This is the important part */
              display : flex;
              justify-content: center;
              align-items: center;
            }
            
            .message {
              background-color :  rgb(119, 128, 0);
              border: 5px solid rgb(0, 53, 53);
              height : 50%;
              width : 50%;
              padding : 5px;
            }
            <div class="black">
                <div class="message">
                    This is a popup message.
                </div>
            </div>

            【讨论】:

              【解决方案13】:

              .black {
                  position:absolute;
                  /*
                      Replace with a one line inset property.
                  top:0;
                  bottom:0;
                  left:0;
                  right:0;
                  */
                  inset: 0;
                  background:rgba(0,0,0,.5);
                  /*
                      Since no one has mentioned it yet,
                      here it is the grid display and
                      the place-content property.
                  */
                  display:grid;
                  place-content: center;
              }
              .message {
                  background:yellow;
                  width:200px;
                  /*
                      There's no point here.
                  margin:auto auto;
                  */
                  padding:10px;
              }
              <div class="black">
                  <div class="message">
                      This is a popup message.
                  </div>
              </div>

              【讨论】:

                【解决方案14】:
                .black {
                    position:absolute;
                    top:0;
                    bottom:0;
                    left:0;
                    right:0;
                    background:rgba(0,0,0,.5);
                }
                .message {
                    position: absolute;
                    top:50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    background:yellow;
                    width:200px;
                    padding:10px;
                }
                
                 - 
                
                
                ----------
                
                
                <div class="black">
                <div class="message">
                    This is a popup message.
                </div>
                

                【讨论】:

                  猜你喜欢
                  • 2014-08-03
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多