Tại sao dọc-align: middle không hoạt động trên span hoặc div của tôi?


246

Tôi đang cố gắng tập trung theo chiều dọc một spanhoặc một divyếu tố trong một divyếu tố khác . Tuy nhiên khi tôi đặt vertical-align: middle, không có gì xảy ra. Tôi đã thử thay đổi displaythuộc tính của cả hai yếu tố và dường như không có gì hoạt động.

Đây là những gì tôi đang làm trong trang web của mình:

.main {
  height: 72px;
  vertical-align: middle;
  border: 1px solid black;
  padding: 2px;
}
    
.inner {
  vertical-align: middle;
  border: 1px solid red;    
}
    
.second {
  border: 1px solid blue; 
}
<div class="main">
  <div class="inner">
    This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

Đây là một jsfiddle của việc triển khai cho thấy nó không hoạt động: http://jsfiddle.net/gZXWC/

Câu trả lời:


207

Đây có vẻ là cách tốt nhất - một thời gian đã trôi qua kể từ bài đăng gốc của tôi và đây là điều nên làm ngay bây giờ: http://jsfiddle.net/m3ykdyds/200

/* CSS file */

.main {
    display: table;
}

.inner {
    border: 1px solid #000000;
    display: table-cell;
    vertical-align: middle;
}

/* HTML File */
<div class="main">
    <div class="inner"> This </div>
</div>

2
Vậy làm thế nào để ai đó làm những gì OP muốn làm?
Ryan Mortensen

Bất kỳ ý tưởng về đoạn văn biến? I E. nếu không có cách nào để biết liệu nó sẽ là một hoặc hai dòng. Tôi có cần người dùng jQuery không?
foochow

Nếu chiều cao phải năng động, giải pháp là gì?
Murhaf Sousli

không nên là câu trả lời được chấp nhận, dựa vào việc biết chiều cao của '.inner', vì vậy không chính xác những gì OP yêu cầu và một số câu trả lời tốt hơn nhiều dưới đây xem câu trả lời của @timbergus hoặc Tim Perkins ở gần phía dưới.
mike-source

@ mike-source biết chiều cao của bên trong là 100% có thể ngay cả khi chiều cao là động vì một chút javascript có thể tìm ra điều đó và thay đổi động quy tắc CSS cho đối tượng DOM đó.
Charles Addis

143

Sử dụng CSS3:

<div class="outer">
   <div class="inner"/>
</div>

Css:

.outer {
  display : flex;
  align-items : center;
  justify-content: center;
}

Lưu ý: Điều này có thể không hoạt động trong IE cũ


16
Điều này được hỗ trợ bởi tất cả các trình duyệt hiện đại chính và giải pháp đơn giản và gọn gàng nhất.
Sam

2
Ngoài ra, hãy nhớ inline-flexcó nhiều yếu tố liên tiếp bên trong yếu tố bên trong.
Dan Nissenbaum

1
Trong trường hợp của tôi, vì tôi muốn tập trung vào nội dung của .inner theo chiều ngang, tôi phải thêm vào .inner { width: 100%; }. Bằng cách này, nó có vẻ hoạt động như thế .outer { display: table; } .inner { display: table-cell; vertical-align: middle; }nhưng không bắt buộc chiều rộng tối thiểu.
Bart S

Tôi đã sử dụng justify-content: center;để sắp xếp theo chiều ngang hoạt động tuyệt vời
Ruth Young

140

Hãy thử điều này, làm việc cho tôi rất tốt:

/* Internet Explorer 10 */
display:-ms-flexbox;
-ms-flex-pack:center;
-ms-flex-align:center;

/* Firefox */
display:-moz-box;
-moz-box-pack:center;
-moz-box-align:center;

/* Safari, Opera, and Chrome */
display:-webkit-box;
-webkit-box-pack:center;
-webkit-box-align:center;

/* W3C */
display:box;
box-pack:center;
box-align:center;

4
câu trả lời tuyệt vời, điều này đã mang đến cho tôi một giải pháp hoạt động hoàn toàn không gây ra các sự cố khác (một ứng dụng sử dụng jquerymobile + phonegap và tất cả các giải pháp khác dẫn đến các vấn đề kích thước css & div). Chỉ cần chỉ ra rằng các tham số này phải được thêm vào khối CSS cụ thể cho các thành phần được căn giữa / trung gian, ví dụ: #element span {height:100%;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;}- lưu ý chiều cao rất quan trọng để đảm bảo nhịp kế thừa toàn bộ chiều cao của vùng chứa của nó (có thể là div) bạn vẫn sẽ không nhận được trung tâm dọc!
Andy Lorenz

BTW, bạn có thể viết mã flexbox tiêu chuẩn mà không cần tiền tố trình duyệt và sau đó lấy tiền tố trình duyệt với autoprefixer github.com/postcss/autoprefixer hoặc qua bản demo trực tuyến simevidas.jsbin.com/gufoko/quiet
starikovs

2
giá trị tài sản không hợp lệ boxtrongdisplay
Joaquinglezsantos 17/2/2016

Ngoài ra, câu trả lời của @ user1782556 hoạt động tốt hơn khi hộp bên ngoài có phần đệm.
tự động

34

Đặt chiều cao của dòng thành cùng chiều cao với div có chứa cũng sẽ hoạt động

DEMO http://jsfiddle.net/kevinPHPkevin/gZXWC/7/

.inner {
    line-height:72px;
    border: 1px solid #000000;
}

1
Tôi đã đăng một liên kết giải thích phương pháp đó là tốt. Mặc dù không phải là phương pháp ưa thích của tôi, nếu phần còn lại của bố cục không cố định về kích thước - tôi đã gặp phải các vấn đề trên các khung nhìn có kích thước khác nhau với phương pháp này.
Charles Addis

2
có, kỹ thuật chiều cao dòng hoạt động tốt, nhưng CHỈ NẾU bạn có nội dung một dòng. Các dòng bổ sung sẽ bị mất / sẽ tràn ra ngoài container và bạn sẽ cần bắt đầu lại!
Andy Lorenz

a) line-heightcũng sẽ thay đổi chiều cao của phần tử bên trong. b) Phần tử bên trong vẫn không được căn giữa chính xác theo chiều dọc. c) Nó không hoạt động trên các phần tử không chứa văn bản, ví dụ: <img>hoặc các phần tử có chiều cao cố định.
Alph.Dev

Nó cũng có thể bị lỗi hệ điều hành chéo (Windows / Mac) do sự khác biệt về kết xuất phông chữ
LocalPCGuy

1
Điều này rất khó đoán và thường dẫn đến chiều cao thêm trên container.
Undistraction

25

Trong trường hợp bạn không thể dựa vào flexbox ... Đặt .childvào .parenttrung tâm của. Hoạt động khi kích thước pixel không xác định (nói cách khác là luôn luôn) và không có vấn đề gì với IE9 +.

.parent { position: relative; }

.child {
    position: absolute;
    top : 50%;
    left: 50%;
    -ms-transform: translate(-50%, -50%);
    transform    : translate(-50%, -50%);    
}
<div class="parent" style="background:lightyellow; padding:6em"> 
  <div class="child" style="background:gold; padding:1em">&mdash;</div> 
</div>


Đây thực sự là giải pháp được thực hiện tốt nhất, đặc biệt là vì hầu hết các dự án tôi đã thấy cho đến nay đều cần khả năng tương thích IE9
Jabberwocky

20

Bạn nên đặt vertical-align: middlevào phần tử bên trong, không phải phần tử bên ngoài. Đặt thuộc line-heighttính trên phần tử bên ngoài để khớp với heightphần tử bên ngoài. Sau đó thiết lập display: inline-blockline-height: normaltrên các yếu tố bên trong. Bằng cách này, văn bản trên phần tử bên trong sẽ bao bọc với chiều cao dòng bình thường. Hoạt động trong Chrome, Firefox, Safari và IE 8+

.main {
    height: 72px;
    line-height:72px;
    border: 1px solid black;
}
.inner {
    display: inline-block;
    vertical-align: middle;
    line-height: normal;
}
<div class="main">
    <div class="inner">Vertically centered text</div>
</div>

Vĩ cầm


Đây có lẽ là cách đơn giản nhất ... tất cả các câu trả lời khác trên trang này là không cần thiết / hacky HOẶC không được hỗ trợ trong các trình duyệt cũ HOẶC dựa vào việc biết chiều cao của phần tử bên trong. Bạn thực sự không cần line-height: normal;và cũng display:inline;làm việc. Phần thưởng của phương pháp này là nó không can thiệp vào text-align:center;, việc sử dụng display: table-cell;có thể tạo ra vấn đề. Chúng tôi thường muốn căn chỉnh theo chiều ngang cũng như chiều dọc. Xem fiddle đã chỉnh sửa này: jsfiddle.net/br090prs/36
mike-source

2
@ mike-source lý do để sử dụng line-height: normaldisplay: inline-blocklà để văn bản bên trong sẽ bao bọc đúng. Nếu bạn chắc chắn rằng văn bản trong div bên trong sẽ không bao giờ ngắt thì các thuộc tính này sẽ không cần thiết.
Tim Perkins

Kể từ khi Microsoft kết thúc hỗ trợ cho các phiên bản IE cũ, tôi đã sử dụng flexbox cho loại điều này (như @ user1782556 đề xuất). Câu trả lời ban đầu của tôi là con đường để đi nếu bạn vẫn cần hỗ trợ IE 10 trở lên.
Tim Perkins

100% đồng ý, nhưng cá nhân tôi chưa đi đến hộp flex, chỉ có 76% trình duyệt hỗ trợ đầy đủ vào tháng 5 năm 2016 (94% nếu bạn bao gồm hỗ trợ một phần), xem: caniuse.com/#search=flexible% 20 hộp . Nó đang trở nên rất gần với việc là tùy chọn hợp lý nhất, tùy thuộc vào cơ sở người dùng của bạn.
mike-source

10

Tôi đã sử dụng điều này để sắp xếp mọi thứ ở trung tâm của div trình bao bọc trong trường hợp nó giúp được bất kỳ ai - tôi thấy nó đơn giản nhất:

div.wrapper {
  /* --- This works --- */
  display: flex;
  /* Align Vertically */
  align-items: center;
  /* Align Horizontally */
  justify-content: center;
  /* --- ---------- ----- */
  width: 100%;
  height:100px;
  background-color: blue;
}
div.inner {
  width: 50px;
  height: 50px;
  background-color: orange;
}
<div class="wrapper">
  <div class="inner">
  </div>
</div>


7

Ở đây bạn có một ví dụ về hai cách thực hiện căn chỉnh dọc. Tôi sử dụng chúng và chúng hoạt động khá tốt. Một là sử dụng định vị tuyệt đối và một là sử dụng flexbox .

Ví dụ căn dọc

Sử dụng flexbox, bạn có thể tự căn chỉnh một yếu tố bên trong một yếu tố khác bằng display: flex;cách sử dụng align-self. Nếu bạn cần căn chỉnh nó theo chiều ngang, bạn có thể sử dụng align-itemsjustify-contenttrong thùng chứa.

Nếu bạn không muốn sử dụng flexbox, bạn có thể sử dụng thuộc tính vị trí. Nếu bạn làm cho container tương đối và nội dung tuyệt đối, nội dung sẽ có thể di chuyển tự do bên trong container. Vì vậy, nếu bạn sử dụng top: 0;left: 0;trong nội dung, nó sẽ được đặt ở góc trên cùng bên trái của container.

Định vị tuyệt đối

Sau đó, để căn chỉnh nó, bạn chỉ cần thay đổi các tham chiếu trên cùng và bên trái thành 50%. Điều này sẽ định vị nội dung tại trung tâm container từ góc trên cùng bên trái của nội dung.

Căn chỉnh ở giữa container

Vì vậy, bạn cần sửa lỗi này để dịch một nửa nội dung của nó sang bên trái và trên cùng.

Trung tâm tuyệt đối


5

Đây là một bài viết tuyệt vời về làm thế nào để căn chỉnh lý thuyết .. Tôi thích cách nổi.

http://www.vanseodesign.com/css/vertical-centering/

HTML:

<div id="main">
    <div id="floater"></div>
    <div id="inner">Content here</div>
</div>

Và kiểu dáng tương ứng:

#main {
   height: 250px;
}

#floater {
   float: left;
   height: 50%;
   width: 100%;
   margin-bottom: -50px;
}

#inner {
   clear: both;
   height: 100px;
}

3
Tôi nghĩ rằng nếu bạn xác định chiều cao của khối #inner thì nó làm mất hiệu lực khái niệm định tâm dọc phù hợp. OPS đã yêu cầu làm cho nó tự động, vì vậy tôi sẽ tưởng tượng điều đó có nghĩa là chiều cao của hộp bên trong không được biết đến tại thời điểm thụ thai.
Alexis Wilke

5

HTML

<div id="myparent">
  <div id="mychild">Test Content here</div>
</div>

CSS

#myparent {
  display: table;
}
#mychild {
  display: table-cell;
  vertical-align: middle;
}

Chúng tôi đặt div cha hiển thị dưới dạng bảng và div con hiển thị dưới dạng ô bảng. Sau đó, chúng ta có thể sử dụng căn chỉnh dọc trên div con và đặt giá trị của nó thành giữa. Bất cứ điều gì bên trong div con này sẽ được tập trung theo chiều dọc.


4

Thật đơn giản. Chỉ cần thêm display:table-cellvào lớp chính của bạn.

.main {
  height: 72px;
  vertical-align: middle;
  display:table-cell;
  border: 1px solid #000000;
}

Kiểm tra jsfiddle này !


4

Đây là giải pháp đơn giản mới nhất - không cần thay đổi bất cứ điều gì, chỉ cần thêm ba dòng quy tắc CSS vào thùng chứa div mà bạn muốn đặt ở giữa. Tôi yêu Flex Box#LoveFlexBox

.main {
  /* I changed height to 200px to make it easy to see the alignment. */
  height: 200px;
  vertical-align: middle;
  border: 1px solid #000000;
  padding: 2px;
  
  /* Just add the following three rules to the container of which you want to center at. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* This is true vertical center, no math needed. */
}
.inner {
  border: 1px solid #000000;
}
.second {
  border: 1px solid #000000;
}
<div class="main">
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

Tặng kem

các justify-contentgiá trị có thể được thiết lập để vài tùy chọn sau:

  • flex-start, sẽ điều chỉnh div con đến nơi luồng flex bắt đầu trong vùng chứa chính của nó. Trong trường hợp này, nó sẽ ở trên đầu.

  • center, sẽ sắp xếp div con vào trung tâm của thùng chứa chính của nó. Điều này thực sự gọn gàng, bởi vì bạn không cần thêm một div bổ sung để quấn quanh tất cả trẻ em để đặt vỏ bọc trong hộp đựng cha mẹ để tập trung vào trẻ em. Do đó, đây là trung tâm dọc thực sự ( column flex-directiontương tự, nếu bạn thay đổi flow-directionthành row, nó sẽ trở thành trung tâm theo chiều ngang.

  • flex-end, sẽ điều chỉnh div con đến nơi dòng flex kết thúc trong thùng chứa chính của nó. Trong trường hợp này, nó sẽ di chuyển xuống dưới cùng.

  • space-between, sẽ lây lan tất cả trẻ em từ đầu dòng chảy đến cuối dòng chảy. Nếu bản demo, tôi đã thêm một div con khác, để cho thấy chúng được trải ra.

  • space-around, tương tự space-between, nhưng với một nửa không gian ở đầu và cuối dòng chảy.


Giải pháp hoàn hảo. Các trình duyệt không tương thích có thể mất nội dung không được chỉ định và người dùng phải đối phó với nó hoặc nâng cấp trình duyệt của mình.
hai lần vào

0

vertical-alignhoạt động như mong đợi trên mộttd , bạn có thể đặt một ô duy nhất tablevào divđể căn chỉnh nội dung của nó.

<div>
    <table style="width: 100%; height: 100%;"><tr><td style="vertical-align: middle; text-align: center">
        Aligned content here...
    </td></tr></table>
</div>

Clunky, nhưng hoạt động như xa như tôi có thể nói. Nó có thể không có nhược điểm của các cách giải quyết khác.


5
Không, xin vui lòng, không có bảng nữa. CSS có thể làm điều đó một cách sạch sẽ. Không cần sử dụng <bảng> trong trường hợp này.
enguerranws

0

Chỉ cần đặt nội dung bên trong bảng có chiều cao 100% và đặt chiều cao cho div chính

<div style="height:80px;border: 1px solid #000000;">
<table style="height:100%">
<tr><td style="vertical-align: middle;">
  This paragraph should be centered in the larger box
</td></tr>
</table>
</div>

0

Để định tâm theo chiều dọc một phần tử span hoặc div trong div khác, hãy thêm vị trí tương ứng với div cha và vị trí tuyệt đối với div con. Bây giờ div con có thể được định vị ở bất cứ đâu trong div. Ví dụ bên dưới trung tâm theo cả chiều ngang và chiều dọc.

<div class="parent">
    <div class="child">Vertically and horizontally centered child div</div>
</div>

css:

.parent{
    position: relative;
}
.child{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

0

Đây là một cách tiếp cận hiện đại và nó sử dụng chức năng CSS Flexbox. Bây giờ bạn có thể căn chỉnh theo chiều dọc nội dung trong vùng chứa cha mẹ của mình bằng cách thêm các kiểu này vào vùng .mainchứa

.main {
        display: flex;
        flex-direction: column;
        justify-content: center;
}

Và bạn tốt để đi!

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.