Layout and the containing block
Kích thước và vị trí của một phần tử thường bị ảnh hưởng bởi containing block của nó. Thông thường, containing block là vùng nội dung của phần tử block-level tổ tiên gần nhất, nhưng điều này không phải lúc nào cũng đúng. Trong bài viết này, chúng ta xem xét các yếu tố xác định containing block của một phần tử.
Khi một user agent (như trình duyệt của bạn) trình bày một tài liệu, nó tạo ra một hộp cho mỗi phần tử. Mỗi hộp được chia thành bốn vùng:
- Vùng nội dung
- Vùng padding
- Vùng border
- Vùng margin

Nhiều developer tin rằng containing block của một phần tử luôn là vùng nội dung của cha của nó, nhưng điều đó không nhất thiết đúng. Hãy điều tra các yếu tố xác định containing block của một phần tử là gì.
Hiệu ứng của containing block
Trước khi tìm hiểu điều gì xác định containing block của một phần tử, việc biết tại sao điều đó quan trọng là hữu ích.
Kích thước và vị trí của một phần tử thường bị ảnh hưởng bởi containing block của nó. Các giá trị phần trăm được áp dụng cho các thuộc tính width, height, padding, margin, và các thuộc tính offset của một phần tử được định vị tuyệt đối (tức là có position được đặt thành absolute hoặc fixed) được tính từ containing block của phần tử.
Xác định containing block
Quá trình xác định containing block phụ thuộc hoàn toàn vào giá trị của thuộc tính position của phần tử:
- Nếu thuộc tính
positionlàstatic,relative, hoặcsticky, containing block được tạo bởi cạnh của content box của phần tử tổ tiên gần nhất là block container (như phần tử inline-block, block, hoặc list-item) hoặc thiết lập một formatting context (như table container, flex container, grid container, hoặc bản thân block container). - Nếu thuộc tính
positionlàabsolute, containing block được tạo bởi cạnh của padding box của phần tử tổ tiên gần nhất có giá trịpositionkhácstatic(fixed,absolute,relative, hoặcsticky). - Nếu thuộc tính
positionlàfixed, containing block được thiết lập bởi viewport (trong trường hợp media liên tục) hoặc vùng trang (trong trường hợp paged media). - Nếu thuộc tính
positionlàabsolutehoặcfixed, containing block cũng có thể được tạo bởi cạnh của padding box của phần tử tổ tiên gần nhất có bất kỳ điều nào sau đây:- Giá trị
filter,backdrop-filter,transform,perspective,rotate,scale, hoặctranslatekhácnone. - Giá trị
containlàlayout,paint,stricthoặccontent(ví dụ:contain: paint;). - Giá trị
container-typekhácnormal. - Giá trị
will-changechứa một thuộc tính mà giá trị không phải ban đầu sẽ tạo thành containing block (ví dụ:filterhoặctransform). - Giá trị
content-visibilitylàauto.
- Giá trị
Note:
Containing block mà phần tử gốc (<html>) tồn tại là một hình chữ nhật được gọi là initial containing block. Nó có kích thước của viewport (đối với media liên tục) hoặc vùng trang (đối với paged media).
Note:
Có sự không nhất quán giữa các trình duyệt với perspective và filter đóng góp vào việc tạo thành containing block.
Tính giá trị phần trăm từ containing block
Như đã lưu ý ở trên, khi một số thuộc tính được cho một giá trị phần trăm, giá trị được tính phụ thuộc vào containing block của phần tử. Các thuộc tính hoạt động theo cách này là thuộc tính box model và thuộc tính offset:
- Các thuộc tính
height,top, vàbottomtính giá trị phần trăm từheightcủa containing block. - Các thuộc tính
width,left,right,padding, vàmargintính giá trị phần trăm từwidthcủa containing block.
Note: Một block container (như phần tử inline-block, block, hoặc list-item) chứa chỉ các hộp inline-level tham gia vào inline formatting context, hoặc chỉ các hộp block-level tham gia vào block formatting context. Một phần tử là block container chỉ khi nó chứa các hộp block-level hoặc inline-level.
Một số ví dụ
Mã HTML cho tất cả các ví dụ của chúng ta là:
<body>
<section>
<p>This is a paragraph!</p>
</section>
</body>
Chỉ có CSS được thay đổi trong mỗi trường hợp dưới đây.
Ví dụ 1
Trong ví dụ này, đoạn văn được định vị tĩnh, vì vậy containing block của nó là <section> vì đó là tổ tiên gần nhất là block container (vì display: block).
body {
background: beige;
}
section {
display: block;
width: 400px;
height: 160px;
background: lightgray;
}
p {
width: 50%; /* == 400px * .5 = 200px */
height: 25%; /* == 160px * .25 = 40px */
margin: 5%; /* == 400px * .05 = 20px */
padding: 5%; /* == 400px * .05 = 20px */
background: cyan;
}
Ví dụ 2
Trong ví dụ này, containing block của đoạn văn là phần tử <body>, vì <section> không phải là block container (vì display: inline) và không thiết lập formatting context.
body {
background: beige;
}
section {
display: inline;
background: lightgray;
}
p {
width: 50%; /* == half the body's width */
height: 200px; /* Note: a percentage would be 0 */
background: cyan;
}
Ví dụ 3
Trong ví dụ này, containing block của đoạn văn là <section> vì position của nó là absolute. Các giá trị phần trăm của đoạn văn bị ảnh hưởng bởi padding của containing block của nó, mặc dù nếu giá trị box-sizing của containing block là border-box thì điều này sẽ không xảy ra.
body {
background: beige;
}
section {
position: absolute;
left: 30px;
top: 30px;
width: 400px;
height: 160px;
padding: 30px 20px;
background: lightgray;
}
p {
position: absolute;
width: 50%; /* == (400px + 20px + 20px) * .5 = 220px */
height: 25%; /* == (160px + 30px + 30px) * .25 = 55px */
margin: 5%; /* == (400px + 20px + 20px) * .05 = 22px */
padding: 5%; /* == (400px + 20px + 20px) * .05 = 22px */
background: cyan;
}
Ví dụ 4
Trong ví dụ này, position của đoạn văn là fixed, vì vậy containing block của nó là initial containing block (trên màn hình, là viewport). Do đó, kích thước của đoạn văn thay đổi dựa trên kích thước của cửa sổ trình duyệt.
body {
background: beige;
}
section {
width: 400px;
height: 480px;
margin: 30px;
padding: 15px;
background: lightgray;
}
p {
position: fixed;
width: 50%; /* == (50vw - (width of vertical scrollbar)) */
height: 50%; /* == (50vh - (height of horizontal scrollbar)) */
margin: 5%; /* == (5vw - (width of vertical scrollbar)) */
padding: 5%; /* == (5vw - (width of vertical scrollbar)) */
background: cyan;
}
Ví dụ 5
Trong ví dụ này, position của đoạn văn là absolute, vì vậy containing block của nó là <section>, là tổ tiên gần nhất có thuộc tính transform khác none.
body {
background: beige;
}
section {
transform: rotate(0deg);
width: 400px;
height: 160px;
background: lightgray;
}
p {
position: absolute;
left: 80px;
top: 30px;
width: 50%; /* == 200px */
height: 25%; /* == 40px */
margin: 5%; /* == 20px */
padding: 5%; /* == 20px */
background: cyan;
}
Xem thêm
allpropertycontainpropertyaspect-ratiopropertybox-sizingpropertymin-contentandmax-contentsize values- Learn: sizing items in CSS
- Box model
- CSS box model module
- Layout modes
- Visual formatting models
- Block formatting context
- Stacking context
- Margin collapsing
- Initial, computed, used, and actual values
- Replaced elements
- Intrinsic size