Giãn cách

Podcast CSS – 013: Khoảng cách

Giả sử bạn có một bộ sưu tập gồm ba hộp, xếp chồng lên nhau và bạn muốn có không gian giữa chúng. Bạn có thể nghĩ ra bao nhiêu cách để làm điều đó trong CSS?

Ba hộp xếp chồng có mũi tên xuống

Thuộc tính margin có thể cung cấp cho bạn những gì bạn cần, nhưng cũng có thể thêm khoảng cách bổ sung mà bạn không muốn. Ví dụ: làm cách nào để bạn chỉ nhắm mục tiêu khoảng không ở giữa mỗi phần tử đó? Một nội dung như gap có thể phù hợp hơn trong trường hợp này. Có nhiều cách để điều chỉnh khoảng cách trong giao diện người dùng, mỗi cách có những điểm mạnh và cảnh báo riêng.

Giãn cách HTML

Bản thân HTML cung cấp một số phương thức cho các phần tử không gian. Các phần tử <br><hr> cho phép bạn giãn cách các thành phần theo hướng khối. Nếu bạn sử dụng ngôn ngữ Latinh, thì từ trên xuống dưới.

Nếu bạn sử dụng phần tử <br>, phần tử này sẽ tạo ra một dấu ngắt dòng, giống như khi bạn nhấn phím Enter trong trình xử lý văn bản.

<hr> tạo một đường ngang có khoảng trống ở hai bên, được gọi là margin.

Cùng với việc sử dụng các phần tử HTML, các thực thể HTML còn có thể tạo ra không gian. Thực thể HTML là một chuỗi ký tự dành riêng được trình duyệt thay thế bằng các thực thể ký tự. Ví dụ: nếu bạn nhập &copy; vào tệp HTML, tệp đó sẽ được chuyển đổi thành ký tự ©. Thực thể &nbsp; được chuyển đổi thành một ký tự dấu cách không ngắt, cung cấp một không gian cùng dòng. Tuy nhiên, hãy cẩn thận, vì khía cạnh không phá vỡ của ký tự này ghép hai thành phần lại với nhau, điều này có thể dẫn đến hành vi bất thường.

Lợi nhuận

Nếu muốn thêm khoảng trống ở bên ngoài một phần tử, bạn sẽ sử dụng thuộc tính margin. Lề giống như thêm một lớp đệm xung quanh phần tử của bạn. Thuộc tính margin là viết tắt của margin-top, margin-right, margin-bottommargin-left.

Sơ đồ 4 khu vực chính của mô hình hình hộp.

Viết tắt margin áp dụng các thuộc tính theo thứ tự cụ thể: trên cùng, bên phải, dưới cùng và bên trái. Bạn không thể nhớ được những gợi ý này: TRouBLe.

Từ &quot;Vấn đề&quot; chạy xuống với T, R, B và L mở rộng đến Trên, Phải, Dưới và Trái.
Một hộp có các mũi tên để chỉ đường.

Bạn cũng có thể sử dụng viết tắt margin với một, hai hoặc ba giá trị. Việc thêm giá trị thứ tư cho phép bạn đặt từng bên riêng lẻ. Các thuộc tính này được áp dụng như sau:

  • Một giá trị sẽ được áp dụng cho tất cả các mặt. (margin: 20px).
  • Hai giá trị: giá trị đầu tiên sẽ áp dụng cho cạnh trên cùng và dưới cùng, còn giá trị thứ hai sẽ áp dụng cho bên trái và bên phải. (margin: 20px 40px)
  • Ba giá trị: giá trị đầu tiên là top, giá trị thứ hai là left right, và giá trị thứ ba là bottom. (margin: 20px 40px 30px).

Bạn có thể xác định lợi nhuận bằng độ dài, tỷ lệ phần trăm hoặc giá trị tự động, chẳng hạn như 1em hoặc 20%. Nếu bạn sử dụng tỷ lệ phần trăm, giá trị sẽ được tính dựa trên chiều rộng của khối chứa phần tử.

Điều này có nghĩa là nếu khối vùng chứa của phần tử có chiều rộng là 250px và phần tử có giá trị margin20%: mỗi bên của phần tử sẽ có lề được tính toán là 50px.

Bạn cũng có thể sử dụng giá trị auto cho lợi nhuận. Đối với các phần tử cấp khối có kích thước bị hạn chế, lề auto sẽ chiếm không gian có sẵn theo hướng áp dụng lề. Ví dụ điển hình là trường hợp này, trong mô-đun flexbox, trong đó các mục đẩy ra khỏi nhau.

Một ví dụ điển hình khác về lề auto là trình bao bọc căn giữa theo chiều ngang có chiều rộng tối đa. Loại trình bao bọc này thường được dùng để tạo một cột trung tâm nhất quán trên trang web.

.wrapper {
    max-width: 400px;
    margin: 0 auto;
}

Ở đây, lề bị xoá khỏi cạnh trên và dưới (khối) và auto chia sẻ không gian giữa bên trái và bên phải (cùng dòng).

Lề âm

Bạn cũng có thể sử dụng giá trị âm cho lợi nhuận. Thay vì thêm không gian giữa các phần tử phụ liền kề, điều này sẽ giảm không gian giữa các phần tử đó. Việc này có thể dẫn đến các phần tử trùng lặp nếu bạn khai báo một giá trị âm nhiều hơn không gian có sẵn.

Thu gọn lề

Thu gọn lề là một khái niệm phức tạp, nhưng bạn sẽ gặp rất phổ biến khi xây dựng giao diện. Giả sử bạn có hai phần tử: một tiêu đề và một đoạn đều có lề dọc:

<article>
  <h1>My heading with teal margin</h1>
  <p>A paragraph of text that has blue margin on it, following the heading with margin.</p>
</article>
h1 {
    margin-bottom: 2rem;
}

p {
    margin-top: 3rem;
}

Thoạt nhìn, bạn sẽ cảm thấy khó chịu khi nghĩ rằng đoạn văn bản sẽ được giãn cách 5em với tiêu đề, vì 2rem3rem kết hợp với nhau để tính toán thành 5rem. Vì lề dọc thu gọn nên không gian thực ra là 3rem.

Tính năng thu gọn lề hoạt động bằng cách chọn giá trị lớn nhất của hai phần tử liền kề với lề dọc được đặt ở các cạnh liền kề. Đáy dưới cùng của h1 gặp trên cùng của p, do đó, giá trị lớn nhất của lề dưới cùng của h1 và lề trên của p sẽ được chọn. Nếu h1 có lề dưới là 3.5rem thì khoảng cách giữa cả hai đều là 3.5rem vì lề dưới lớn hơn 3rem. Chỉ thu gọn lề của khối, chứ không phải lề cùng dòng (ngang).

Tính năng thu gọn lề cũng hữu ích với các phần tử trống. Nếu bạn có một đoạn văn có lề trên và lề dưới là 20px, thì đoạn văn bản đó sẽ chỉ tạo ra không gian 20px: chứ không phải 40px. Tuy nhiên, nếu bất kỳ nội dung nào được thêm vào bên trong phần tử này, bao gồm cả padding, thì lề của phần tử đó sẽ không còn tự thu gọn và sẽ được coi là bất kỳ hộp nào có nội dung.

Kiểm tra mức độ hiểu biết của bạn

Kiểm tra kiến thức của bạn về việc thu hẹp biên lợi nhuận

Nếu hai phần tử xếp chồng lên nhau đều có 20 px cho lề trên và 30 px của lề dưới, thì khoảng cách giữa chúng là bao nhiêu?

10px
Hãy thử lại!
20px
Chưa đúng
30px
CSS sẽ lấy khoảng cách lề lớn hơn giữa các phần tử!
40px
Hãy thử lại!

Tránh thu gọn lề

Nếu bạn tạo một phần tử ở vị trí tuyệt đối bằng position: absolute, lề sẽ không thu gọn nữa. Lề cũng sẽ không thu gọn nếu bạn sử dụng thuộc tính float.

Nếu bạn có một phần tử không có lề giữa hai phần tử có lề của khối, thì lề cũng sẽ không thu gọn vì hai phần tử có lề khối không còn là các thành phần đồng cấp liền kề: chúng chỉ là các thành phần đồng cấp.

Trong bài học về bố cục, bạn đã biết rằng vùng chứa flexbox và lưới rất giống với vùng chứa khối, nhưng xử lý các phần tử con rất khác nhau. Trường hợp này cũng xảy ra với thu gọn lề.

Nếu chúng ta lấy ví dụ ban đầu trong bài học và áp dụng hộp linh hoạt theo hướng cột, thì các lề sẽ được kết hợp lại, thay vì thu gọn. Điều này có thể mang lại khả năng dự đoán đối với công việc về bố cục, vốn là mục đích của vùng chứa flexbox và lưới.

Lợi nhuận và thu gọn lề có thể rất khó hiểu, nhưng việc hiểu chi tiết cách hoạt động của các giá trị này rất hữu ích. Vì vậy, bạn nên sử dụng giải thích chi tiết này.

Khoảng đệm

Thay vì tạo không gian ở bên ngoài hộp, như margin đã làm, thuộc tính padding tạo không gian ở bên trong hộp của bạn: như lớp cách nhiệt.

Hộp có mũi tên chỉ vào trong để cho biết rằng khoảng đệm nằm bên trong hộp

Tuỳ thuộc vào mô hình hộp mà bạn đang sử dụng (đã được đề cập trong bài học về mô hình hộp), padding cũng có thể ảnh hưởng đến kích thước tổng thể của phần tử.

Thuộc tính padding là viết tắt của padding-top, padding-right, padding-bottompadding-left. Giống như margin, padding cũng có các thuộc tính logic: padding-block-start, padding-inline-end, padding-block-endpadding-inline-start.

Khẳng định vị thế

Cũng được đề cập trong mô-đun bố cục, nếu đặt giá trị cho position khác với static, thì bạn có thể tạo khoảng trống các phần tử bằng các thuộc tính top, right, bottomleft. Có một số khác biệt về cách hoạt động của các giá trị định hướng này:

  • Một phần tử có position: relative sẽ giữ nguyên vị trí trong luồng tài liệu, ngay cả khi bạn đặt các giá trị này. Các giá trị này cũng sẽ tương ứng với vị trí của phần tử.
  • Một phần tử có position: absolute sẽ lấy giá trị định hướng từ vị trí của thành phần mẹ tương đối.
  • Một phần tử có position: fixed sẽ dựa trên các giá trị hướng trên khung nhìn.
  • Một phần tử có position: sticky sẽ chỉ áp dụng các giá trị hướng khi ở trạng thái được gắn/cố định.

Trong mô-đun thuộc tính logic, bạn sẽ tìm hiểu về các thuộc tính inset-blockinset-inline. Các thuộc tính này cho phép bạn đặt các giá trị hướng phù hợp với chế độ viết.

Cả hai thuộc tính đều là từ viết tắt kết hợp các giá trị startend, do đó, chấp nhận một giá trị được đặt cho startend hoặc hai giá trị riêng lẻ.

Lưới và hộp linh hoạt

Cuối cùng, trong cả lưới và flexbox, bạn có thể sử dụng thuộc tính gap để tạo khoảng trống giữa các phần tử con. Thuộc tính gap là viết tắt của row-gapcolumn-gap. Thuộc tính này chấp nhận một hoặc hai giá trị, có thể là độ dài hoặc tỷ lệ phần trăm. Bạn cũng có thể sử dụng các từ khoá như unset, initialinherit. Nếu bạn chỉ xác định một giá trị, cùng một gap sẽ được áp dụng cho cả hàng và cột, nhưng nếu bạn xác định cả hai giá trị, giá trị đầu tiên sẽ là row-gap và giá trị thứ hai là column-gap.

Với cả flexbox và lưới, bạn cũng có thể tạo không gian bằng khả năng phân phối và căn chỉnh mà chúng tôi đề cập trong mô-đun lướimô-đun flexbox.

Một sơ đồ biểu diễn một lưới có các khoảng trống

Tạo khoảng cách nhất quán

Bạn nên chọn một chiến lược và theo sát chiến lược đó để tạo ra một giao diện người dùng nhất quán, có luồng và nhịp điệu tốt. Một cách hay để làm được điều này là sử dụng các số đo nhất quán cho khoảng cách của bạn.

Ví dụ: bạn có thể cam kết sử dụng 20px làm thước đo nhất quán cho tất cả các khoảng trống giữa các phần tử (còn gọi là rãnh) để tất cả các bố cục đều có giao diện nhất quán. Bạn cũng có thể quyết định sử dụng 1em làm khoảng cách dọc giữa nội dung luồng, để đạt được khoảng cách nhất quán dựa trên font-size của phần tử. Dù chọn cách nào, bạn cũng nên lưu các giá trị này dưới dạng biến (hoặc thuộc tính tuỳ chỉnh CSS) để mã hoá các giá trị đó và tăng tính nhất quán một chút.

Khoảng cách nhất quán giữa các phần tử, sử dụng 20px cho bố cục hoặc 1em cho nội dung luồng.

:root {
  --gutter: 20px;
  --spacing: 1em;
}

h1 {
  margin-left: var(--gutter);
  margin-top: var(--spacing);
}

Việc sử dụng các thuộc tính tuỳ chỉnh như thế này cho phép bạn xác định chúng một lần, sau đó sử dụng các thuộc tính đó trong toàn bộ CSS của bạn. Khi được cập nhật, cục bộ trong một phần tử hoặc trên toàn cục, các giá trị sẽ truyền qua tầng và các giá trị đã cập nhật sẽ được phản ánh.

Kiểm tra mức độ hiểu biết của bạn

Kiểm tra kiến thức của bạn về khoảng cách

Có thể sử dụng HTML để giãn cách khi...

Chỉ có một mà thôi.
Hãy thử lại!
Sẽ không ai để ý.
Hãy thử lại!
Ứng dụng này chỉ dành cho không gian.
Hãy thử lại!
Tên này giúp bạn hiểu rõ nội dung tài liệu.
Chính xác!

Để tạo không gian bên trong một hộp, hãy sử dụng...

Lợi nhuận
Lề dùng để đẩy ra ngoài hộp.
HTML
Các tuỳ chọn này dùng để giãn cách và phân chia nội dung.
Gap
Khoảng trống là khoảng cách giữa các hộp.
Khoảng đệm
Khoảng đệm dùng để tạo khoảng trống bên trong hộp.

Để tạo không gian bên ngoài hộp, hãy sử dụng...

Lợi nhuận
Lề dùng để đẩy ra ngoài hộp.
HTML
Các tuỳ chọn này dùng để giãn cách và phân chia nội dung.
Gap
Khoảng trống là khoảng cách giữa các hộp.
Khoảng đệm
Khoảng đệm dùng để tạo khoảng trống bên trong hộp.

Để tạo khoảng cách giữa các hộp, hãy sử dụng...

Lợi nhuận
Lề dùng để đẩy ra ngoài hộp.
HTML
Các tuỳ chọn này dùng để giãn cách và phân chia nội dung.
Gap
Khoảng trống là khoảng cách giữa các hộp.
Khoảng đệm
Khoảng đệm dùng để tạo khoảng trống bên trong hộp.