简体   繁体   English

使用 margin:auto 垂直对齐 div

[英]Using margin:auto to vertically-align a div

So I know we can center a div horizontally if we use margin:0 auto;所以我知道如果我们使用margin:0 auto; . . Should margin:auto auto;margin:auto auto; work how I think it should work?工作我认为它应该如何工作? Centering it vertically as well?也垂直居中?

Why doesn't vertical-align:middle;为什么不vertical-align:middle; work either?工作吗?

 .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 JSFiddle

Update Aug 2020 2020 年 8 月更新

Although the below is still worth reading for the useful info, we have had Flexbox for some time now, so just use that, as per this answer .尽管下面的有用信息仍然值得一读,但我们已经使用 Flexbox 有一段时间了,所以按照这个答案使用它。


You can't use:你不能使用:

vertical-align:middle because it's not applicable to block-level elements vertical-align:middle因为 不适用于块级元素

margin-top:auto and margin-bottom:auto because their used values would compute as zero margin-top:automargin-bottom:auto因为它们使用的值将计算为零

margin-top:-50% because percentage-based margin values are calculated relative to the width of containing block margin-top:-50%因为基于百分比的边距值是相对于包含块的宽度计算的

In fact, the nature of document flow and element height calculation algorithms make it impossible to use margins for centering an element vertically inside its parent.事实上,文档流和元素高度计算算法的本质使得不可能使用边距来使元素在其父元素中垂直居中。 Whenever a vertical margin's value is changed, it will trigger a parent element height re-calculation (re-flow), which would in turn trigger a re-center of the original element... making it an infinite loop.每当更改垂直边距的值时,它将触发父元素高度重新计算(重新流动),这反过来又会触发原始元素的重新居中......使其成为无限循环。

You can use:您可以使用:

A few workarounds like this which work for your scenario; 像这样的一些解决方法适用于您的场景; the three elements have to be nested like so:这三个元素必须像这样嵌套:

 .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 works fine according to Browsershot.根据 Browsershot, JSFiddle可以正常工作。

Since this question was asked in 2012 and we have come a long way with browser support for flexboxes, I felt as though this answer was obligatory.自从 2012 年提出这个问题以来,我们在浏览器对 flexbox 的支持方面取得了长足的进步,我觉得这个答案似乎是强制性的。

If the display of your parent container is flex , then yes , margin: auto auto (also known as margin: auto ) will work to center it both horizontally and vertically, regardless if it is an inline or block element.如果父容器的显示是flex ,那么的, margin: auto auto (也称为margin: auto )将使其水平和垂直居中,无论它是inline元素还是block元素。

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

Note that the width/height do not have to be specified absolutely, as in this example jfiddle which uses sizing relative to the viewport.请注意,不必绝对指定宽度/高度,如在此示例 jfiddle中,它使用相对于视口的大小。

Although browser support for flexboxes is at an all-time high at time of posting, many browsers still do not support it or require vendor prefixes.尽管浏览器对弹性盒的支持在发布时处于历史最高水平,但许多浏览器仍然不支持它或需要供应商前缀。 Refer to http://caniuse.com/flexbox for updated browser support information.有关更新的浏览器支持信息,请参阅http://caniuse.com/flexbox

Update更新

Since this answer received a bit of attention, I would also like to point out that you don't need to specify margin at all if you're using display: flex and would like to center all of the elements in the container:由于这个答案受到了一些关注,我还想指出,如果您使用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>

Here's the best solution I've found: http://jsfiddle.net/yWnZ2/446/ Works in Chrome, Firefox, Safari, IE8-11 & Edge.这是我找到的最佳解决方案:http: //jsfiddle.net/yWnZ2/446/适用于 Chrome、Firefox、Safari、IE8-11 和 Edge。

If you have a declared height ( height: 1em , height: 50% , etc.) or it's an element where the browser knows the height ( img , svg , or canvas for example), then all you need for vertical centering is this:如果您有一个声明的heightheight: 1emheight: 50%等),或者它是浏览器知道高度的元素(例如imgsvgcanvas ),那么垂直居中所需的只是:

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

You'll usually want to specify a width or max-width so the content doesn't stretch the whole length of the screen/container.您通常需要指定widthmax-width ,以便内容不会拉伸屏幕/容器的整个长度。

If you're using this for a modal that you want always centered in the viewport overlapping other content, use position: fixed;如果您将它用于您希望始终在视口中居中与其他内容重叠的模式,请使用position: fixed; for both elements instead of position: absolute .对于两个元素而不是position: absolute http://jsfiddle.net/yWnZ2/445/ http://jsfiddle.net/yWnZ2/445/

Here's a more complete writeup: http://codepen.io/shshaw/pen/gEiDt这是一个更完整的文章:http: //codepen.io/shshaw/pen/gEiDt

Edit: it's 2020, I would use flex box instead.编辑:现在是 2020 年,我会改用弹性框。

Original answer:原答案:

Html html

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

CSS CSS

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

I know the question is from 2012, but I found the easiest way ever, and I wanted to share.我知道这个问题来自 2012 年,但我找到了最简单的方法,我想分享。

HTML: HTML:

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

and CSS:和 CSS:

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

If you know the height of the div you want to center , you can position it absolutely within its parent and then set the top value to 50% .如果您知道要居中的 div 的高度,则可以将其绝对定位在其父级内,然后将top值设置为50% That will put the top of the child div 50% of the way down its parent, ie too low.这将使子 div 的顶部下降其父级的 50%,即太低。 Pull it back up by setting its margin-top to half its height.通过将其margin-top设置为其高度的一半将其拉回。 So now you have the vertical midpoint of the child div sitting at the vertical midpoint of the parent - vertically centered!所以现在你的子 div 的垂直中点位于父 div 的垂直中点 - 垂直居中!

Example:例子:

 .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/ http://jsfiddle.net/yWnZ2/2/

Those two solution require only two nested elements.这两个解决方案只需要两个嵌套元素。
First - Relative and absolute positioning if the content is static (manual center). First -如果内容是静态的(手动中心),则相对和绝对定位。

.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/ https://jsfiddle.net/GlupiJas/5mv3j171/

or for fluid design - for exact content center use below example instead:用于流体设计- 对于确切的内容中心,请改用以下示例:

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

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

You need 'min-height' set in case the content will exceed 50% of window height.您需要设置“最小高度”以防内容超过窗口高度的 50%。 You can also manipulate this height with media query for mobile and tablet devices .您还可以使用移动和平板设备的媒体查询来控制此高度。 But only if You play with responsive design.但前提是您使用响应式设计。

I guess You could go further and use simple JavaScript/JQuery script to manipulate the min-height or fixed height if there is a need for some reason.我想如果出于某种原因需要,您可以更进一步并使用简单的 JavaScript/JQuery 脚本来操作最小高度或固定高度。

Second - if content is fluid u can also use table and table-cell css properties with vertical alignment and text-align centered:第二-如果内容是流动的,你还可以使用垂直对齐和文本居中对齐的表格和表格单元 css 属性:

/*in a wrapper*/  
display:table;   

and

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

Works and scale perfectly, often used as responsive web design solution with grid layouts and media query that manipulate the width of the object.完美地工作和扩展,通常用作具有网格布局和媒体查询的响应式网页设计解决方案,可操纵对象的宽度。

.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/ https://jsfiddle.net/GlupiJas/4daf2v36/

I prefer table solution for exact content centering, but in some cases relative absolute positioning will do better job especially if we don't want to keep exact proportion of content alignment.我更喜欢精确内容居中的表格解决方案,但在某些情况下,相对绝对定位会做得更好,特别是如果我们不想保持内容对齐的精确比例。

 .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>

There isn't one easy way to center div vertically which would do the trick in every situation.没有一种简单的方法可以使 div 垂直居中,这在每种情况下都能奏效。

However, there are lots of ways to do it depending on the situation.但是,根据情况有很多方法可以做到这一点。

Here are few of them:以下是其中几个:

  • Set top and bottom padding of the parent element for example padding:20px 0px 20px 0px设置父元素的顶部和底部填充,例如 padding:20px 0px 20px 0px
  • Use table, table cell centers its' content vertically使用表格,表格单元格将其内容垂直居中
  • Set parent element's position relative and the div's you want to vertically center to absolute and style it as top:50px;将父元素的相对位置和要垂直居中的 div 设置为绝对并将其样式设置为 top:50px; bottom:50px;底部:50px; for example例如

You may also google for "css vertical centering"您也可以在 Google 上搜索“css 垂直居中”

Using Flexbox:使用弹性盒:

HTML: HTML:

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

CSS: CSS:

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

View result查看结果

variable height ,margin top and bottom auto可变高度,边距顶部和底部自动

 .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>

variable height ,margin top and bottom auto可变高度,边距顶部和底部自动

I think you can fix that with Flexbox我认为你可以用 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>

 .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>

<div style="display:flex">
  <img src="" style="display:block !important; margin:auto">
</div>

To center an image in a div horizontally and vertically将 div 中的图像水平和垂直居中

.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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM