Bài 2.3: Box model và layout cơ bản trong CSS

Bài 2.3: Box model và layout cơ bản trong CSS
Chào mừng bạn đến với bài viết tiếp theo trong series học lập trình Web Front-end! Nếu như HTML giúp chúng ta tạo ra cấu trúc và nội dung cho trang web, thì CSS chính là "phù thủy" biến những cấu trúc đó thành một giao diện đẹp mắt và có tổ chức. Và để thực sự điều khiển được cách các phần tử hiển thị và sắp xếp trên trang, chúng ta cần phải hiểu một khái niệm cực kỳ quan trọng và cốt lõi: CSS Box Model.
Hãy cùng nhau "bóc tách" từng lớp của Box Model và xem nó giúp chúng ta xây dựng layout cơ bản như thế nào nhé!
Box Model: Mọi thứ đều là một chiếc hộp
Hãy tưởng tượng mỗi phần tử HTML trên trang web của bạn (như đoạn văn bản <p>
, tiêu đề <h1>
, ảnh <img>
, hay khối chứa nội dung <div>
) đều là một chiếc hộp hình chữ nhật. CSS Box Model mô tả cấu trúc của chiếc hộp này, bao gồm các thành phần:
- Content (Nội dung): Đây là khu vực bên trong cùng, chứa đựng nội dung thực tế của phần tử – văn bản, hình ảnh, hoặc các phần tử HTML khác. Kích thước của khu vực nội dung thường được điều khiển bởi các thuộc tính
width
vàheight
. - Padding (Đệm): Đây là lớp không gian trong suốt nằm giữa khu vực Content và Border. Padding được sử dụng để tạo khoảng đệm bên trong phần tử, đẩy nội dung ra xa viền. Nó không có màu nền riêng mà sẽ lấy màu nền của phần tử. Các thuộc tính điều khiển padding là
padding-top
,padding-right
,padding-bottom
,padding-left
, hoặc shorthandpadding
. - Border (Viền): Đây là đường viền bao quanh Padding và Content. Border giúp phân tách rõ ràng giữa một phần tử với các phần tử lân cận. Bạn có thể định dạng độ dày (
border-width
), kiểu dáng (border-style
như solid, dashed, dotted), và màu sắc (border-color
) cho viền. Hoặc sử dụng shorthandborder
. - Margin (Lề ngoài): Đây là khu vực không gian trong suốt nằm bên ngoài Border. Margin được sử dụng để tạo khoảng cách giữa phần tử hiện tại với các phần tử khác xung quanh nó. Margin cũng không có màu nền. Các thuộc tính điều khiển margin là
margin-top
,margin-right
,margin-bottom
,margin-left
, hoặc shorthandmargin
.
Hãy xem qua một sơ đồ "trực quan hóa" Box Model (tưởng tượng nhé, vì ta không dùng ảnh ở đây):
+-----------------------------------+
| MARGIN (ngoài) |
| +---------------------------+ |
| | BORDER (viền) | |
| | +-----------------------+ |
| | | PADDING (đệm) | |
| | | +---------------+ | |
| | | | CONTENT | | |
| | | | (nội dung) | | |
| | | +---------------+ | |
| | +-----------------------+ |
| +---------------------------+ |
+-----------------------------------+
Áp dụng Box Model với CSS
Chúng ta sử dụng các thuộc tính CSS để thiết lập kích thước và khoảng cách cho từng phần của Box Model.
Ví dụ minh họa Box Model cơ bản:
HTML:
<div class="my-box">
Đây là nội dung của chiếc hộp.
</div>
CSS:
.my-box {
width: 200px; /* Kích thước chiều rộng của KHU VỰC NỘI DUNG */
height: 100px; /* Kích thước chiều cao của KHU VỰC NỘI DUNG */
padding: 20px; /* Thêm đệm 20px VÀO BÊN TRONG viền, xung quanh nội dung */
/* Tương đương với:
padding-top: 20px;
padding-right: 20px;
padding-bottom: 20px;
padding-left: 20px;
*/
border: 5px solid blue; /* Thêm viền dày 5px, kiểu nét liền, màu xanh */
/* Tương đương với:
border-width: 5px;
border-style: solid;
border-color: blue;
*/
margin: 30px; /* Thêm lề ngoài 30px XUNG QUANH chiếc hộp, tạo khoảng cách với các phần tử khác */
/* Tương đương với:
margin-top: 30px;
margin-right: 30px;
margin-bottom: 30px;
margin-left: 30px;
*/
background-color: lightgrey; /* Màu nền cho khu vực nội dung và padding */
}
Giải thích:
width: 200px; height: 100px;
: Xác định kích thước cho phần nội dung là 200px x 100px.padding: 20px;
: Thêm 20px không gian đệm bên trong viền ở cả 4 phía. Phần background-color (lightgrey) sẽ kéo dài ra đến hết khu vực padding này.border: 5px solid blue;
: Tạo một đường viền màu xanh dày 5px xung quanh khu vực padding.margin: 30px;
: Tạo khoảng cách 30px bên ngoài đường viền, tách chiếc hộp này khỏi bất kỳ phần tử nào khác trên trang. Phần này sẽ trong suốt, không có màu nền của phần tử.
Với cấu hình trên, tổng kích thước thực tế mà chiếc hộp này chiếm trên trang sẽ là:
- Chiều rộng: 30px (margin trái) + 5px (border trái) + 20px (padding trái) + 200px (content) + 20px (padding phải) + 5px (border phải) + 30px (margin phải) = 310px.
- Chiều cao: 30px (margin trên) + 5px (border trên) + 20px (padding trên) + 100px (content) + 20px (padding dưới) + 5px (border dưới) + 30px (margin dưới) = 210px.
Như bạn thấy, width
và height
mặc định chỉ áp dụng cho content. Padding, Border và Margin đều thêm vào kích thước tổng thể của phần tử.
Shorthand cho Padding và Margin
Các thuộc tính padding
và margin
có cú pháp shorthand rất tiện lợi:
padding: 20px;
-> Áp dụng 20px cho cả top, right, bottom, left.padding: 10px 20px;
-> Áp dụng 10px cho top/bottom, 20px cho left/right.padding: 10px 20px 30px;
-> Áp dụng 10px cho top, 20px cho left/right, 30px cho bottom.padding: 10px 20px 30px 40px;
-> Áp dụng 10px cho top, 20px cho right, 30px cho bottom, 40px cho left (theo chiều kim đồng hồ từ top).
Cú pháp tương tự áp dụng cho margin
.
Box Sizing: "Chiêu" giúp bạn kiểm soát kích thước dễ hơn
Cách tính toán kích thước tổng thể như ví dụ trên đôi khi hơi khó chịu khi bạn muốn một phần tử có chiều rộng tổng cộng là 200px, nhưng lại phải liên tục cộng trừ padding và border. May mắn thay, CSS cung cấp một thuộc tính để thay đổi cách tính toán này: box-sizing
.
box-sizing: content-box;
(Mặc định): Đây là cách tính toán truyền thống như chúng ta vừa học.width
vàheight
chỉ bao gồm kích thước của Content. Padding và Border sẽ được thêm vào kích thước này.box-sizing: border-box;
: Đây là chế độ tính toán hiện đại và thường được ưa chuộng hơn. Khi sử dụngborder-box
, thuộc tínhwidth
vàheight
sẽ bao gồm cả Content, Padding và Border. Margin vẫn nằm ngoài kích thước này.
Ví dụ minh họa sự khác biệt giữa content-box
và border-box
:
HTML:
<div class="box content-box">
Content-box
</div>
<div class="box border-box">
Border-box
</div>
CSS:
.box {
width: 200px;
padding: 20px;
border: 5px solid green;
margin-bottom: 10px; /* Khoảng cách giữa 2 hộp */
background-color: lightblue;
}
.content-box {
box-sizing: content-box; /* Kích thước tổng: 200(content) + 20*2(padding) + 5*2(border) = 250px */
}
.border-box {
box-sizing: border-box; /* Kích thước tổng: 200px (bao gồm content, padding, border) */
}
Giải thích:
Cả hai div
đều có width: 200px
, padding: 20px
, border: 5px
.
content-box
: Chiều rộng 200px chỉ là nội dung. Tổng chiều rộng là 200 + (20*2) + (5*2) = 250px.border-box
: Chiều rộng tổng cộng (bao gồm padding và border) là 200px. CSS sẽ tự động tính toán kích thước nội dung còn lại.
Sử dụng box-sizing: border-box;
giúp việc tính toán layout trở nên trực quan hơn rất nhiều, đặc biệt khi làm việc với phần trăm hoặc các layout phức tạp. Rất nhiều lập trình viên web hiện đại thích đặt quy tắc này cho tất cả các phần tử trên trang như một "CSS Reset" cơ bản:
* {
box-sizing: border-box;
}
Dấu *
chọn tất cả các phần tử trên trang. Quy tắc này đảm bảo mọi thứ hoạt động theo cách tính toán border-box
.
Layout Cơ bản với Box Model và Thuộc tính Display
Box Model giúp chúng ta định hình kích thước và khoảng cách của từng phần tử. Nhưng làm thế nào để các phần tử này tương tác và sắp xếp cạnh nhau hoặc trên/dưới nhau? Đó là lúc thuộc tính display
phát huy tác dụng.
Thuộc tính display
kiểm soát cách một phần tử hiển thị và tương tác với các phần tử khác trên trang. Đây là một trong những thuộc tính quan trọng nhất trong CSS để tạo layout. Có rất nhiều giá trị cho display
, nhưng ở mức cơ bản, chúng ta cần hiểu sự khác biệt giữa:
display: block;
:- Mỗi phần tử
block
sẽ bắt đầu trên một dòng mới. - Nó sẽ mở rộng theo chiều ngang để chiếm toàn bộ chiều rộng khả dụng của phần tử cha (trừ đi padding, border, margin của chính nó và cha).
- Bạn có thể dễ dàng thiết lập
width
,height
,padding
,border
,margin
cho phần tử block. - Các phần tử mặc định là
block
:div
,p
,h1-h6
,ul
,li
,article
,section
, v.v.
- Mỗi phần tử
display: inline;
:- Các phần tử
inline
không bắt đầu trên một dòng mới. Chúng xếp hàng cạnh nhau theo luồng văn bản. - Chúng chỉ chiếm chiều rộng vừa đủ với nội dung của chúng.
- Bạn không thể thiết lập
width
vàheight
cho phần tửinline
. Padding và margin chỉ có tác dụng theo chiều ngang (trái/phải), margin và padding theo chiều dọc (top/bottom) sẽ không ảnh hưởng đến vị trí của các phần tử khác trên dòng. - Các phần tử mặc định là
inline
:span
,a
,strong
,em
,img
(thường coi là inline-block hoặc inline), v.v.
- Các phần tử
display: inline-block;
:- Đây là sự kết hợp giữa
inline
vàblock
. - Giống như
inline
, các phần tửinline-block
xếp hàng cạnh nhau trên cùng một dòng (nếu đủ chỗ). - Tuy nhiên, giống như
block
, bạn có thể thiết lậpwidth
,height
,padding
,border
, vàmargin
cho chúng, và các thuộc tính này sẽ ảnh hưởng đến cách chúng chiếm không gian và tương tác với các phần tử khác. inline-block
rất hữu ích để tạo các cột đơn giản hoặc các danh sách các mục xếp ngang hàng (ví dụ: menu navigation).
- Đây là sự kết hợp giữa
Ví dụ minh họa sự khác biệt giữa display
:
HTML:
<h2>Block Elements</h2>
<div class="element block">Div 1</div>
<div class="element block">Div 2</div>
<h2>Inline Elements</h2>
<span class="element inline">Span 1</span>
<span class="element inline">Span 2</span>
<a href="#" class="element inline">Link</a>
<h2>Inline-Block Elements</h2>
<div class="element inline-block">Inline-Block 1</div>
<div class="element inline-block">Inline-Block 2</div>
CSS:
.element {
padding: 10px;
margin: 10px;
border: 1px solid black;
background-color: yellow;
}
.block {
/* display: block; */ /* Đây là giá trị mặc định cho div, nên không cần khai báo tường minh */
background-color: lightcoral;
}
.inline {
display: inline;
background-color: lightgreen;
/* Thử đặt width/height/margin-top/margin-bottom ở đây, bạn sẽ thấy chúng không ảnh hưởng */
/* width: 50px; */
/* height: 30px; */
/* margin-top: 20px; */
/* margin-bottom: 20px; */
}
.inline-block {
display: inline-block;
background-color: lightblue;
width: 120px; /* Có tác dụng! */
height: 60px; /* Có tác dụng! */
margin-bottom: 20px; /* Có tác dụng! */
}
Giải thích:
- Các
div
với classblock
(mặc định làdisplay: block
) mỗi cái nằm trên một dòng riêng và kéo dài hết chiều rộng. Margin 10px tạo khoảng cách xung quanh chúng. - Các
span
vàa
với classinline
(hoặc mặc định là inline) xếp hàng trên cùng một dòng. Padding 10px thêm không gian bên trong chúng, margin 10px thêm không gian giữa chúng theo chiều ngang. Thử bỏ chú thích các dòngwidth
,height
,margin-top/bottom
trong CSS của.inline
, bạn sẽ thấy chúng không thay đổi cách hiển thị hoặc vị trí theo chiều dọc. - Các
div
với classinline-block
cũng xếp hàng trên cùng một dòng, nhưng chúng ta có thể thiết lậpwidth
vàheight
cho chúng, vàmargin-bottom
cũng có tác dụng tạo khoảng cách theo chiều dọc giữa các dòng của các inline-block element.
Hiểu rõ sự khác biệt giữa block
, inline
, và inline-block
kết hợp với Box Model là nền tảng để bạn bắt đầu xây dựng các layout phức tạp hơn sau này bằng các kỹ thuật như Flexbox hay Grid.
Comments