Làm thế nào để trung tâm nội dung theo chiều dọc với chiều cao thay đổi trong một div?


158

Cách tốt nhất để tập trung theo chiều dọc nội dung của div khi chiều cao của nội dung là thay đổi. Trong trường hợp cụ thể của tôi, chiều cao của div container được cố định, nhưng sẽ rất tuyệt nếu có một giải pháp hoạt động trong trường hợp container có chiều cao thay đổi. Ngoài ra, tôi rất thích một giải pháp không có hoặc sử dụng rất ít các bản hack CSS và / hoặc đánh dấu phi ngữ nghĩa.

văn bản thay thế


phương pháp trong bài viết đó sụp đổ trong Safari (4.0.5): S

7
@ ripper234 Không chính xác, vì câu hỏi này là về div chiều cao thay đổi
Rauli Rajande

9
Ngoài ra, câu hỏi này đã được hỏi đầu tiên.
Gui Imamura

Câu trả lời:


147

Chỉ cần thêm

position: relative;
top: 50%;
transform: translateY(-50%);

đến div bên trong.

Những gì nó làm là di chuyển đường viền trên cùng của div bên trong đến một nửa chiều cao của div bên ngoài ( top: 50%;) và sau đó div bên trong tăng một nửa chiều cao của nó ( transform: translateY(-50%)). Điều này sẽ làm việc với position: absolutehoặc relative.

Hãy nhớ rằng transformtranslatecó các tiền tố nhà cung cấp không được bao gồm để đơn giản.

Codepen: http://codepen.io/anon/pen/ZYprdb


6
Chỉ tự hỏi tại sao điều này hoạt động trên Chrome và Firefox, nhưng không dành cho Safari. Sau đó, tôi nhận thấy rằng hầu hết transformcác công cụ liên quan đều có -webkit-tiền tố và bây giờ nó hoạt động. Vì vậy, như một lời nhắc nhở: Đừng quên thêm -webkit-tiền tố.
miho

5
Sử dụng một công cụ như github.com/postcss/autoprefixer để xử lý các tiền tố cho bạn.
Jamie Chong

6
Câu trả lời này nên được đặt lên hàng đầu.
Jose Faeti

3
Điều này nên có nhiều upvote hơn! Nhân tiện, nó cũng hoạt động với position: absolute, phải không?
caw

4
Phương pháp này có tác dụng phụ đáng tiếc trong Chrome - nếu trình bao bọc của bạn có số pixel lẻ thì translatesẽ hiển thị mọi thứ một cách mờ nhạt khi nó cố gắng xử lý chiều cao .5px trên mọi thứ.
Keith

157

Đây dường như là giải pháp tốt nhất mà tôi đã tìm thấy cho vấn đề này, miễn là trình duyệt của bạn hỗ trợ ::beforephần tử giả: CSS-Tricks: Định tâm trong Unknown .

Nó không yêu cầu bất kỳ đánh dấu thêm và dường như hoạt động rất tốt. Tôi không thể sử dụng display: tablephương pháp này vì tablecác yếu tố không tuân theo max-heighttài sản.

.block {
  height: 300px;
  text-align: center;
  background: #c0c0c0;
  border: #a0a0a0 solid 1px;
  margin: 20px;
}

.block::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */

  /* For visualization 
  background: #808080; width: 5px;
  */
}

.centered {
  display: inline-block;
  vertical-align: middle;
  width: 300px;
  padding: 10px 15px;
  border: #a0a0a0 solid 1px;
  background: #f5f5f5;
}
<div class="block">
    <div class="centered">
        <h1>Some text</h1>
        <p>But he stole up to us again, and suddenly clapping his hand on my
           shoulder, said&mdash;"Did ye see anything looking like men going
           towards that ship a while ago?"</p>
    </div>
</div>


3
Bây giờ -that- là một giải pháp -BRILLIANT-. Cảm ơn rất nhiều vì đã gửi bài này!
Troy Alford

Cũng như câu trả lời khác, câu trả lời này sẽ tốt hơn nhiều nếu nó mô tả cách tiếp cận và bao gồm mã từ liên kết.
KatieK

3
+1, Giải pháp này thực sự khá khéo léo! Btw bạn có thể thêm .block { white-space: nowrap; font-size: 0; line-height: 0; }và để lại lề phải âm trên phần tử giả, bạn chỉ cần đặt lại fs và lh trên .centered ... như thế này bạn đảm bảo rằng phần tử sẽ được định vị chính xác ngay cả khi nó rộng hơn khung nhìn (và don 'T phải sử dụng imo một chút âm lề lộn xộn).
Simon

@jessegavin - theo ý kiến ​​của bạn ... làm thế nào để những thứ sau đây chồng lên với cách tiếp cận bạn đã vạch ra: stackoverflow.com/questions/396145/
Kẻ

1
Ngoài ra, điều này bị phá vỡ khi container .block bên ngoài có chiều cao tối thiểu thay vì chiều cao.
Lincoln B

16

Đây là điều tôi cần phải làm nhiều lần và một giải pháp nhất quán vẫn yêu cầu bạn thêm một chút đánh dấu phi ngữ nghĩa và một số hack cụ thể của trình duyệt. Khi chúng tôi nhận được hỗ trợ trình duyệt cho css 3, bạn sẽ có được định tâm thẳng đứng mà không phạm tội.

Để giải thích rõ hơn về kỹ thuật, bạn có thể xem bài viết mà tôi đã điều chỉnh từ đó , nhưng về cơ bản, nó liên quan đến việc thêm một yếu tố phụ và áp dụng các kiểu khác nhau trong IE và các trình duyệt hỗ trợ position:table\table-cellcác yếu tố không phải bảng.

<div class="valign-outer">
    <div class="valign-middle">
        <div class="valign-inner">
            Excuse me. What did you sleep in your clothes again last night. Really. You're gonna be in the car with her. Hey, not too early I sleep in on Saturday. Oh, McFly, your shoe's untied. Don't be so gullible, McFly. You got the place fixed up nice, McFly. I have you're car towed all the way to your house and all you've got for me is light beer. What are you looking at, butthead. Say hi to your mom for me.
        </div>
    </div>
</div>

<style>
    /* Non-structural styling */
    .valign-outer { height: 400px; border: 1px solid red; }
    .valign-inner { border: 1px solid blue; }
</style>

<!--[if lte IE 7]>
<style>
    /* For IE7 and earlier */
    .valign-outer { position: relative; overflow: hidden; }
    .valign-middle { position: absolute; top: 50%; }
    .valign-inner { position: relative; top: -50% }
</style>
<![endif]-->
<!--[if gt IE 7]> -->
<style>
    /* For other browsers */
    .valign-outer { position: static; display: table; overflow: hidden; }
    .valign-middle { position: static; display: table-cell; vertical-align: middle; width: 100%; }
</style>

Có nhiều cách (hack) để áp dụng các kiểu trong các bộ trình duyệt cụ thể. Tôi đã sử dụng các bình luận có điều kiện nhưng nhìn vào bài viết được liên kết ở trên để thấy hai kỹ thuật khác.

Lưu ý: Có những cách đơn giản để lấy định tâm dọc nếu bạn biết trước một số độ cao, nếu bạn đang cố gắng căn giữa một dòng văn bản hoặc trong một số trường hợp khác. Nếu bạn có nhiều chi tiết hơn thì hãy ném chúng vào vì có thể có một phương pháp không yêu cầu hack trình duyệt hoặc đánh dấu phi ngữ nghĩa.

Cập nhật: Chúng tôi đang bắt đầu nhận hỗ trợ trình duyệt tốt hơn cho CSS3, mang cả hộp flex và biến đổi thành phương pháp thay thế để lấy định tâm dọc (trong số các hiệu ứng khác). Xem câu hỏi khác này để biết thêm thông tin về các phương pháp hiện đại, nhưng hãy nhớ rằng hỗ trợ trình duyệt vẫn còn sơ sài cho CSS3.


Vâng, tôi thấy bài báo đó ngày hôm nay và không thể làm cho nó hoạt động cho tình huống cụ thể của tôi. Có lẽ tôi cần xem xét thêm.
jessegavin

Có lẽ bạn có thể đăng mã bạn đang sử dụng không hoạt động?
Chris Marasti-Georg

Đây vẫn là giải pháp tốt nhất cho vấn đề này?
ripper234

Bài viết đó dường như không hoạt động trên Chrome 23, Firefox 16 và IE 9. Câu trả lời này dường như là một giải pháp tốt hơn.
Fernando Correia

Không, bài viết đó vẫn KHÔNG hoạt động trong Chrome và Firefox mới nhất kể từ ngày 24 tháng 2 năm 2013
OMA

9

Sử dụng bộ chọn con, tôi đã đưa ra câu trả lời đáng kinh ngạc của Fadi ở trên và đưa nó xuống chỉ một quy tắc CSS mà tôi có thể áp dụng. Bây giờ tất cả những gì tôi phải làm là thêm contentCenteredtên lớp vào các phần tử tôi muốn căn giữa:

.contentCentered {
  text-align: center;
}

.contentCentered::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -.25em; /* Adjusts for spacing */
}

.contentCentered > * {
  display: inline-block;
  vertical-align: middle;
}
<div class="contentCentered">
  <div>
    <h1>Some text</h1>
    <p>But he stole up to us again, and suddenly clapping his hand on my
      shoulder, said&mdash;"Did ye see anything looking like men going
      towards that ship a while ago?"</p>
  </div>
</div>

Mã ngã baPen: http://codepen.io/dougli/pen/Eeysg


Mát mẻ. Cám ơn vì đã chia sẻ. Một lưu ý cần thận trọng là *bộ chọn sẽ hoạt động kém hơn câu trả lời được chấp nhận. Có thể không phải là một vấn đề, nhưng đáng chú ý. stevesouders.com/blog/2009/06/18/simplifying-css-selector
jessegavin

Cảm ơn. Vâng, nó có thể sẽ hoạt động kém hơn, nhưng ngày nay các quy tắc CSS có thể không ảnh hưởng đến nhiều thứ. Chúng tôi có thể cải thiện điều này bằng cách chọn vào > divthay thế. calendar.perfplanet.com/2011/ từ
dougli

Đơn giản và tuyệt vời. Làm việc cho tôi hoàn hảo.
Lovro

4

Kết quả tốt nhất cho tôi cho đến nay:

div là trung tâm:

position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;

Làm việc như một

3

Bạn có thể sử dụng lề tự động. Với flex, div dường như cũng được tập trung theo chiều dọc.

body,
html {
  height: 100%;
  margin: 0;
}
.site {
  height: 100%;
  display: flex;
}
.site .box {
  background: #0ff;
  max-width: 20vw;
  margin: auto;
}
<div class="site">
  <div class="box">
    <h1>blabla</h1>
    <p>blabla</p>
    <p>blablabla</p>
    <p>lbibdfvkdlvfdks</p>
  </div>
</div>

hiển thị: flex thực tế vẫn là một tính năng thử nghiệm; chưa có trình duyệt nào hỗ trợ nó một cách chính xác
andreszs 6/10/2016

1

Đối với tôi cách tốt nhất để làm điều này là:

.container{
  position: relative;
}

.element{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

Ưu điểm là không phải làm cho chiều cao rõ ràng


0

Đây là giải pháp tuyệt vời của tôi cho divchiều cao động (phần trăm).

CSS

.vertical_placer{
  background:red;
  position:absolute; 
  height:43%; 
  width:100%;
  display: table;
}

.inner_placer{  
  display: table-cell;
  vertical-align: middle;
  text-align:center;
}

.inner_placer svg{
  position:relative;
  color:#fff;
  background:blue;
  width:30%;
  min-height:20px;
  max-height:60px;
  height:20%;
}

HTML

<div class="footer">
    <div class="vertical_placer">
        <div class="inner_placer">
            <svg> some Text here</svg>
        </div>
    </div>
</div>  

Hãy thử điều này một mình.


0

bạn có thể sử dụng màn hình flex như mã dưới đây:

.example{
  background-color:red;
  height:90px;
  width:90px;
  display:flex;
  align-items:center; /*for vertically center*/
  justify-content:center; /*for horizontally center*/
}
<div class="example">
    <h6>Some text</h6>
</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.