우리 모두는 margin:0 auto; 스타일이 요소를 수평으로 중앙에 배치할 수 있다는 것을 알고 있지만 지금까지는 margin: auto; 하지만 참고하세요! 요소가 완전히 중앙에 오도록 하려면 요소의 높이를 선언하고 다음 스타일을 추가하기만 하면 됩니다.
.Absolute-Center { margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; }
저는 이 방법을 처음으로 발견한 사람은 아닙니다. 이를 사용하려면 "완벽한 센터링"이라고 합니다.) 아마도 매우 일반적인 기술일 것입니다. 그러나 수직 센터링을 소개하는 대부분의 기사에서는 이 방법을 언급하지 않았습니다
Simon은 jsFiddle에 대한 링크를 제공하며 다른 방법은 이에 비해 미미합니다. (Priit도 댓글란에서 같은 방법을 언급했습니다.) 심층적인 조사 끝에 특정 키워드를 사용하여 이 방법을 설명하는 세 개의 웹사이트(사이트 1, 사이트 2, 사이트 3)를 찾았습니다.
한 번도 이 방법을 사용해 본 적이 없는데, 이 "완전 중심" 방법이 얼마나 놀라운지 한번 해보고 싶었습니다. 장점:
크로스 브라우저, 우수한 호환성(해킹 필요 없음, IE8~IE10 고려 가능)
특수 태그 없음, 더욱 간소화된 스타일
적응형 레이아웃, 당신 백분율, 최대, 최소 높이 및 너비와 같은 스타일을 사용할 수 있습니다
중앙에 배치할 때 요소의 패딩 값을 고려하지 않습니다(그리고 상자 크기 스타일을 사용할 필요가 없습니다)
레이아웃 블록의 크기는 자유롭게 조정할 수 있습니다
img 이미지도 사용할 수 있습니다
동시에 주의하세요:
요소 높이를 선언해야 합니다
요소 오버플로 및 비정상적인 표시 문제를 방지하려면 Overflow:auto; 스타일을 설정하는 것이 좋습니다
이 방법은 Windows Phone에서는 작동하지 않습니다
브라우저 지원: Chrome, Firefox, Safari, Mobile 사파리, IE8-10. "Completely Centered"는 테스트를 거쳐 최신 버전의 Chrome, Firefox, Safari, Mobile Safari에서 완벽하게 적용 가능하며 IE8~IE10에서도 실행 가능
비교표
"완전 중앙 정렬"이 이 문서의 유일한 옵션은 아닙니다. 수직 센터링을 달성하는 다른 방법도 있으며 각각 고유한 장점이 있습니다. 취하는 접근 방식은 지원하는 브라우저와 기존 태그의 구조에 따라 다릅니다. 아래 비교표는 귀하의 필요에 가장 적합한 방법을 선택하는 데 도움이 될 수 있습니다.
설명
사양과 문서를 연구한 후 "완전 중앙 정렬"이 어떻게 작동하는지 결론을 내렸습니다.
정상 문서 흐름에서 , margin: auto; 요소의 margin-top 및 margin-bottom을 0으로 설정하는 것을 의미합니다.
W3.org:?'margin-top' 또는 'margin-bottom'이 'auto'인 경우 사용된 값은 0입니다.
2. 위치 설정: 절대; 블록 요소가 되어 일반적인 문서 흐름을 벗어납니다. 문서의 나머지 부분은 평소대로 렌더링되고 요소는 더 이상 원래 위치에 없는 것처럼 보입니다. Developer.mozilla.org:?…절대적으로 배치된 요소는 흐름에서 제외되므로 공간을 차지하지 않습니다.
3. top: 0; left: 0; ;-스타일 블록 요소는 브라우저가 주위에 새 상자를 둘러싸게 하므로 이 요소는 상대 상위 요소의 내부 공간을 채울 것입니다. . Developer.mozilla.org:?절대 위치에 있는 요소의 경우 위쪽, 오른쪽, 아래쪽 및 왼쪽 속성은 요소의 포함 블록(요소가 상대적으로 위치하는 위치)의 가장자리로부터의 오프셋을 지정합니다.
4. 요소의 너비와 높이를 설정한 후 브라우저는 요소가 모든 공간을 채우는 것을 방지하고 margin:auto; 요구 사항에 따라 요소를 다시 계산한 다음 새 상자로 포장합니다. Developer.mozilla.org:?[절대 위치] 요소의 여백은 이러한 오프셋 내부에 배치됩니다.
5. 블록 요소는 절대 위치에 있고 일반 문서 흐름에서 분리되어 있으므로 브라우저는 래핑하기 전에 상자, margin-top 및 margin-bottom은 동일한 값으로 설정됩니다. W3.org:?세 가지 [상단, 하단, 높이] 중 어느 것도 '자동'이 아닌 경우: 'margin-top'과 'margin-bottom'이 모두 'auto'인 경우 두 개가 추가로 적용되는 제약 조건 하에서 방정식을 풉니다. 여백은 동일한 값을 얻습니다.?일명: 블록을 수직으로 가운데에 배치합니다
"완전히 가운데에 맞춤"을 사용하는 것은 의도적으로 표준 여백: 자동 스타일 렌더링 규정을 준수하므로 표준과 호환되는 다양한 브라우저에서 활성화해야 합니다. 효과.
정렬
컨테이너 내 정렬
상대 요소 위치로 설정된 컨테이너에서 완전한 중앙 정렬을 달성하려면 "완전 중앙 정렬"을 사용하세요! (가운데 예시, 영문 원문으로 이동하여 확인하세요)
.Center-Container { position: relative; } .Absolute-Center { width: 50%; height: 50%; overflow: auto; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; }
다음 예시에서는 아래의 스타일이 포함된 것으로 가정하고, 각 스타일별로 다양한 스타일을 제공합니다. 점차적으로 스타일을 추가합니다.
在可视区域内居中
想要使内容区在可视区域内居中么?设置position: fixed样式,并设置一个较高的z-index值,就可以做到。
.Absolute-Center.is-Fixed { position: fixed; z-index: 999; }
移动版Safari的说明:如果外面没有一层设置position: relative的容器,内容区会以整个文档的高度的中心点为基准居中,而不是以可视区域的高度中心点为基准居中。
偏移值
如果需要添加固定的标题,或者其他带偏移样式的元素,可以直接把类似top: 70px; 的样式写进内容区域的样式中。一旦声明了margin: auto; 的样式,内容块的top left bottom right的属性值也会同时计算进去。
如果想让内容块在贴近侧边的过程中保持水平居中,可以使用right: 0; left: auto; 让内容贴在右侧,或者使用left: 0; right: auto; 使内容贴在左侧。
.Absolute-Center.is-Fixed { position: fixed; z-index: 999; }
带响应式
使用absolute的最大好处就是可以完美地使用带百分比的宽高样式!就算是min-width/max-width或者min-height/max-height也能够有如预期般的表现。
再进一步加上padding样式的话,absolute式的完全居中也丝毫不会破坏!
.Absolute-Center.is-Responsive { width: 60%; height: 60%; min-width: 200px; max-width: 400px; padding: 40px; }
带溢出内容
内容区高度大于可视区域或者一个position: relative的容器,其内容可能会溢出容器,或被容器截断。只要内容区域没有超出容器(没有给内容容器预留padding的话,可以设置max-height: 100%;的样式),那么容器内就会产生滚动条。
.Absolute-Center.is-Overflow { overflow: auto; }
大小可调整
使用其他样式,或者使用JavaScript调整内容区的大小,也是不用手动重新计算的!如果设置了resize的样式,甚至可以让用户自行调节内容区域的大小。 “完全居中”法,无论内容区怎么改变大小,都会保持居中。
设置了min-/max- 开头的属性可以限制区块的大小而不用担心撑开容器。
.Absolute-Center.is-Resizable { min-width: 20%; max-width: 80%; min-height: 20%; max-height: 80%; resize: both; overflow: auto; }
如果不设置resize: both的样式,可以设置transition样式平滑地在大小间切换。一定要记得设置overflow: auto样式,因为改变大小后的容器高宽很有可能会小于内容的高宽。 “完全居中”法是唯一一种能支持使用resize: both样式的方法。
使用注意:
需要设置max-width/max-height给内容区域留足够的空间,不然就有可能使容器溢出。
resize属性不支持移动版浏览器和IE8-10,如果用户体验很重要的话,请确保用户可以有其他替代方法来改变大小。
同时使用resize样式和transition会使用户在开始改变大小时产生等于transition效果时间等长的延时。
图像
图像也同样有效!提供相应的class,并指定样式 height: auto; ,就得到了一张随着容器改变大小的响应式图片。
请注意,height: auto; 样式虽然对图片有效,如果没有用到了后面介绍的‘可变高技巧’,则会导致普通内容区域伸长以适应容器长度。
浏览器很有可能是根据渲染结果填充了图像高度值,所以在测试过的浏览器中,margin: auto; 样式就像是声明了固定的高度值一般正常工作。
HTML:
<img src="http://placekitten.com/g/500/200" alt="" />
CSS:
.Absolute-Center.is-Image { height: auto; } .Absolute-Center.is-Image img { width: 100%; height: auto; }
可变高度
“完全居中”法的确需要声明容器高度,但是高度受max-height样式的影响,也可以是百分比。这非常适合响应式的方案,只需要设置好带溢出内容就行。
另一种替代方案是设置display: table样式居中,,不管内容的长度。这种方法会在一些浏览器中产生问题(主要是IE和Firefox)。我在ELL Creative的朋友Kalley写了一个基于Modernizr 的测试,可以用来检查浏览器是否支持这种居中方案。现在这种方法可以做到渐进增强。
注意要点: 这种方法会破坏浏览器兼容性,如果Modernizr测试不能满足你的需求,你可能需要考虑其他的实现方案。
与大小可调整技术是不兼容的
Firefox/IE8中使用display: table,内容区在垂直方向靠上,水平方向仍然居中。
IE9/10中使用display: table,内容区会跑到左上角。
移动版Safari中内容区是水平对齐的,但是如果使用了百分比的宽度,水平方向上会稍稍偏离中心。
Javascript:
/* Modernizr Test for Variable Height Content */ Modernizr.testStyles('#modernizr { display: table; height: 50px; width: 50px; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; }', function(elem, rule) { Modernizr.addTest('absolutecentercontent', Math.round(window.innerHeight / 2 - 25) === elem.offsetTop); });
CSS:
.absolutecentercontent .Absolute-Center.is-Variable { display: table; height: auto; }
其他方法
“完全居中”法是解决居中问题的好方法,同时也有许多可以满足不同需求的其他方法。最常见的,推荐的方法有负margin值、transform法、table-cell法、inline-block法、以及现在出现的Flexbox法,这些方法其他文章都有深入介绍,所以这里只会稍稍提及。
负margin值
这或许是最常用的方法。如果知道了各个元素的大小,设置等于宽高一半大小的负margin值(如果没有使用box-sizing: border-box样式,还需要加上padding值),再配合top: 50%; left: 50%;样式就会使块元素居中。
需要注意的是,这是按照预想情况也能在工作在IE6-7下的唯一方法。
.is-Negative { width: 300px; height: 200px; padding: 20px; position: absolute; top: 50%; left: 50%; margin-left: -170px; /* (width + padding)/2 */ margin-top: -120px; /* (height + padding)/2 */ }
好处:
浏览器兼容性非常好,甚至支持IE6-7
需要的编码量很少
同时注意:
这是个非响应式的方法,不能使用百分比的大小,也不能设置min-/max-的最大值最小值。
内容可能会超出容器
需要为padding预留空间,或者需要使用box-sizing: border-box样式。
transform法
和“完全居中”法的好处一样,简单有效,同时支持可变高度。为内容指定带有厂商前缀的transform: translate(-50%,-50%)和top: 50%; left: 50%;样式就可以让内容块居中。
.is-Transformed { width: 50%; margin: auto; position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%,-50%); -ms-transform: translate(-50%,-50%); transform: translate(-50%,-50%); }
好处:
内容高度可变
代码量小
同时注意:
不支持IE8
需要写厂商前缀
会和其他transform样式有冲突
某些情况下的边缘和字体渲染会有问题
table-cell法
这种可能是最好的方法,因为高度可以随内容改变,浏览器支持也不差。主要缺陷是会产生额外的标签,每一个需要居中的元素需要三个额外的HTML标签。
HTML:
<div class="Center-Container is-Table"> <div class="Table-Cell"> <div class="Center-Block"> <!-- CONTENT --> </div> </div> </div>
CSS:
.Center-Container.is-Table { display: table; } .is-Table .Table-Cell { display: table-cell; vertical-align: middle; } .is-Table .Center-Block { width: 50%; margin: 0 auto; }
好处:
内容高度可变
内容溢出则能自动撑开父元素高度
浏览器兼容性好
同时注意:
需要额外的HTML标签
inline-block法
迫切需要的方法:inline-block法居中。基本方法是使用 display: inline-block, vertical-align: middle样式和伪元素让内容块在容器中居中。我的实现用到了几个在其他地方见不到的新技巧解决了一些问题。
内容区声明的宽度不能大于容器的100% 减去0.25em的宽度。就像一段带有长文本的区域。不然,内容区域会被推到顶端,这就是使用:after伪类的原因。使用:before伪类则会让元素有100%的大小!
如果内容块需要尽可能大地占用水平空间,可以为大容器加上max-width: 99%;样式,或者考虑浏览器和容器宽度的情况下使用max-width: calc(100% – 0.25em) 样式。
这种方法和table-cell的大多数好处相同,不过最初我放弃了这个方法,因为它更像是hack。不管这一点的话,浏览器支持很不错,而且也被证实是很流行的方法。
HTML:
<div class="Center-Container is-Inline"> <div class="Center-Block"> <!-- CONTENT --> </div> </div>
CSS:
.Center-Container.is-Inline { text-align: center; overflow: auto; } .Center-Container.is-Inline:after, .is-Inline .Center-Block { display: inline-block; vertical-align: middle; } .Center-Container.is-Inline:after { content: ''; height: 100%; margin-left: -0.25em; /* To offset spacing. May vary by font */ } .is-Inline .Center-Block { max-width: 99%; /* Prevents issues with long content causes the content block to be pushed to the top */ /* max-width: calc(100% - 0.25em) /* Only for IE9+ */ }
好处:
内容高度可变
内容溢出则能自动撑开父元素高度
浏览器兼容性好,甚至可以调整支持IE7
同时注意:
需要额外容器
依赖于margin-left: -0.25em的样式,做到水平居中,需要为不同的字体大小作调整
内容区声明的宽度不能大于容器的100% 减去0.25em的宽度
Flexbox法
CSS未来发展的方向就是采用Flexbox这种设计,解决像垂直居中这种共同的问题。请注意,Flexbox有不止一种办法居中,他也可以用来分栏,并解决奇奇怪怪的布局问题。
.Center-Container.is-Flexbox { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-align: center; -moz-box-align: center; -ms-flex-align: center; -webkit-align-items: center; align-items: center; -webkit-box-pack: center; -moz-box-pack: center; -ms-flex-pack: center; -webkit-justify-content: center; justify-content: center; }
好处:
内容可以是任意高宽,溢出也能表现良好
可以用于各种高级布局技巧
同时注意: 不支持IE8-9
需要在body上写样式,或者需要额外容器
需要各种厂商前缀兼容现代浏览器
可能有潜在的性能问题
最后的建议
各项技术都有各自的好处,采取什么样的方法,取决于你所支持的浏览器,以及现有标签的结构。请使用上面提供对照表帮你选出最符合你需要的方法。
“完全居中”法简单方便,迅速及时。以前使用负Margin值的地方,都可以使用Absolute居中。无需繁琐的数学计算,无需额外标签,而且可以随时改变大小。
如果网站需要可变高度的内容,而且同时照顾到浏览器兼容性的话,可以尝试table-cell和inline-block技术,如果想尝试新鲜事物的话,可以使用Flexbox,并享受这种高级技术带来的好处。