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
widthvà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-stylenhư 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.widthvàheightchỉ 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ínhwidthvàheightsẽ 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ử
blocksẽ 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,margincho 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ử
inlinekhô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
widthvàheightcho 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
inlinevàblock. - Giống như
inline, các phần tửinline-blockxế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àmargincho 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-blockrấ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
divvớ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
spanvàavớ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/bottomtrong 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
divvới classinline-blockcũng xếp hàng trên cùng một dòng, nhưng chúng ta có thể thiết lậpwidthvàheightcho chúng, vàmargin-bottomcũ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