Kích thước hộp CSS3: hộp lề; Tại sao không?


139

Tại sao chúng ta không có box-sizing: margin-box;? Thông thường khi chúng tôi đặt box-sizing: border-box;trong các tờ phong cách của chúng tôi, chúng tôi thực sự có nghĩa là trước đây.


Thí dụ:

Giả sử tôi có bố cục trang 2 cột. Cả hai cột có chiều rộng 50%, nhưng chúng trông có vẻ xấu xí vì không có máng xối (khoảng trống ở giữa); Dưới đây là CSS:

.col2 {
    width: 50%;
    float: left;
}


Để áp dụng máng xối, bạn có thể nghĩ rằng chúng ta chỉ cần đặt lề phải trên cột đầu tiên trong số 2 cột; đại loại như thế này:

.col2:first-child {
    margin-right: 24px;
}

Nhưng điều này sẽ làm cho cột thứ hai quấn lên một dòng mới, bởi vì điều sau đây là đúng:

50% + 50% + 24px > 100%

box-sizing: margin-box;sẽ giải quyết vấn đề này bằng cách bao gồm lề trong chiều rộng tính toán của phần tử. Tôi sẽ thấy điều này rất hữu ích nếu không hữu ích hơn box-sizing: border-box;.


30
"Tại sao chúng ta không có box-sizing: margin-box;?" Bởi vì trong khi lề ngang không sụp đổ, một đề xuất như vậy sẽ can thiệp nghiêm trọng đến sự sụp đổ lề dọc. Dù sao, nếu bạn muốn đề xuất một cái gì đó cho tiêu chuẩn hóa, Stack Overflow không phải là nơi thích hợp. Hãy thử danh sách gửi thư.
BoltClock

16
Trong một số trường hợp nhất định, bạn có thể khắc phục điều này bằng cách sử dụng border: xxx solid transparent;, vì đường viền được bao gồm trong border-box. Điều này sẽ phá vỡ một số thứ khác mặc dù, chẳng hạn như box-shadow.
Nathan Osman

28
Bây giờ chúng ta có đóng tất cả các câu hỏi về các tiêu chuẩn là "không mang tính xây dựng" không ?? Đó là một câu hỏi công bằng để hỏi và thậm chí nó có một câu trả lời đơn giản: chúng tôi không có box-sizing: margin-boxvì nó sẽ không hoạt động với sự sụp đổ lề.
thomasrutter

@thomasrutter: Không có lý do nào tốt hơn cho nó tại thời điểm tôi đóng nó, đó là hơn một năm trước. Dù sao, "không mang tính xây dựng" đã biến mất ngay bây giờ (có nghĩa là không, chúng tôi thực sự không đóng bất cứ thứ gì là không mang tính xây dựng nữa) và vì toàn bộ "Tôi có một ý tưởng, đây là cách nó hoạt động, hãy biến nó thành tiêu chuẩn!" điều này đã bị xóa kể từ lần đóng cuối cùng, bây giờ nó thực sự nghe có vẻ thực tế "tại sao X không thể hoạt động?" câu hỏi Đây vẫn là một câu hỏi cực kỳ khó đoán (lý luận của tôi ở trên thực sự không có gì khác hơn là một phỏng đoán có giáo dục), nhưng tôi không bình luận gì thêm về điều đó.
BoltClock

tại sao không chỉ có một bọc bên trong / div nếu bạn muốn khoảng cách: codepen.io/chriscoyier/pen/eGcLw
ashley

Câu trả lời:


55

Bạn không thể sử dụng width: calc(50% - 24px);cho cols của bạn? Sau đó thiết lập lề của bạn.


5
Nó phụ thuộc nhiều vào trình duyệt. Có lẽ vào khoảng năm 2020, tức là15 sẽ hỗ trợ nó và bạn cũng sẽ được phép sử dụng nó trong công việc của mình :-(
peterh - Tái lập Monica

1
Có vẻ như không hoạt động tốt trong Firefox? (hoặc những thứ khác tôi đã làm không)
Laurengineer

@Morgan Feeney: Vâng, nhưng kích thước hộp không có giá trị được gọi là hộp lề (đó là toàn bộ điểm của câu hỏi này). Ngay cả khi một giá trị như vậy được giới thiệu ngay bây giờ, làm thế nào để bạn đề xuất vá / polyfilling / shinkle nó vào các trình duyệt hiện có?
BoltClock

Vâng nhưng ... cụ thể là trả lời một câu trả lời gợi ý calc () như một cách giải quyết.
Morgan Feeney

Không chắc chắn nếu điều này áp dụng cho ví dụ cụ thể nhưng tiêu cực chính đối với việc sử dụng calc () trong kịch bản của chúng tôi (như tại FF 53.0.3) là hành vi của nó không giống với chiều rộng: X%; Từ những gì chúng ta có thể thấy "calc" được thực hiện tại thời điểm kết xuất ban đầu thành Xpx tĩnh. Điều này có nghĩa là không giống như chiều rộng: X%, cột calc'ed không tự động thay đổi kích thước với thay đổi kích thước vùng chứa.
Pancho

16

Tôi nghĩ rằng chúng ta có thể có một box-sizing: margin-box . Mô hình hộp css hiển thị chính xác, vị trí của các lề của khung là gì.

Có một số vấn đề nhỏ - ví dụ, các hộp lề có thể chồng lấp - nhưng chúng không khó giải quyết.

Tôi nghĩ, tình huống là như nhau, như chúng ta có thể thấy với các kết hợp overflow-x& overflow-y, với các div được định vị tuyệt đối trong các ô của bảng, với sự kết hợp của min | max-width | height với kích thước hộp, v.v.

Có những tính năng, những tính năng thực sự đơn giản, mà các nhà phát triển trình duyệt đơn giản là không phát triển.

IMHO, box-sizing: margin-boxlà một tính năng rất hữu ích. Một tính năng hữu ích khác là box-sizing: padding-box, nó tồn tại ít nhất trong tiêu chuẩn, nhưng nó không được triển khai trong bất kỳ trình duyệt chính nào. Ngay cả trong chrome mới nhất!


Lưu ý: Nhận xét của @Oriol: Firefox đã triển khai kích thước hộp: padding-box. Nhưng những người khác thì không, và nó đã bị xóa khỏi thông số kỹ thuật. Firefox sẽ xóa nó trong phiên bản 50. Buồn.


2
Firefox đã thực hiện box-sizing: padding-box. Nhưng những người khác thì không, và nó đã bị xóa khỏi thông số kỹ thuật. Firefox sẽ xóa nó trong phiên bản 50. Buồn.
Oriol

6

Anh chàng ở phía trên đang hỏi về việc thêm lề vào chiều rộng tổng thể, bao gồm cả phần đệm và đường viền. Vấn đề là, lề được áp dụng bên ngoài hộp và phần đệm và đường viền không, khi sử dụngborder-box .

Tôi đã cố gắng để đạt được border-marginý tưởng. Những gì tôi đã tìm thấy là nếu sử dụng lề, bạn có thể thêm một lớp .lastvào mục cuối cùng (với lề, sau đó áp dụng lề bằng 0 hoặc sử dụng :last-child/:last-of-type). Hoặc thêm các lề bằng nhau (tương tự như phiên bản đệm ở trên).

Xem ví dụ tại đây: http://codepen.io/mofeenster/pen/Anidc

border-boxtính chiều rộng của phần tử + phần đệm của nó + đường viền của nó là tổng chiều rộng. Vì vậy, nếu bạn có 2 divs rộng 50%, chúng sẽ liền kề nhau. Nếu bạn thêm phần 8pxđệm cho chúng, thì bạn sẽ có một máng xối 16px. Kết hợp điều đó với một yếu tố bao bọc - cũng có phần đệm8px - bạn sẽ có một lưới được bố trí độc đáo với máng xối bằng nhau trên khắp đường.

Xem ví dụ này tại đây: http://codepen.io/mofeenster/pen/vGgje

Thứ hai là phương pháp yêu thích của tôi.


4

Tôi chắc chắn tất cả những điều này là rõ ràng, nhưng dù sao tôi cũng sẽ loại nó ra bởi vì ... tốt, tôi cần tập thể dục. Kết quả sau đây sẽ không hiệu quả như box-sizing: margin-box;:

.col2 {
    width: 45%;
    height: 90%;
    margin: 5% 2.5%;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    float: left;
}

http://jsfiddle.net/Fg3hg/

box-sizingđược sử dụng để kiểm soát từ điểm đệm và đường viền được đánh giá theo kích thước tổng thể của phần tử. Vì vậy, mặc dù không bao gồm các pxlề có %chiều rộng (thường là như vậy), việc tính toán tỷ lệ phần trăm tương đối sẽ là bao nhiêu vì bạn không phải kết hợp phần đệm và viền với chiều rộng đã xác định.


9
Trường hợp sử dụng cho một cái gì đó như hộp lề là để cho phép trộn độ rộng phần trăm với lề pixel. Nếu bạn muốn hai hộp 50% có lề 1px giữa chúng, điều này không thể thực hiện được với tỷ lệ phần trăm là 1% tương tự - một số kích thước màn hình nhỏ sẽ làm tròn 1% xuống 0 pixel và đột nhiên bạn không có lề. Những gì chúng tôi thực sự cần là hỗ trợ nhiều trình duyệt hơn cho calc () như các chương trình @Slouch hoặc mô hình flexbox.

1
Nếu đó là sự quan tâm, thùng chứa cha mẹ sẽ nhỏ hơn 100px và tôi hy vọng một số yếu tố thiết kế sẽ được nghĩ lại vào thời điểm đó. Có một số điều khác bạn có thể làm với các phần tử lồng nhau và tương tự, nhưng, vâng, có các phép tính biến sẽ khá dope. Nếu bạn thích những thứ như sass hoặc ít hơn, tôi nghĩ họ làm rất nhiều thứ này. Tôi đã chơi xung quanh với họ, nhưng chưa phải là Jedi.
Plummer

2
Những gì bạn đang đề xuất là một công việc xung quanh. Đây không phải là một cách lý tưởng để viết CSS khi bạn đang làm việc với các bố cục phức tạp. Bạn đang giả định rằng nhà thiết kế hoặc tác giả muốn sử dụng tỷ lệ phần trăm trong thiết kế của họ. Ngoài ra, bất kể vấn đề này là gì, ngay cả khi bạn sử dụng hàm calc () để tính toán khoảng cách bằng cách sử dụng lề pixel, nó vẫn giới hạn người thiết kế vì họ phải xác định trước máng xối là gì, thay vì cho phép ghi đè bằng CSS.
Unlimitedlessloop

Tôi không hiểu quan điểm của bạn. Vấn đề hiện tại là bao gồm px và% gây ra ngắt dòng vì lề không được bao gồm trong tính toán kích thước. Một lề không được bao gồm trong kích thước của một yếu tố, đó là không gian bạn muốn xuất hiện xung quanh một yếu tố. Thêm vào đó, làm thế nào để margin-boxxử lý các tính toán biên đa chiều? @mediađiểm dừng, max-widthmin-widthlàm việc tốt. Tôi đoán margin-boxcó thể cắt giảm một số sưng lên, nhưng tôi cũng có được lý do tại sao nó có thể được coi là dư thừa.
Plummer

Tại sao không ai đề cập rằng tỷ lệ phần trăm này GIÁ TRỊ là phần trăm chiều rộng vì một số lý do ... không quan trọng chiều cao hoặc chiều rộng. Chiều rộng của cha mẹ được sử dụng. Đó là bizzare để nói rằng ít nhất .. vì vậy mã ở trên không nên hoạt động và không hoạt động. trừ khi bạn làm cho chiều cao và chiều rộng bằng nhau.
Muhammad Umer

4

Điều này là do thuộc tính kích thước hộp đề cập đến kích thước của một phần tử sau khi tính toán các giá trị cụ thể về kích thước cụ thể (phần đệm, đường viền). "Box-sizing: Border-box" đặt chiều cao / chiều rộng của một phần tử và xem xét phần đệm cũng như chiều rộng đường viền. Phạm vi lề của một phần tử lớn hơn chính phần tử đó, có nghĩa là nó điều chỉnh dòng chảy của trang và các phần tử xung quanh, do đó trực tiếp thay đổi cách phần tử khớp với cha mẹ của nó so với các phần tử anh chị em của nó. Cuối cùng, giá trị thuộc tính "hộp lề" sẽ gây ra vấn đề lớn và về cơ bản giống như đặt trực tiếp chiều cao / chiều rộng của các phần tử.


1
tôi xin lỗi nhưng tôi không hiểu cách bao gồm phần đệm, đường viền và lề trong tính toán không gian thông qua "hộp lề" sẽ khác về mặt khái niệm với việc bao gồm phần đệm và đường viền thông qua "hộp viền". Chắc chắn đó chỉ là một biến thể trong cùng một chủ đề?
Pancho

1

Trên Codrops, có một vài bài viết hay về chủ đề ảnh hưởng của lề và hàng bị buộc phải tràn. Họ đề nghị sử dụng đơn vị rem hoặc em với kích thước phông chữ css của trình chuẩn hóa thành 100% cho tất cả các trình duyệt, sau đó khi bạn đặt độ rộng và lề, bạn có thể dễ dàng theo dõi hiệu ứng trên chiều rộng của hàng bằng cách chỉ cần ghi chú trong các nhận xét cho tổng chiều rộng. Chuyển đổi 16px thành 1 em là cách để thu hẹp tổng số lượt xem được nhắm mục tiêu.

Làm việc như vậy đối với giai đoạn nhà phát triển ít nhất và sau đó nếu bạn muốn các mẫu 'phản hồi', bạn có thể chuyển đổi độ rộng thành% bao gồm cả độ rộng lề.

Một cách khác và thường đơn giản hơn mà họ đề xuất để xử lý máng xối là sử dụng giả sau và content: '';trên mỗi cột của bạn mà tôi thấy hoạt động rất tốt. Nếu bạn đặt một lớp div là cột cuối cùng được xác định, chẳng hạn như kết thúc, thì bạn có thể nhắm mục tiêu lớp đó không có giả sau hoặc để có một cột rộng hơn; mà phù hợp nhất với bố cục của bạn.

Phần thưởng thêm vào khi sử dụng phương pháp phần tử giả này là nó cũng cung cấp cho bạn mục tiêu cho các bóng có thể mang lại hiệu ứng 3d và độ sâu lớn hơn cho hình ảnh phẳng trên màn hình của trình đọc. Tôi đang thử nghiệm hiệu ứng này vào lúc này bằng cách nhân rộng các hiệu ứng đang được sử dụng trên các nút, 'điều chỉnh' độ dốc và chỉ số z.


1

Kích thước của các yếu tố cấp khối, không thay thế trong luồng bình thường phải đáp ứng

lề-trái + viền-trái-chiều rộng + đệm-trái + chiều rộng + đệm-phải + viền-phải-rộng + lề-phải = chiều rộng của khối chứa

Khi bị hạn chế quá mức, các trình duyệt phải điều chỉnh lề trái hoặc lề phải. Tôi nghĩ điều đó có nghĩa là chiều rộng của hộp lề phải bằng chiều rộng của khối chứa (tức là 100%).

Đối với trường hợp của bạn, đường viền trong suốt có box-sizing: border-boxthể hoạt động giống như lề .


1

Có lẽ đặt đường viền thành độ mờ 0% bằng RGBA và sử dụng đường viền làm lề.


Âm thanh như một hack, nhưng sẽ làm công việc.
Morgan Feeney

Điều này có thể hữu ích nếu bạn không muốn sử dụng trình bao bọc để đạt được công việc.
Unlimitedlessloop

... trừ khi bạn thực sự cần một đường viền
FrancescoMM

@FrancescoMM - hơi "ồn ào", nhưng bạn có thể tạo một hộp có viền trong suốt "lề rộng" (và dĩ nhiên không có lề) và bên trong đó đặt một hộp có viền hiển thị chiều rộng bạn muốn hiển thị (một lần nữa không có lề)
Pancho

1
Tôi không thể làm theo kiểu suy nghĩ này. Có điều gì tự nhiên hơn là nói rằng tôi muốn hai hộp 1pxcách nhau, mỗi hộp lấy 50%không gian có sẵn? Đó chính xác là những gì margin-boxsẽ làm. Hoặc quên hộp lề và suy nghĩ về không gian có sẵn. Không phải 50% container mẹ, mà là 50% những gì còn lại. Không "calc", không "5% lợi nhuận", không lộn xộn như vậy ...
maaartinus

0

Có tình huống thú vị khi sử dụng kích thước hộp bên trong nội dung cơ thể

không có nội dung, không có hộp viền nào cho bất kỳ giá trị nào trên lề trái phải% kể lại hai hộp này kể lại algoritms

  .body{
    box-sizing: border-box;
    margin:0 3%;
  }

Các phiên bản Firefox trước 57 cũng hỗ trợ giá trị hộp đệm cho kích thước hộp, mặc dù giá trị này đã bị xóa khỏi đặc tả và các phiên bản mới hơn của trình duyệt.

Vì vậy, hộp lề thậm chí không được lên kế hoạch ...

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.