Sử dụng lề: tự động căn chỉnh theo chiều dọc một div


113

Vì vậy, tôi biết chúng ta có thể căn giữa một div theo chiều ngang nếu chúng ta sử dụng margin:0 auto;. Nên margin:auto auto;việc làm thế nào tôi nghĩ rằng nó sẽ làm việc? Căn giữa nó theo chiều dọc?

Tại sao cũng không vertical-align:middle;hoạt động?

.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


1
Rất khuyên bạn nên đọc và thực hiện câu trả lời của @ zpr bên dưới về Flexbox. Nó được hỗ trợ khá tốt cho đến ngày hôm nay và css của bạn sẽ sạch hơn rất nhiều.
Govind Rai

if ((new Date ()). getFullYear ()> 2017) useFlexBox = true;
Brandito

Câu trả lời:


173

Cập nhật tháng 8 năm 2020

Mặc dù phần dưới đây vẫn đáng đọc vì thông tin hữu ích, chúng tôi đã có Flexbox một thời gian, vì vậy hãy sử dụng nó, theo câu trả lời này .


Bạn không thể sử dụng:

vertical-align:middlebởi vì không áp dụng cho các phần tử cấp khối

margin-top:automargin-bottom:autobởi vì các giá trị đã sử dụng của chúng sẽ tính bằng 0

margin-top:-50%bởi vì giá trị ký quỹ dựa trên phần trăm được tính toán liên quan đến chiều rộng của khối chứa

Trên thực tế, bản chất của luồng tài liệu và các thuật toán tính toán chiều cao phần tử khiến không thể sử dụng lề để căn giữa một phần tử theo chiều dọc bên trong phần tử gốc. Bất cứ khi nào giá trị của lề dọc bị thay đổi, nó sẽ kích hoạt tính toán lại chiều cao của phần tử mẹ (dòng lại), điều này sẽ kích hoạt lại tâm của phần tử gốc ... làm cho nó trở thành một vòng lặp vô hạn.

Bạn có thể dùng:

Một vài cách giải quyết như thế này phù hợp với kịch bản của bạn; ba phần tử phải được lồng vào nhau như vậy:

.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 hoạt động tốt theo B browserhot .


10
#là một cuộc tấn công để quy tắc có tiền tố chỉ được hiểu bởi IE7 trở xuống. Bạn có thể thích thay vì bao gồm những quy tắc trong một stylesheet IE-cụ thể bằng cách sử dụng ý kiến có điều kiện , vv
ov

2
+1 cho việc nêu lý do tại sao lại như vậy, việc tính toán tỷ lệ phần trăm lợi nhuận dựa trên chiều rộng rất thú vị.
ricosrealm

2
Tôi nghi ngờ về tuyên bố 'vòng lặp vô hạn'.
Barun

105
nhân loại đã lên mặt trăng nhiều năm trước và chúng ta vẫn phải đối phó với trò lừa đảo này. căn chỉnh theo chiều dọc mọi thứ trong trình duyệt,
Chúa ơi

3
Trong tuổi> = IE9, position: absolute; top: 50%; transform: translateY(-50%);cũng khả thi và khá phổ biến ... (không giống như top:50%;margin: - $halfHeightbạn không cần phải biết chiều cao trước ...)
Frank Nocke

112

Vì câu hỏi này được đặt ra vào năm 2012 và chúng tôi đã đi một chặng đường dài với sự hỗ trợ của trình duyệt cho flexbox, tôi cảm thấy như thể câu trả lời này là bắt buộc.

Nếu màn hình của vùng chứa mẹ của bạn là flex, thì , margin: auto auto(còn được gọi là margin: auto) sẽ hoạt động để căn giữa nó theo cả chiều ngang và chiều dọc, bất kể nó là một phần tử inlinehay blockphần tử.

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

Lưu ý rằng chiều rộng / chiều cao không nhất thiết phải được chỉ định tuyệt đối, như trong ví dụ jfiddle này sử dụng định cỡ liên quan đến chế độ xem.

Mặc dù hỗ trợ trình duyệt cho flexbox ở mức cao nhất mọi thời đại tại thời điểm đăng, nhiều trình duyệt vẫn không hỗ trợ hoặc yêu cầu tiền tố của nhà cung cấp. Tham khảo http://caniuse.com/flexbox để biết thông tin hỗ trợ trình duyệt được cập nhật.

Cập nhật

Vì câu trả lời này nhận được một chút chú ý, tôi cũng muốn chỉ ra rằng bạn không cần chỉ định margingì cả nếu bạn đang sử dụng display: flexvà muốn căn giữa tất cả các phần tử trong vùng chứa:

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


4
cha {display: flex; } con {margin: auto 0; } chỉ đơn giản là tuyệt vời.
Arek Kostrzeba

OMG anh bạn, anh là một ngôi sao nhạc rock, chết tiệt, tôi không thể ủng hộ anh nhiều hơn một lần !!!
PirateApp

Đó là một câu trả lời hay khi bạn cũng có thể nhầm lẫn với vấn đề nội dung phù hợp. Bằng cách đặt flex trên vùng chứa, div nội dung không cần bất kỳ thuộc tính nào để đặt.
Eric

1
Đây là giải pháp tốt nhất và thanh lịch để làm việc trong năm 2018, cảm ơn bạn.
SilverSurfer

Tôi muốn nói thêm rằng, kể từ tháng 5 năm 2018, với giải pháp này, văn bản không căn chỉnh theo chiều dọc ở giữa trong IE 11.
Yefu

62

Đây là giải pháp tốt nhất mà tôi đã tìm thấy: http://jsfiddle.net/yWnZ2/446/ Hoạt động trong Chrome, Firefox, Safari, IE8-11 & Edge.

Nếu bạn có một tuyên bố height( height: 1em, height: 50%, vv) hoặc đó là một yếu tố mà các trình duyệt biết chiều cao ( img, svghoặc canvaschẳng hạn), thì tất cả các bạn cần cho định tâm thẳng đứng là thế này:

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

Thông thường, bạn sẽ muốn chỉ định một widthhoặc max-widthnhiều nội dung không kéo dài toàn bộ chiều dài của màn hình / vùng chứa.

Nếu bạn đang sử dụng điều này cho một phương thức mà bạn muốn luôn luôn tập trung trong khung nhìn chồng lên nội dung khác, hãy sử dụng position: fixed;cho cả hai phần tử thay vì position: absolute. http://jsfiddle.net/yWnZ2/445/

Đây là bản ghi đầy đủ hơn: http://codepen.io/shshaw/pen/gEiDt


3
Điều này không nhất thiết phải căn giữa nó trong phần tử mẹ của nó. Mặc dù vậy, hãy hack tốt nếu bạn chỉ muốn nó ở trung tâm của trang.
Joel Mellon

2
Chỉ cần thêm position: relativevào phần tử gốc và phần tử sẽ được căn giữa trong phần tử gốc. Tôi đã làm một writeup lớn hơn nhiều trên Smashing Magazine về kỹ thuật này nếu bạn muốn đọc thêm: coding.smashingmagazine.com/2013/08/09/...
shshaw

Đôi khi, giá trị tuyệt đối dựa trên cha mẹ hoặc hai bên (so với phần thân) và họ hàng có thể là ông hoặc bà lớn (so với cha mẹ). Có thể những người biết khi nào hoặc tại sao điều đó xảy ra có thể kiểm soát kỹ thuật này tốt hơn - Tôi chưa bao giờ thực sự xem xét những vấn đề đó nhưng tôi biết rằng chuyển từ tuyệt đối sang tương đối tự bản thân nó không phải là một giải pháp để thực hiện điều này. Tôi đọc một chút bài viết của bạn và có vẻ như tuyệt đối và tương đối đi lên tổ tiên tuyệt đối hoặc tương đối đầu tiên, có chính xác không?
Joel Mellon

Tôi hơi chậm. Tôi vừa đọc lại bình luận của bạn ở trên. Tôi không nhận thấy bạn nói thêm nó vào parent- đã hiểu. Cám ơn rất nhiều!
Joel Mellon

1
@commonpike Vấn đề duy nhất với IE8 / 9 là nếu bạn sử dụng display: tablecho nội dung có chiều cao thay đổi. Nếu không, phương pháp này sẽ hoạt động như mong đợi. Đọc qua writeup để biết thêm chi tiết tổng thể. Bạn cũng có thể kiểm tra toàn bộ chế độ xem trong IE8 / 9 để xem có vấn đề gì không.
shshaw

22

Chỉnh sửa: đó là năm 2020, tôi sẽ sử dụng hộp flex thay thế.

Câu trả lời ban đầu:

Html

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

CSS

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

sẽ không hoạt động cho IE 8 và các phiên bản cũ hơn của IE. Vì properyty biến đổi được hỗ trợ (với tiền tố -ms-) từ phiên bản 9.0 trở lên. (tức là. 10 không cần tiền tố nữa).
DevWL

5
Đúng, tôi không quan tâm đến IE8
Gal Margalit

Và nhà văn gắn thẻ html5 cho câu hỏi của anh ☺
Gal Margalit

9

Tôi biết câu hỏi có từ năm 2012, nhưng tôi đã tìm ra cách dễ nhất từ ​​trước đến nay và tôi muốn chia sẻ.

HTML:

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

và CSS:

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

7

Nếu bạn biết chiều cao của div mà bạn muốn căn giữa , bạn có thể định vị nó hoàn toàn trong cha của nó và sau đó đặt topgiá trị thành 50%. Điều đó sẽ đặt phần trên cùng của div con đi 50% đường xuống cha của nó, tức là quá thấp. Kéo nó lên bằng cách đặt nó margin-topbằng một nửa chiều cao của nó. Vì vậy, bây giờ bạn có trung điểm dọc của div con ngồi ở trung điểm dọc của cha mẹ - căn giữa theo chiều dọc!

Thí dụ:

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


1
margin-topkhông thể được đặt theo% liên quan đến chiều cao phần tử, vì vậy bạn sẽ kết thúc với một bản sửa lỗi phụ thuộc vào thứ nguyên
ov

1
Đó là ... chính xác những gì tôi đã nói trong câu trả lời của mình? "Nếu bạn biết chiều cao của div bạn muốn căn giữa". Và tôi không nói rằng OP nên sử dụng% in margin-top.
tuff

Tôi không đồng ý với giải pháp vì nó khóa bạn vào chiều cao phần tử được xác định trước - nhưng nhận xét của bạn có lý. Bạn có thể muốn phản ánh điều đó trong câu trả lời
ov

3
OK, tôi đã tô đậm phần mà bạn đã bỏ qua, hy vọng điều đó rõ ràng hơn bây giờ.
tuff

1
@ov: Nếu phần tử không có chiều cao cố định, bạn chỉ có thể sử dụng JS để lấy chiều cao được tính toán và sau đó đặt lề trên âm cho phù hợp. Theo tôi, đây vẫn là phương pháp tốt nhất để căn giữa theo chiều dọc.
daGUY 14/09/12

3

Hai giải pháp đó chỉ yêu cầu hai phần tử lồng nhau.
Thứ nhất - Định vị tương đối và tuyệt đối nếu nội dung là tĩnh (tâm thủ công).

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

hoặc cho thiết kế linh hoạt - để sử dụng trung tâm nội dung chính xác thay thế ví dụ dưới đây:

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

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

Bạn cần đặt 'chiều cao tối thiểu' trong trường hợp nội dung vượt quá 50% chiều cao cửa sổ. Bạn cũng có thể thao tác chiều cao này với truy vấn phương tiện cho thiết bị di động và máy tính bảng. Nhưng chỉ khi Bạn chơi với thiết kế đáp ứng.

Tôi đoán Bạn có thể đi xa hơn và sử dụng tập lệnh JavaScript / JQuery đơn giản để thao tác chiều cao tối thiểu hoặc chiều cao cố định nếu cần vì lý do nào đó.

Thứ hai - nếu nội dung là linh hoạt, bạn cũng có thể sử dụng các thuộc tính css bảng và ô bảng với căn chỉnh dọc và căn giữa văn bản:

/*in a wrapper*/  
display:table;   

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

Hoạt động và chia tỷ lệ hoàn hảo, thường được sử dụng làm giải pháp thiết kế web đáp ứng với bố cục lưới và truy vấn phương tiện thao tác chiều rộng của đối tượng.

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

Tôi thích giải pháp bảng để căn giữa nội dung chính xác, nhưng trong một số trường hợp, định vị tương đối tuyệt đối sẽ làm tốt hơn, đặc biệt nếu chúng tôi không muốn giữ tỷ lệ căn chỉnh nội dung chính xác.


2

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


Xin ông vui lòng chia sẻ với chúng tôi, giải pháp này như thế nào? Thêm vào đó, tôi thấy "thông báo bật lên" của bạn ở dưới cùng không được căn giữa
Alex

Tôi đã bỏ lỡ điều gì đó, nhưng bây giờ nó đã được tinh chỉnh để giữ div ở giữa theo chiều dọc. bạn có thể kiểm tra ngay bây giờ.
Seetpal singh 25/09/17

0

Không có một cách dễ dàng để căn giữa div theo chiều dọc có thể thực hiện thủ thuật trong mọi tình huống.

Tuy nhiên, có rất nhiều cách để làm điều đó tùy thuộc vào tình huống.

Đây là một vài trong số chúng:

  • Đặt phần đệm trên cùng và dưới cùng của phần tử mẹ, ví dụ padding: 20px 0px 20px 0px
  • Sử dụng bảng, ô bảng căn giữa nội dung của nó theo chiều dọc
  • Đặt vị trí tương đối của phần tử mẹ và div mà bạn muốn căn giữa theo chiều dọc thành tuyệt đối và đặt nó là top: 50px; dưới cùng: 50px; ví dụ

Bạn cũng có thể google để tìm "căn giữa dọc css"


0

chiều cao thay đổi, lề trên và dưới tự động

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

chiều cao thay đổi, lề trên và dưới tự động


0

Sử dụng Flexbox:

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 */
}

Xem kết quả


0
.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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.