Tìm kiếm
Đóng khung tìm kiếm này.

Giải thích thuộc tính CSS Float và cách sử dụng trong lập trình web

css float

Mục Lục

Việc sắp xếp các phần tử trên một trang web là một trong những nhiệm vụ cơ bản nhất của CSS. Chúng ta muốn hình ảnh nằm cạnh đoạn văn. Chúng ta muốn tạo ra các cột nội dung song song. Hay chúng ta muốn menu điều hướng hiển thị theo chiều ngang. Trong quá khứ, trước khi các công cụ hiện đại như Flexbox hay Grid ra đời, các nhà phát triển web đã phải dựa vào một thuộc tính CSS khá đặc biệt. Thuộc tính đó chính là float. Mặc dù ngày nay vai trò của nó đã thay đổi, việc hiểu rõ về float vẫn rất quan trọng. Nó giúp chúng ta hiểu được lịch sử phát triển của layout web. Nó cũng giúp chúng ta xử lý một vài tình huống cụ thể. Vậy thực sự CSS float là gì?

CSS Float là gì? Giải mã thuộc tính thay đổi luồng trang

Để có thể sử dụng hiệu quả, trước hết chúng ta cần nắm vững định nghĩa và cách thức hoạt động cơ bản của thuộc tính này.

Định nghĩa cốt lõi: Cho phép phần tử “trôi” tự do khỏi luồng trang

Hãy tưởng tượng các phần tử HTML trên trang web của bạn giống như những khối gạch. Bình thường, chúng sẽ được xếp chồng lên nhau theo chiều dọc. Mỗi khối gạch (phần tử block) sẽ chiếm trọn một hàng. Thuộc tính CSS float giống như một phép thuật. Nó nhấc một viên gạch ra khỏi vị trí cố định đó. Nó cho phép viên gạch đó “trôi” sang một bên, sang trái hoặc sang phải. Khi một phần tử được đặt float, nó sẽ bị đưa ra khỏi luồng văn bản thông thường (normal document flow).

Nó sẽ di chuyển đến cạnh trái hoặc cạnh phải của phần tử chứa nó (container). Điểm đặc biệt là các nội dung khác, đặc biệt là văn bản (phần tử inline), sẽ tự động bao quanh phần tử bị float đó. Nó tạo ra hiệu ứng giống như một bức ảnh trên một trang báo. Chữ viết sẽ tự động chảy xung quanh bức ảnh đó. Đây chính là bản chất của CSS float.

Lịch sử ra đời: Từ bố cục ảnh đến “hack” layout website

Ít ai biết rằng, mục đích ban đầu khi CSS float được tạo ra rất đơn giản. Nó chỉ nhằm để giải quyết một bài toán duy nhất. Đó là làm thế nào để đặt một bức ảnh và cho phép văn bản bao quanh nó một cách tự nhiên. Trước khi có float, việc này rất khó khăn. Hình ảnh thường bị đẩy xuống một dòng riêng biệt. Nó tạo ra những khoảng trắng rất khó chịu. Thuộc tính float đã giải quyết vấn đề này một cách hoàn hảo.

Tuy nhiên, các nhà phát triển web thời kỳ đầu rất thông minh và sáng tạo. Họ nhanh chóng nhận ra tiềm năng lớn hơn của float. Họ bắt đầu “lạm dụng” nó cho một mục đích hoàn toàn khác. Đó là để tạo ra các bố cục website có nhiều cột. Bằng cách đặt float: left cho nhiều phần tử div cạnh nhau, họ có thể ép chúng nằm trên cùng một hàng. Kỹ thuật này đã trở thành phương pháp tiêu chuẩn để xây dựng layout web trong suốt nhiều năm. Mặc dù nó có nhiều hạn chế và gây ra các vấn đề phức tạp (chúng ta sẽ tìm hiểu sau), nhưng không thể phủ nhận vai trò lịch sử to lớn của CSS float.

Các giá trị phổ biến của thuộc tính CSS Float

Thuộc tính float có một vài giá trị chính. Mỗi giá trị sẽ quyết định hướng “trôi” của phần tử.

float: left – Trôi sang bên trái: Giá trị được dùng nhiều nhất

Đây là giá trị được sử dụng phổ biến nhất của thuộc tính CSS float. Khi bạn áp dụng float: left cho một phần tử, nó sẽ thực hiện các hành động sau. Đầu tiên, phần tử đó sẽ bị đưa ra khỏi luồng trang thông thường. Sau đó, nó sẽ di chuyển sang phía bên trái hết mức có thể. Nó sẽ dừng lại khi chạm vào cạnh trái của phần tử cha chứa nó. Hoặc nó sẽ dừng khi chạm vào cạnh phải của một phần tử khác cũng đang được float: left trước đó.css float

Phần quan trọng nhất là cách các nội dung khác phản ứng. Các phần tử inline (như văn bản, thẻ span) xuất hiện sau phần tử float sẽ tự động bao quanh phía bên phải của nó. Chúng sẽ lấp đầy khoảng trống còn lại trên cùng một dòng. Các phần tử block (như p, div) xuất hiện sau phần tử float sẽ hành xử như thể phần tử float không tồn tại về mặt chiều dọc. Chúng sẽ bị đẩy xuống dưới phần tử float. Nhưng về mặt chiều ngang, nội dung của chúng vẫn sẽ bao quanh phần tử float.

Ví dụ đơn giản:

HTML

<div style="width: 300px; border: 1px solid black;">
  <img src="logo.png" style="float: left; width: 100px; margin-right: 10px;">
  Đây là đoạn văn bản sẽ bao quanh logo. Chữ viết sẽ tự động chảy xung quanh phía bên phải của hình ảnh đã được float sang trái.
</div>

Kết quả là logo sẽ nằm ở góc trên bên trái. Đoạn văn bản sẽ bắt đầu ngay bên cạnh logo và tiếp tục chảy xuống dưới. Việc hiểu rõ float: left là nền tảng của CSS float là gì.

float: right – Trôi sang bên phải: Đối xứng với float: left

Giá trị float: right hoạt động theo nguyên tắc hoàn toàn tương tự như float: left. Chỉ khác là hướng di chuyển của phần tử sẽ ngược lại. Khi bạn áp dụng float: right cho một phần tử, nó cũng bị đưa ra khỏi luồng trang. Sau đó, nó sẽ di chuyển sang phía bên phải hết mức có thể. Nó sẽ dừng lại khi chạm vào cạnh phải của phần tử cha. Hoặc nó sẽ dừng khi chạm vào cạnh trái của một phần tử khác đang float: right trước đó. Các nội dung inline xuất hiện sau sẽ bao quanh phía bên trái của phần tử float này.

float: right thường được sử dụng trong các trường hợp bạn muốn đặt một thành phần sang hẳn phía bên phải. Ví dụ như một menu phụ, một hộp thông tin liên hệ trong sidebar. Hoặc bạn muốn tạo hiệu ứng hình ảnh nằm bên phải và văn bản bao quanh bên trái. Việc sử dụng float: right cũng đòi hỏi bạn phải hiểu rõ về cách nó tương tác với các phần tử khác. Nó cũng gây ra vấn đề “sụp đổ phần tử cha” tương tự như float: left. Việc nắm vững cả hai giá trị này giúp bạn hiểu toàn diện CSS float là gì.

float: none – Giá trị mặc định: Khôi phục trạng thái ban đầu

float: none là giá trị mặc định của mọi phần tử HTML. Điều này có nghĩa là, nếu bạn không đặt thuộc tính float cho một phần tử, nó sẽ tự động có giá trị float: none. Khi một phần tử có float: none, nó sẽ nằm yên vị trong luồng văn bản thông thường. Nó sẽ không “trôi” đi đâu cả. Hành vi của nó sẽ được quyết định bởi thuộc tính display mặc định của nó (block hoặc inline).css float

Vậy khi nào chúng ta cần phải ghi tường minh float: none? Trường hợp phổ biến nhất là trong thiết kế đáp ứng (responsive design). Giả sử trên màn hình lớn, bạn đặt hai cột div float: left để chúng nằm cạnh nhau. Nhưng trên màn hình điện thoại nhỏ, bạn muốn hai cột này xếp chồng lên nhau theo chiều dọc. Lúc này, bạn sẽ sử dụng Media Queries. Bạn sẽ viết một quy tắc CSS chỉ áp dụng cho màn hình nhỏ.

Trong quy tắc đó, bạn đặt lại float: none cho cả hai cột. Điều này sẽ hủy bỏ hiệu ứng float và đưa chúng trở về luồng trang bình thường. Việc hiểu rõ float: none là rất quan trọng để kiểm soát layout ở các kích thước màn hình khác nhau. Đây là một phần không thể thiếu khi tìm hiểu CSS float là gì.

Vấn đề nan giải: Clearfix và sự sụp đổ của phần tử cha

Việc sử dụng float để tạo layout mang lại một vấn đề rất khó chịu. Đó là hiện tượng phần tử cha không thể bao bọc được các phần tử con bị float.

Hiện tượng “sụp đổ” (Collapsing Parent): Nỗi ám ảnh của người dùng Float

Hãy tưởng tượng bạn có một div cha chứa hai div con bên trong. Bạn đặt float: left cho cả hai div con để chúng nằm cạnh nhau. Điều kỳ lạ sẽ xảy ra. Chiếc div cha, thay vì mở rộng ra để bao bọc cả hai đứa con, lại co lại. Nó hành xử như thể bên trong nó không hề có nội dung gì cả. Chiều cao của nó gần như bằng không. Nếu bạn đặt một màu nền hoặc đường viền cho div cha, bạn sẽ thấy rõ vấn đề này. Màu nền sẽ không hiển thị đúng.

Nguyên nhân là vì khi các phần tử con bị float, chúng bị đưa ra khỏi luồng trang bình thường. Phần tử cha lúc này không còn “nhận biết” được chiều cao của những đứa con đang “trôi nổi” đó nữa. Nó tự co lại theo chiều cao của các nội dung không bị float (nếu có) bên trong nó. Hiện tượng này được gọi là “collapsing parent”. Nó gây ra rất nhiều phiền toái trong việc tạo bố cục. Đây là vấn đề lớn nhất của CSS float.

Giải pháp Clearfix: “Dọn dẹp” sau khi float để khôi phục luồng trang

Để khắc phục hiện tượng “sụp đổ” này, các nhà phát triển đã sáng tạo ra một kỹ thuật gọi là “Clearfix”. Mục đích của clearfix là buộc phần tử cha phải nhận biết và bao bọc lấy các phần tử con đã bị float. Có nhiều cách để thực hiện clearfix. Tuy nhiên, phương pháp phổ biến và đáng tin cậy nhất là sử dụng pseudo-element ::after.

Kỹ thuật này hoạt động như sau: Bạn sẽ tạo một lớp CSS (ví dụ: đặt tên là .clearfix). Sau đó, bạn áp dụng lớp này vào phần tử cha đang bị sụp đổ. Đoạn code CSS cho lớp .clearfix thường có dạng:

CSS

.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

Giải thích:

  • .clearfix::after: Tạo ra một phần tử ảo ngay sau nội dung của phần tử cha.
  • content: “”;: Phần tử ảo này không có nội dung thực tế.
  • display: table;: Biến phần tử ảo này thành một dạng bảng đặc biệt. Nó giúp tạo ra một ngữ cảnh định dạng khối mới.
  • clear: both;: Đây là thuộc tính quan trọng nhất. Nó ra lệnh cho phần tử ảo này phải được đẩy xuống dưới tất cả các phần tử đang float (cả left và right) trước đó. Chính hành động này đã “buộc” phần tử cha phải mở rộng chiều cao của mình để chứa cả phần tử ảo. Và do đó, nó cũng chứa luôn cả các phần tử con bị float. Việc hiểu và sử dụng clearfix là bắt buộc khi bạn dùng CSS float cho layout.

Các phương pháp Clear khác: Overflow và Display: flow-root

Ngoài kỹ thuật ::after cổ điển, còn có một vài cách khác để “clear” float.

  • Sử dụng overflow: hidden; hoặc overflow: auto;: Một cách đơn giản hơn là đặt thuộc tính overflow với giá trị hidden hoặc auto trực tiếp cho phần tử cha. Thuộc tính này cũng tạo ra một ngữ cảnh định dạng khối mới. Nó cũng buộc phần tử cha phải bao bọc các con bị float. Tuy nhiên, cách này có thể gây ra các tác dụng phụ không mong muốn. Ví dụ, nếu nội dung bên trong vượt quá kích thước, nó có thể bị cắt mất (hidden) hoặc xuất hiện thanh cuộn (auto).
  • Sử dụng display: flow-root;: Đây là giải pháp hiện đại và “sạch sẽ” nhất do chính CSS cung cấp. Bạn chỉ cần đặt display: flow-root; cho phần tử cha. Nó sẽ tự động tạo ra ngữ cảnh định dạng khối mới và bao bọc các float mà không gây ra bất kỳ tác dụng phụ nào của overflow. Tuy nhiên, flow-root là một giá trị tương đối mới. Các trình duyệt rất cũ có thể không hỗ trợ nó. Khi tìm hiểu về CSS float là gì, bạn nên biết về tất cả các phương pháp clear này.

CSS Float trong Kỷ nguyên Hiện đại: Khi nào nên và không nên dùng?

Với sự ra đời của Flexbox và Grid, vai trò của float đã thay đổi hoàn toàn. Nó không còn là công cụ chính để xây dựng layout nữa.

Sự trỗi dậy của Flexbox và Grid: Giải pháp layout ưu việt hơn

Flexbox và Grid là hai module layout cực kỳ mạnh mẽ. Chúng được thiết kế đặc biệt để giải quyết các bài toán về sắp xếp và căn chỉnh phần tử một cách linh hoạt và hiệu quả. So với việc dùng CSS float để “hack” layout, chúng có những ưu điểm vượt trội. Chúng cho phép căn chỉnh các phần tử theo cả chiều ngang và dọc một cách dễ dàng. Việc căn giữa theo chiều dọc, vốn là một cơn ác mộng với float, trở nên cực kỳ đơn giản. Chúng cũng hỗ trợ việc tạo ra các thiết kế đáp ứng (responsive) một cách tự nhiên hơn. Bạn có thể dễ dàng thay đổi thứ tự hiển thị của các phần tử mà không cần thay đổi cấu trúc HTML.

Quan trọng nhất, Flexbox và Grid không gây ra hiện tượng “sụp đổ phần tử cha”. Chúng có cơ chế riêng để phần tử cha luôn bao bọc các phần tử con. Vì những lý do này, đối với việc xây dựng bố cục chính của trang web (như tạo cột, sidebar, header, footer), Flexbox và Grid là lựa chọn tiêu chuẩn và được khuyến khích sử dụng thay thế hoàn toàn cho float.

Vai trò còn lại của CSS Float ngày nay: Quay về mục đích ban đầu

Vậy liệu CSS float có còn hữu dụng trong thế giới hiện đại? Câu trả lời là có, nhưng phạm vi ứng dụng của nó đã bị thu hẹp lại đáng kể. Vai trò chính của float ngày nay chính là quay trở lại mục đích ban đầu của nó. Đó là để cho phép văn bản bao quanh một hình ảnh hoặc một phần tử nội tuyến khác.

Hãy tưởng tượng bạn có một bài viết blog dài. Bạn muốn chèn một bức ảnh minh họa vào đầu đoạn văn. Bạn muốn văn bản của đoạn đó chảy xung quanh bức ảnh một cách tự nhiên. Trong trường hợp này, việc sử dụng float: left hoặc float: right cho thẻ <img> là giải pháp đơn giản và hiệu quả nhất. Việc sử dụng Flexbox hay Grid chỉ để giải quyết bài toán nhỏ này sẽ trở nên quá phức tạp và không cần thiết. Tương tự, bạn cũng có thể dùng float cho các biểu tượng nhỏ nằm cạnh tiêu đề.

Hoặc dùng cho các đoạn trích dẫn (pull-quotes) muốn nổi bật ra khỏi dòng văn bản chính. Tóm lại, CSS float vẫn là một công cụ hữu ích. Nhưng nó chỉ nên được dùng cho các tác vụ cục bộ, liên quan đến việc sắp xếp nội dung nội tuyến.

Kết luận

Qua bài viết chi tiết này, hy vọng bạn đã có một câu trả lời toàn diện cho câu hỏi “CSS float là gì?”. Nó là một thuộc tính CSS có lịch sử lâu đời. Nó từng là công cụ chính để xây dựng layout web. Nhưng ngày nay, vai trò đó đã được thay thế bởi Flexbox và Grid. Tuy nhiên, float vẫn giữ một vị trí quan trọng cho mục đích ban đầu của nó. Đó là tạo ra hiệu ứng văn bản bao quanh hình ảnh. Việc hiểu rõ cách hoạt động, các vấn đề tiềm ẩn (như sụp đổ phần tử cha) và các giải pháp khắc phục (clearfix) vẫn là một phần kiến thức nền tảng quan trọng cho bất kỳ ai làm việc với CSS.