Tại sao tỷ lệ phần trăm lề / phần đệm trong CSS luôn được tính theo chiều rộng?


130

Nếu bạn xem thông số mô hình hộp CSS , bạn sẽ tuân thủ các điều sau:

Tỷ lệ phần trăm [lề] được tính theo chiều rộng của khối chứa hộp được tạo. Lưu ý rằng điều này cũng đúng với 'lề trên' và 'lề dưới'. Nếu chiều rộng của khối chứa phụ thuộc vào thành phần này, thì bố cục kết quả không được xác định trong CSS 2.1. (nhấn mạnh của tôi)

Điều này thực sự đúng. Nhưng tại sao ? Điều gì trên trái đất sẽ buộc bất cứ ai thiết kế nó theo cách này? Thật dễ dàng để nghĩ ra các kịch bản mà bạn muốn, ví dụ một điều nhất định luôn giảm 25% so với đầu trang, nhưng thật khó để đưa ra bất kỳ lý do nào khiến bạn muốn đệm dọc có liên quan đến kích thước ngang của cha mẹ

Đây là một ví dụ về hiện tượng tôi đang đề cập đến:

<div style="border: 1px solid red; margin: 0; padding: 0; width: 200px; height: 800px;">
  This div is 200x800.
  <div style="border: 1px solid blue; margin: 10% 0 0 10%;">
    This div has top-margin of 10% and left-margin of 10% with respect to its parent.
  </div>
</div>

http://jsfiddle.net/8JDYD/


3
Suy nghĩ ban đầu của tôi là nó sẽ gây ra sự mơ hồ về ý margin: 25%nghĩa thực sự của nó. Nó sẽ không phải là một lề chẵn, mặc dù mã cho thấy nó là. Tôi không có bằng chứng để sao lưu điều này, nhưng nó có vẻ hợp lý.
Ryan Kinal

4
jsFiddle suy nghĩ của tôi . Chiều cao dễ thay đổi hơn nhiều so với chiều rộng, do đó, nó sẽ làm cho lề thay đổi theo những cách khó dự đoán mỗi khi nội dung thay đổi.
RichardTowers

1
@Ryan: Đó là sự thật, nó sẽ không phải là một lề chẵn, nhưng một lần nữa, nếu bạn nói height: 10%; width: 10%bạn cũng sẽ không nhận được một phần tử vuông.
mqp

4
Theo dev.w3.org/csswg/css3-box/#the-margin-properies, nó nêu rõ Note that in a horizontal flow, percentages on ‘margin-top’ and ‘margin-bottom’ are relative to the width of the containing block, not the height (and in vertical flow, ‘margin-left’ and ‘margin-right’ are relative to the height, not the width).cả hai cách
Adam Sweeney

1
@Ryan Tôi nghĩ chúng ta có một người chiến thắng. Looky đây cho một bản demo - jsFiddle
RichardTowers

Câu trả lời:


60

Chuyển nhận xét của tôi để trả lời, bởi vì nó có ý nghĩa logic. Tuy nhiên, xin lưu ý rằng đây là phỏng đoán vô căn cứ. Lý do thực tế tại sao thông số kỹ thuật được viết theo cách này vẫn còn, về mặt kỹ thuật, chưa biết.

Chiều cao yếu tố được xác định bởi chiều cao của trẻ em. Nếu một phần tử có phần đệm trên cùng: 10% (so với chiều cao của cha mẹ), điều đó sẽ ảnh hưởng đến chiều cao của cha mẹ. Vì chiều cao của trẻ phụ thuộc vào chiều cao của bố mẹ và chiều cao của bố mẹ phụ thuộc vào chiều cao của trẻ, chúng ta sẽ có chiều cao không chính xác hoặc vòng lặp vô hạn. Chắc chắn, điều này chỉ ảnh hưởng đến trường hợp bù cha mẹ === cha, nhưng vẫn. Đó là một trường hợp kỳ lạ rất khó giải quyết.

Cập nhật: Các câu cuối cùng có thể không hoàn toàn chính xác. Chiều cao của yếu tố lá (trẻ không có con) có ảnh hưởng đến chiều cao của tất cả các yếu tố trên nó, vì vậy điều này ảnh hưởng đến nhiều tình huống khác nhau.


1
Lưu ý rằng có các ngoại lệ cho quy tắc này - phần 10.6 của CSS2.1 bao gồm gần như tất cả các trường hợp tính toán độ cao cho các loại hộp khác nhau. Và thực tế, các trường hợp liên quan đến sự phụ thuộc giữa cha mẹ và con cái về chiều cao có xu hướng dẫn đến hành vi không xác định.
BoltClock

1
@sanjaypoyzer Tôi đoán trong trường hợp đơn giản nhất là các trình duyệt tính toán độ rộng khối từ bên ngoài vào trong (từ gốc đến mẹo), sau đó chuyển nội dung vào các khối đó để xác định độ cao của chúng (mẹo để root).
sam

9
Tại sao W3C liên tục làm điều này? Rõ ràng 'ngữ nghĩa' đối với W3C tương đương với việc phải phục vụ cho những người không thể suy nghĩ logic, điều này vô nghĩa. Nó giống như phàn nàn về việc những người khó hiểu và ngu ngốc trên thế giới sau đó lan truyền thêm sự nhầm lẫn và ngu ngốc như thế nào. Lý do bạn cung cấp không có ý nghĩa: cùng một lý lẽ áp dụng cho chiều rộng, nhưng điều đó chỉ hoạt động tốt. Tất cả những gì cần thiết là đặt bối cảnh và hướng xác định độ cao, trừ khi chiều cao của cha mẹ được đặt bằng pixel hoặc thứ gì đó không thay đổi, thì không có vấn đề gì.
u353

3
Sự phụ thuộc đó là một công thức đại số có một giải pháp và sẽ không dẫn đến một vòng lặp vô hạn trừ khi bạn chọn giải quyết nó theo cách không tôn trọng điều này. Nói chiều cao bố mẹ là h_p. Một phần đệm trên 10% sẽ làm cho chiều cao của trẻ h_c = h_ci + 0.1h_p, h_cichiều cao bên trong của trẻ và không phụ thuộc vào chiều cao của cha mẹ. Đối với một đứa trẻ, bạn chỉ cần tìm chiều cao cha mẹ từ phương trình h_p = h_ci + 0.1h_p=> h_p = h_ci / 0.9. Bạn luôn có thể làm điều này, bất kể bạn có bao nhiêu con, ngay cả đối với phần đệm khác nhau. Nó chỉ là một ẩn số ( h_p) và một phương trình.
jeteon

2
Tôi không nghĩ tính toán vô hạn là lý do. Một lý do đơn giản là: sử dụng widthkết quả trong cùng một vấn đề theo chiều ngang.
Niềm vui

30

Để lề "n%" (và phần đệm) giống nhau cho lề-đỉnh / lề-phải / lề-dưới / lề-trái, cả bốn phải có cùng một cơ sở. Nếu trên / dưới sử dụng một cơ sở khác với bên trái / bên phải ', thì "n%" lề (và phần đệm) sẽ không có nghĩa giống nhau ở cả bốn phía.

(Cũng lưu ý rằng có lề trên / dưới so với chiều rộng cho phép hack CSS kỳ lạ cho phép bạn chỉ định một hộp có tỷ lệ khung hình không thay đổi ... ngay cả khi hộp được định cỡ lại.)


... một câu trả lời đơn giản đến bất ngờ. Mặc dù tất cả các phỏng đoán ở trên đều có giá trị, đây là một điểm khá tốt. Có vẻ như có thể là một trường hợp trong đó nhiều giải pháp sẽ đúng vì vậy họ chỉ chọn một giải pháp có khả năng được sử dụng nhiều nhất .... có thể?
dudewad 7/2/2015

1
Tôi cho rằng sẽ rất tốt nếu có một yếu tố phụ trong cú pháp để bạn có thể viết nói padding: n [type]. Vì vậy, bạn sẽ có padding: 5% logical(những gì OP gợi ý) trái ngược padding: 5% widthvới tham số thứ hai mặc định là "chiều rộng" để tương thích ngược.
jeteon

5
"N% lề (và phần đệm) sẽ không có nghĩa giống nhau ở cả bốn phía" - Nhưng tại sao đó lại là một vấn đề?
Herbertusz

4

Tôi bỏ phiếu cho câu trả lời từ @ChuckKollars sau khi chơi với JSFiddle này (trên Chrome 46.0.2490.86) và đề cập đến bài đăng này (viết bằng tiếng Trung Quốc).


Một lý do chính chống lại phỏng đoán tính toán vô hạn là: sử dụng widthphải đối mặt với cùng một vấn đề tính toán vô hạn .

Hãy xem JSFiddle này , parentmàn hình hiển thị inline-block, đủ điều kiện để xác định lề / phần đệm trên nó. Các childcó giá trị lợi nhuận 20%. Nếu chúng ta theo phỏng đoán tính toán vô hạn :

  1. Chiều rộng của childphụ thuộc vàoparent
  2. Chiều rộng của parentphụ thuộc vàochild

Nhưng kết quả là Chrome dừng tính toán ở đâu đó, kết quả là:

nhập mô tả hình ảnh ở đây

Nếu bạn cố gắng mở rộng bảng "kết quả" theo chiều ngang trên JSFiddle, bạn sẽ thấy rằng chiều rộng của chúng sẽ không thay đổi. Xin lưu ý rằng nội dung trong childđược gói thành hai dòng (không, nói, một dòng), tại sao? Tôi đoán Chrome chỉ khó mã hóa nó ở đâu đó. Nếu bạn chỉnh sửa childnội dung để làm cho nó nhiều hơn ( JSFiddle ), bạn sẽ thấy rằng miễn là có thêm không gian theo chiều ngang, Chrome sẽ giữ nội dung hai dòng.

Vì vậy, chúng ta có thể thấy: có một số cách để ngăn chặn tính toán vô hạn .


Tôi đồng ý với phỏng đoán rằng: thiết kế này chỉ để giữ bốn giá trị lề / đệm dựa trên cùng một thước đo.

bài đăng này (viết bằng tiếng Trung Quốc) cũng đề xuất một lý do khác là: đó là do định hướng đọc / sắp chữ. Chúng tôi đọc từ trên xuống dưới, với chiều rộng cố định và chiều cao vô hạn (hầu như).


Điều này là do các trang web cuộn theo chiều dọc theo một hướng chung vô hạn; vì vậy chiều rộng có thể được tính từ chiều rộng của cửa sổ trình duyệt. Các yếu tố duy nhất rộng hơn màn hình là nếu bạn chỉ định chiều rộng của chúng lớn hơn. Các yếu tố khối điển hình là chiều rộng 100% và mở rộng tự động theo hướng dọc (không xác định). Đó là lý do tại sao chiều rộng không có cùng một vấn đề.
Lucent Fox

3

Tôi nhận ra OP đang hỏi tại sao đặc tả CSS xác định tỷ lệ phần trăm lề trên / dưới là% chiều rộng (và không, như sẽ được giả định, chiều cao), nhưng tôi nghĩ rằng nó cũng có thể hữu ích để đăng một giải pháp tiềm năng.

Hầu hết các trình duyệt hiện đại đều hỗ trợ vw và vh ngay bây giờ cho phép bạn chỉ định số lề so với chiều rộng của khung nhìn và chiều cao của khung nhìn.

100vw / 100vh tương đương 100% chiều rộng / 100% chiều cao (tương ứng) nếu không có thanh cuộn; nếu có một thanh cuộn, số lượt xem không chiếm phần này (trong khi số% thì có). Rất may, gần như tất cả các trình duyệt sử dụng kích thước thanh cuộn 17px ( xem tại đây ), vì vậy bạn có thể sử dụng chức năng css calc để giải thích cho việc này. Nếu bạn không biết liệu thanh cuộn sẽ xuất hiện hay không, thì giải pháp này sẽ không hoạt động.

Ví dụ: Giả sử không có thanh cuộn ngang, lề trên 50% chiều cao, có thể được định nghĩa là "lề trên: 50vh;". Với một thanh cuộn ngang, điều này có thể được định nghĩa là "lề-đỉnh: calc (0,5 * (100vh - 17px));" (hãy nhớ rằng các toán tử trừ và cộng trong calc yêu cầu khoảng trắng ở cả hai bên!).


1
Đó là một cách giải quyết hữu ích trong nhiều trường hợp, nhưng có rất nhiều ví dụ mà nó không hoạt động (ví dụ: nếu bạn đang cố gắng làm cho nội dung phù hợp với kích thước của hộp chứa flexbox phát triển để lấp đầy không gian có sẵn trong khi có một hộp khác với nội dung thay đổi).
Jules
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.