Chrome / Safari không lấp đầy 100% chiều cao của cha mẹ flex


235

Tôi muốn có một menu dọc với chiều cao cụ thể.

Mỗi đứa trẻ phải điền vào chiều cao của cha mẹ và có văn bản căn giữa.

Số lượng trẻ em là ngẫu nhiên, vì vậy tôi phải làm việc với các giá trị động.

Div .containerchứa một số lượng con ( .item) ngẫu nhiên luôn phải lấp đầy chiều cao của cha mẹ. Để đạt được điều đó tôi đã sử dụng flexbox.

Để tạo liên kết với văn bản được căn chỉnh đến giữa tôi đang sử dụng display: table-cellkỹ thuật. Nhưng sử dụng bảng hiển thị yêu cầu sử dụng chiều cao 100%.

Vấn đề của tôi .item-inner { height: 100% }là không hoạt động trong webkit (Chrome).

  1. Có một sửa chữa cho vấn đề này?
  2. Hoặc có một kỹ thuật khác nhau để làm cho tất cả .itemlấp đầy chiều cao của cha mẹ với văn bản dọc được căn chỉnh đến giữa?

Ví dụ ở đây jsFiddle, nên được xem trong Firefox và Chrome

.container {
  height: 20em;
  display: flex;
  flex-direction: column;
  border: 5px solid black
}
.item {
  flex: 1;
  border-bottom: 1px solid white;
}
.item-inner {
  height: 100%;
  width: 100%;
  display: table;
}
a {
  background: orange;
  display: table-cell;
  vertical-align: middle;
}
<div class="container">
  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>
</div>



3
Điều này không liên quan cụ thể đến OP, nhưng có thể phù hợp với những người làm việc ở đây vì "safari hiển thị chiều cao tuyệt đối 100% không hoạt động" hoặc một cái gì đó tương tự. Tôi có một yếu tố như thế này bên trong một thùng chứa flex và phải chỉ định top:0left:0để nó xuất hiện như mong đợi.
AlexMA

1
@vsync chưa được sửa chữa: stackoverflow.com/questions/46226298/
Khăn

Câu trả lời:


408

Giải pháp

Sử dụng container flex lồng nhau.

Loại bỏ chiều cao phần trăm. Loại bỏ các thuộc tính bảng. Loại bỏ vertical-align. Tránh định vị tuyệt đối. Chỉ cần gắn bó với flexbox tất cả các cách thông qua.

Áp dụng display: flexcho mục flex ( .item), làm cho nó trở thành một thùng chứa flex. Điều này tự động thiết lập align-items: stretch, cho biết đứa trẻ ( .item-inner) mở rộng toàn bộ chiều cao của cha mẹ.

Quan trọng: Loại bỏ độ cao đã chỉ định khỏi các mục flex để phương thức này hoạt động. Nếu một đứa trẻ có chiều cao được chỉ định (ví dụ height: 100%), thì nó sẽ bỏ qua việc align-items: stretchđến từ cha mẹ. Để stretchmặc định hoạt động, chiều cao của trẻ phải tính toán auto (giải thích đầy đủ ).

Hãy thử điều này (không thay đổi HTML):

bản demo jsFiddle


Giải trình

Vấn đề của tôi .item-inner { height: 100% }là không hoạt động trong webkit (Chrome).

Nó không hoạt động vì bạn đang sử dụng chiều cao phần trăm theo cách không phù hợp với cách triển khai truyền thống của thông số kỹ thuật.

10.5 Chiều cao nội dung: heighttài sản

phần trăm
Chỉ định chiều cao phần trăm. Tỷ lệ phần trăm được tính tương ứng với chiều cao của khối chứa hộp được tạo. Nếu chiều cao của khối chứa không được chỉ định rõ ràng và phần tử này không được định vị tuyệt đối, giá trị sẽ được tính auto.

auto
Chiều cao phụ thuộc vào giá trị của các thuộc tính khác.

Nói cách khác, để phần trăm chiều cao hoạt động trên một đứa trẻ đang chảy, cha mẹ phải có chiều cao được đặt.

Trong mã của bạn, bộ chứa cấp cao nhất có chiều cao được xác định: .container { height: 20em; }

Container cấp ba có chiều cao xác định: .item-inner { height: 100%; }

Nhưng giữa chúng, thùng chứa cấp hai - .item- không có chiều cao xác định. Webkit xem đó là một liên kết còn thiếu.

.item-innerđang nói với Chrome: hãy cho tôiheight: 100% . Chrome tìm đến phụ huynh ( .item) để tham khảo và trả lời: 100% là gì? Tôi không thấy gì cả (bỏ qua flex: 1quy tắc đó). Kết quả là, nó được áp dụng height: auto(chiều cao nội dung), phù hợp với thông số kỹ thuật.

Mặt khác, Firefox hiện chấp nhận chiều cao linh hoạt của cha mẹ làm tài liệu tham khảo cho chiều cao phần trăm của trẻ. IE11 và Edge cũng chấp nhận độ cao flex.

Ngoài ra, Chrome sẽ chấp nhận flex-growlàm tài liệu tham khảo chính đầy đủ nếu được sử dụng cùng vớiflex-basis (mọi giá trị số hoạt động ( autosẽ không), bao gồm flex-basis: 0). Tuy nhiên, khi viết bài này, giải pháp này thất bại trong Safari.


Bốn giải pháp

1. Chỉ định chiều cao cho tất cả các phần tử cha

Một giải pháp đa trình duyệt đáng tin cậy là chỉ định chiều cao cho tất cả các phần tử cha. Điều này ngăn chặn các liên kết bị thiếu, mà các trình duyệt dựa trên Webkit coi là vi phạm thông số kỹ thuật.

Lưu ý rằng min-heightmax-heightkhông được chấp nhận. Nó phải là heighttài sản.

Thêm chi tiết tại đây: Làm việc với các heightgiá trị phần trăm và thuộc tính CSS

2. Định vị tương đối và định vị CSS

Áp dụng position: relativecho cha mẹ và position: absolutecho trẻ.

Kích đứa trẻ với height: 100%width: 100%, hoặc sử dụng các tính chất bù đắp: top: 0, right: 0, bottom: 0, left: 0.

Với định vị tuyệt đối, phần trăm chiều cao hoạt động mà không có chiều cao được chỉ định trên cha mẹ.

3. Xóa các thùng chứa HTML không cần thiết (được khuyến nghị)

Có cần hai container xung quanh buttonkhông? Tại sao không loại bỏ .itemhoặc .item-inner, hoặc cả hai? Mặc dù buttoncác yếu tố đôi khi thất bại như container flex , chúng có thể là các vật phẩm flex. Xem xét việc tạo ra buttonmột đứa trẻ của .containerhoặc .item, và loại bỏ đánh dấu vô cớ.

Đây là một ví dụ:

4. Container Flex lồng nhau (khuyên dùng)

Loại bỏ chiều cao phần trăm. Loại bỏ các thuộc tính bảng. Thoát khỏivertical-align. Tránh định vị tuyệt đối. Chỉ cần gắn bó với flexbox tất cả các cách thông qua.

Áp dụng display: flexcho mục flex (.item), làm cho nó trở thành một thùng chứa flex. Điều này tự động thiết lập align-items: stretch, cho biết đứa trẻ ( .item-inner) mở rộng toàn bộ chiều cao của cha mẹ.

Quan trọng: Loại bỏ độ cao đã chỉ định khỏi các mục flex để phương thức này hoạt động. Nếu một đứa trẻ có chiều cao được chỉ định (ví dụ height: 100%), thì nó sẽ bỏ qua việc align-items: stretchđến từ cha mẹ. Để stretchmặc định hoạt động, chiều cao của trẻ phải tínhauto (giải thích đầy đủ ).

Hãy thử điều này (không thay đổi HTML):

jsFiddle


3
Tôi đã khắc phục sự cố của mình bằng chiều cao: auto
Alfrex92

chỉ một số nhận xét được lấy từ liên kết giải thích của bài đăng tuyệt vời này - "align-items: Stretch" làm cho trẻ em flex mở rộng qua trục chéo của container - nghĩa là kéo trẻ em lên chiều cao, thùng chứa flex phải có hướng uốn cong như hàng.
littlewhywhat

3
Tôi có thể xác nhận rằng sử dụng container flex lồng nhau hoạt động tốt nhất. Chúng tôi sử dụng flexbox không nhất quán trong menu của chúng tôi. Thay vì sử dụng flex: 1 và hiển thị: flex trên các thùng chứa cha mẹ, chúng tôi đã sử dụng chiều cao: 100% tại một số nơi. Mọi thứ hoạt động như mong đợi sau khi chúng tôi thay thế các định nghĩa tương ứng. Cảm ơn @Michael_B đã gợi ý! :)
flocbit

1
@JamesHarrington, CSS đã phát triển theo thời gian và rất phức tạp ;-)
DerMike

Mỗi giải pháp nên là một câu trả lời khác nhau. Làm thế nào tôi có thể bỏ phiếu trong một giải pháp cụ thể theo cách này?
Jp_

14

Giải pháp: Xóa height: 100%trong .item-bên trong và thêm display: flexvào .item

Bản trình diễn: https://codepen.io/tronghiep92/pen/NvzVoo


Cảm ơn, điều này đã giúp tôi. Có phải trẻ em flex tự động kéo dài đến chiều cao của container của họ? Đây có phải là lý do tại sao điều này làm việc?
Reece Kenney

@ReeceKenney, vâng, cho câu hỏi của bạn. Điều này được giải thích trong câu trả lời của tôi. Xem giải pháp số 4.
Michael Benjamin

10

Chỉ định một thuộc tính flex cho vùng chứa làm việc cho tôi:

.container {
    flex: 0 0 auto;
}

Điều này đảm bảo chiều cao được thiết lập và không tăng trưởng.


6

Đối với Mobile Safari Có bản sửa lỗi Trình duyệt. bạn cần thêm -webkit-box cho thiết bị iOS.

Ví dụ.

display: flex;
display: -webkit-box;
flex-direction: column;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
align-items: stretch;

nếu bạn đang sử dụng thuộc align-items: stretch;tính cho phần tử cha, hãy xóa height : 100%phần tử con.


2

Tôi đã gặp sự cố tương tự trong iOS 8, 9 và 10 và thông tin ở trên không thể khắc phục được, tuy nhiên tôi đã phát hiện ra giải pháp sau một ngày làm việc này. Được cho là nó sẽ không hoạt động cho tất cả mọi người nhưng trong trường hợp của tôi, các mục của tôi được xếp chồng lên nhau trong một cột và có 0 chiều cao khi đáng lẽ nó phải là chiều cao nội dung. Chuyển css thành hàng và bọc đã khắc phục sự cố. Điều này chỉ hoạt động nếu bạn có một mục duy nhất và chúng được xếp chồng lên nhau nhưng vì tôi phải mất một ngày để tìm ra điều này nên tôi nghĩ tôi nên chia sẻ cách khắc phục của mình!

.wrapper {
    flex-direction: column; // <-- Remove this line
    flex-direction: row; // <-- replace it with
    flex-wrap: wrap; // <-- Add wrapping
}

.item {
    width: 100%;
}

0

Tôi đã có một lỗi tương tự, nhưng trong khi sử dụng một số cố định cho chiều cao và không phải là tỷ lệ phần trăm. Nó cũng là một thùng chứa flex trong cơ thể (không có chiều cao được chỉ định). Có vẻ như trên Safari, container flex của tôi có chiều cao 9px vì một số lý do, nhưng trong tất cả các trình duyệt khác, nó hiển thị đúng chiều cao 100px được chỉ định trong biểu định kiểu.

Tôi đã quản lý để làm cho nó hoạt động bằng cách thêm cả thuộc tính heightmin-heightthuộc tính vào lớp CSS.

Phần sau hoạt động với tôi trên cả Safari 13.0.4 và Chrome 79.0.3945.130:

.flex-container {
  display: flex;
  flex-direction: column;
  min-height: 100px;
  height: 100px;
}

Hi vọng điêu nay co ich!

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.