Podcast CSS – 001: The Box Model
Giả sử bạn có đoạn HTML này:
<p>I am a paragraph of text that has a few words in it.</p>
Sau đó, bạn viết CSS này cho nó:
p {
width: 100px;
height: 50px;
padding: 20px;
border: 1px solid;
}
Nội dung sẽ có chiều rộng là 142px thay vì 100px mà bạn chỉ định và phá vỡ phần tử của bạn. Tại sao lại như vậy?
Mô hình hộp là nền tảng cốt lõi của CSS. Tìm hiểu cách mô hình hộp có hiệu quả, mức độ ảnh hưởng của các khía cạnh khác của CSS đối với dịch vụ này và quan trọng là cách bạn có thể kiểm soát nó, có thể giúp bạn viết CSS dễ dự đoán hơn.
Bạn cần nhớ rằng mọi thông tin mà CSS hiển thị đều là một hộp, ngay cả khi
đó chỉ là một số văn bản hoặc có border-radius
khiến nó trông giống như một vòng tròn.
Nội dung và kích thước
Các hộp có hành vi khác nhau dựa trên giá trị display
của chúng, tập hợp của chúng
và nội dung của chúng. Nội dung này có thể là văn bản thuần tuý hoặc
nhiều hộp hơn do các phần tử con tạo. Dù bằng cách nào thì nội dung cũng ảnh hưởng đến kích thước
của hộp theo mặc định.
Bạn có thể kiểm soát điều này bằng cách sử dụng kích thước bên ngoài hoặc bạn có thể sử dụng kích thước nội tại để trình duyệt đưa ra quyết định giúp bạn dựa trên kích thước nội dung.
Dưới đây là bản minh hoạ cơ bản giải thích sự khác biệt:
Bản minh hoạ có dòng chữ "CSS thật tuyệt vời" trong một chiếc hộp có kích thước cố định và
đường viền dày. Do hộp có chiều rộng được chỉ định, nên nó có kích thước bên ngoài.
Tức là chính sách này kiểm soát kích thước của nội dung con. Tuy nhiên, từ
"tuyệt vời" quá lớn so với hộp nên hộp tràn ra ngoài hộp đựng
hộp biên giới (sẽ trình bày thêm về nội dung này ở phần sau). Một cách để ngăn chặn tình trạng tràn này là cho phép
hộp phải có kích thước nội tại bằng cách không đặt chiều rộng hoặc trong trường hợp này,
đặt width
thành min-content
. Từ khoá min-content
cho hộp biết
chỉ rộng bằng chiều rộng tối thiểu nội tại của nội dung (từ
"tuyệt vời"). Điều này cho phép hộp hoàn toàn vừa vặn quanh văn bản.
Dưới đây là một ví dụ phức tạp hơn minh hoạ tác động của việc thay đổi kích thước đối với nội dung:
Bật và tắt tính năng định cỡ nội tại để xem việc định cỡ bên ngoài mang lại cho bạn nhiều lợi ích hơn khả năng kiểm soát bằng cách định kích thước bên ngoài và kích thước bên trong giúp nội dung trở nên kiểm soát. Để xem hiệu ứng, hãy thêm một vài câu văn bản vào thẻ. Khi phần tử này có kích thước bên ngoài, sẽ có giới hạn về lượng nội dung mà bạn có thể thêm trước khi tràn, nhưng điều đó không xảy ra khi kích thước nội tại là đã bật.
Theo mặc định, phần tử này có một tập hợp width
và height
gồm 400px
cho mỗi phần tử.
Những phương diện này đưa ra các giới hạn nghiêm ngặt đối với mọi nội dung bên trong phần tử, tức là
chấp nhận trừ khi nội dung quá lớn đối với hộp. Bạn có thể xem ví dụ thực tế
bằng cách thay đổi chú thích bên dưới hình ảnh hoa thành nội dung vượt quá
chiều cao của hộp.
Từ khoá chính: Trường hợp tràn xảy ra khi nội dung quá lớn so với hộp chứa trong đó. Bạn có thể
quản lý cách một phần tử xử lý nội dung bị tràn bằng thuộc tính overflow
.
Việc chuyển sang định kích thước nội tại cho phép trình duyệt đưa ra quyết định cho bạn dựa vào kích thước nội dung của hộp. Điều này làm giảm khả năng bị tràn vì hộp đổi kích thước với nội dung.
Điều quan trọng cần nhớ là kích thước nội tại là cài đặt mặc định của trình duyệt và nó thường linh hoạt hơn nhiều so với kích thước bên ngoài.
Các khu vực của mô hình hộp
Các hộp được tạo thành từ các khu vực mô hình hộp riêng biệt mà tất cả đều thực hiện một công việc cụ thể.
Hộp nội dung là khu vực chứa nội dung. Nội dung có thể kiểm soát kích thước của thành phần mẹ, vì vậy đây thường là khu vực có kích thước thay đổi nhất.
Hộp khoảng đệm bao quanh hộp nội dung và là không gian được tạo bởi
thuộc tính padding
.
Vì khoảng đệm nằm bên trong hộp, nên nền của hộp có thể nhìn thấy được trong không gian
mà nó tạo ra.
Nếu hộp đã đặt quy tắc tràn, chẳng hạn như overflow: auto
hoặc
overflow: scroll
thì các thanh cuộn cũng chiếm không gian này.
Hộp đường viền bao quanh hộp khoảng đệm và không gian của hộp này được xác định bằng
border
sẽ tạo khung hình ảnh cho phần tử đó. Cạnh đường viền của phần tử là
về những nội dung bạn có thể xem.
Khu vực cuối cùng, hộp lề, là không gian xung quanh hộp của bạn, được xác định bởi
quy tắc margin
của hộp. Những thuộc tính như
outline
và
box-shadow
chiếm không gian này vì chúng được vẽ ở trên phần tử và không
ảnh hưởng đến kích thước của hộp. Đang bật outline-width
/200px
của hộp
hộp không thay đổi bất kỳ nội dung nào bên trong cạnh viền.
Một ví dụ tương tự hữu ích
Mô hình hộp này rất phức tạp nên sẽ có một ví dụ tương tự với những gì bạn đã học được cho đến nay.
Trong sơ đồ này, bạn có ba khung ảnh được gắn cạnh nhau trên tường. Các phần tử của hình ảnh được đóng khung tương ứng với mô hình hộp như sau:
- Hộp nội dung là tác phẩm nghệ thuật.
- Hộp đệm là bảng gắn màu trắng, nằm giữa khung và hình minh hoạ.
- Hộp đường viền là khung, cung cấp đường viền cố định cho hình minh hoạ.
- Hộp lề là khoảng cách giữa các khung.
- Bóng chiếm cùng không gian với hộp lề.
Gỡ lỗi cho mô hình hộp
Công cụ của trình duyệt cung cấp hình ảnh trực quan về mô hình hộp của hộp đã chọn các phép tính này, nhờ đó, bạn có thể nắm được cách hoạt động của mô hình hộp cũng như ảnh hưởng đến trang web bạn đang làm việc.
Hãy thử làm như sau trong trình duyệt của riêng bạn:
- Mở Công cụ cho nhà phát triển.
- Chọn một phần tử.
- Hiển thị trình gỡ lỗi mô hình hộp.
Kiểm soát kiểu hộp
Để biết cách kiểm soát mô hình hộp, trước tiên, bạn cần biết diễn ra trong trình duyệt của bạn.
Mọi trình duyệt đều áp dụng một biểu định kiểu tác nhân người dùng cho các tài liệu HTML xác định các phần tử sẽ trông như thế nào và hoạt động như thế nào nếu chúng không có CSS được xác định. CSS trong biểu định kiểu của tác nhân người dùng là khác nhau giữa các trình duyệt, nhưng chúng đều cung cấp các tính năng hợp lý mặc định để giúp nội dung dễ đọc hơn.
Một thuộc tính mà biểu định kiểu tác nhân người dùng sẽ đặt display
mặc định của một hộp. Cho
Ví dụ: trong một luồng thông thường, giá trị display
mặc định của phần tử <div>
sẽ là
block
, <li>
có giá trị display
mặc định là list-item
và <span>
có giá trị display
mặc định là inline
.
Một phần tử inline
có lề khối, nhưng các phần tử khác không tuân theo lề.
Với inline-block
, các phần tử khác đều tuân theo lề khối, nhưng phần tử đầu tiên
là phần tử giữ hầu hết mọi hành vi tương tự như phần tử inline
.
Theo mặc định, một mục block
sẽ lấp đầy không gian cùng dòng có sẵn, trong khi
Các phần tử inline
và inline-block
chỉ lớn bằng nội dung của chúng.
Biểu định kiểu tác nhân người dùng cũng đặt box-sizing
, cho biết cách
để tính kích thước hộp. Theo mặc định, tất cả các phần tử đều có tác nhân người dùng sau đây
kiểu: box-sizing: content-box;
. Điều này có nghĩa là khi đặt các phương diện như
dưới dạng width
và height
, thì các tham số đó áp dụng cho hộp nội dung. Nếu bạn
sau đó đặt padding
và border
, các giá trị này sẽ được thêm vào
kích thước.
Kiểm tra kiến thức
Kiểm tra kiến thức của bạn về kích thước mô hình hộp ảnh hưởng đến các thuộc tính.
.my-box { width: 200px; border: 10px solid; padding: 20px; }
Bạn nghĩ .my-box
sẽ rộng đến mức nào?
Chiều rộng thực tế của hộp này là 260px.
Vì CSS sử dụng box-sizing: content-box
mặc định nên chiều rộng được áp dụng là
chiều rộng của nội dung, đồng thời padding
và border
ở cả hai bên được thêm vào
thực hiện việc đó. 200px cho nội dung + 40px khoảng đệm + 20px đường viền tạo thành tổng cộng
chiều rộng hiển thị là 260px.
Bạn có thể thay đổi kích thước này bằng cách chỉ định kích thước border-box
:
.my-box {
box-sizing: border-box;
width: 200px;
border: 10px solid;
padding: 20px;
}
Mô hình hộp thay thế này yêu cầu CSS áp dụng width
cho hộp đường viền
thay vì hộp nội dung. Tức là border
và padding
của chúng ta sẽ nhận được
được đẩy vào, vì vậy, khi bạn đặt .my-box
thành 200px
rộng, nó sẽ thực sự hiển thị
rộng 200px
.
Khám phá cách hoạt động của tính năng này trong bản minh hoạ tương tác sau đây. Khi bạn bật/tắt
box-sizing
, vùng màu xanh dương cho biết CSS nào đang được áp dụng bên trong
.
*,
*::before,
*::after {
box-sizing: border-box;
}
Quy tắc CSS này chọn mọi phần tử trong tài liệu
và mọi phần tử giả ::before
và ::after
rồi áp dụng box-sizing: border-box
.
Điều này có nghĩa là mọi phần tử hiện đều sử dụng mô hình hộp thay thế này.
Vì mô hình hộp thay thế có thể dễ dự đoán hơn, nên các nhà phát triển thường thêm quy tắc này để đặt lại và chuẩn hoá, như quy tắc này.