Tìm hiểu về Float, Block, Inline-Block trong CSS

Tìm hiểu về Float, Block, Inline-Block trong CSS

Ngày nay, chúng ta thường sử dụng phần tử float (trôi nổi) khi tạo layout khá phổ biến kể từ cách layout bằng phần tử table đã đi vào quá khứ. Đó là một giải pháp lạ lùng và thường gây không ít rắc rối cho chúng ta, nhưng nếu bạn thật sự nắm rõ về nó, đó là một cách làm hiệu quả.

Một phương pháp thường được thay thế cho float đó là dùng inline-block cùng các thiết lập các giá trị display cho nó. Chính xác là phải làm thế nào? Làm thế nào để nó hoạt động giống float? Sự khác nhau? Hãy cũng tôi đào sâu hơn và khám phá các phần tử này.

Tìm hiểu thuộc tính display

Trình duyệt web biên dịch các thành phần khác nhau theo nhiều các khác nhau. Một số phần tử là cấp độ khối (block-level), nghĩa là mặc định chúng có thuộc tính display là block (khối). Những phần tử cấp độ khối có thể được xác định chiều ngang và chiều cao và sẽ tự động thêm một dòng (hàng) mới trên trang tài liệu nếu được thêm vào.

Một ví dụ cho phần tử khối đó là đoạn văn bản (paragraph). Nếu bạn có hai đoạn văn bản đặt kế nhau, chúng sẽ xếp chồng lên nhau chứ không phải đứng cạnh nhau. Bạn có thể tự do thiết lập kích thước cho các đoạn văn bản và xem nó như những viên gạch xây dựng để sắp xếp hình thù xếp theo ý muốn.

inlineBlock-1

Một số phần tử khác có giá trị display được thiết lập nội tuyến (inline) mặc định. Điều này có nghĩa là chúng không thể xác định được chiều cao và chiều ngang và cũng không tạo thêm dòng (hàng) trong layout (vì thế chúng mới có tên là inline – nội tuyến). Những phần tử inline thường có biên chế trong một đoạn văn bản hoặc hoặc các phần tử cấp độ khối (block-level) khác như strong, em , anchor …

Đây là những gì sẽ xảy ra đối với các phần tử nội tuyến (inline) khi xếp chúng cạnh nhau. Ví dụ như ta có một số phần tử anchor (thẻ a) trong trang HTML, không giống như các đoạn văn bản ở trên, chúng sẽ xếp chồng lên nhau, ở đây các phần tử được tạo ra sẽ xếp cạnh nhau. Chiều cao và rộng sẽ được quyết định bởi nội dung bên trong nó và không thể thay đổi như các phần tử cấp độ khối (block-level)

inlineBlock-2

Trên đây là một vài giá trị mặc định của display chắc hẵn các bạn cũng đã quen thuộc. Tương tự ở phần head giá trị display luôn mặc định là none.

Thiết lập giá trị display  riêng cho bạn

Một trong những tính năng thú vị của CSS chính là khả năng thay đổi cách hiển thị (display ) của các phần tử. Mặc dù mỗi phần tử được gán cho một giá trị display mặc định, nhưng chúng ta vẫn buộc chúng hiển thị theo ý muốn của mình.

Vi dụ, chúng ta có thể dể dàng buộc các thẻ anchor có giá trị mặc định là nội tuyến (inline) ở ví dụ 2 để bắt chúng có những tính chất như các đoạn văn bản (pagragraph) có cấp độ khối (block-level) như ở ví dụ 1. Để thực hiện điều này, chúng ta sẽ thiết lập thuộc tính block trong CSS.

Bây giờ các thẻ anchor có tính chất giống như các phần tử cấp độ khối (block-level), chúng sẽ tạo thêm dòng mới và có thể xác định chiều cao và chiều ngang.

inlineBlock-3

Như bạn cũng hình dung ra, sẽ khó hơn nếu chúng ta làm ngược lại, buộc phần tử có giá trị cấp độ khối (block-level) có tính chất như của phần tử nội tuyến (inline). Thông thường bạn sẽ nghĩ ngay đến cách thiết lập display: inline để buộc hai đoạn văn bản (paragraph) xếp cạnh nhau, nhưng khi thực hiện, kết quả là cả hai nối lại với nhau thành một đoạn văn bản (paragraph)

inlineBlock-4

Vào lúc này, chúng ta đã mất hết khả năng thiết lập chiều ngang và chiều cao (tính chất của inline), do đó hai đoạn văn bản (paragraph) sát nhập lại với nhau không như ý muốn.

Phần tử trôi nổi – Floating Elements

Như ví dụ ở trên, chúng ta muốn hai đoạn văn bản (paragraph) vẫn giữ tách biệt nhưng phải hiển thị xếp cạnh nhau theo cột chứ không phải xếp chồng lên nhau. Câu trả lời đa số cho trường hợp này đó là chuyển sang sử dụng float. Chúng ta có thiết lập float:left để các đoạn văn bản (paragraph) vẫn duy trì tính năng của một phần tử cấp độ khối (block-level) đồng thời hiển thị theo từng cột nội dung như ý muốn.

Float có nhiều tính năng phải lưu ý. Ví dụ, những phần tử float sẽ khiến cho phần tử chứa nó (container element) bị co lại (colapsed – rỗng nội dung và gây vỡ layout), kèm theo đó là vô số những rắc rối khác nếu bạn áp dụng màu nền (backgound color) và đường biên (border) cho phần tử chứa nó (container element). Để làm đúng cách, bạn phải sử dụng vài mánh khóe. Chúng ta sẽ xóa tính năng float trên các phần tử mới (ngày nay thường áp dụng phần tử lớp giả – pseudo-element) ở cuối phần tử chứa nó (container element) hoặc sử dụng overflow:auto ở phần tử cha mẹ parent của nó. Cả hai cách đều sửa được rắc rối cho phần tử chứa float (container element), nếu bạn biết cách làm thế nào để sử dụng đúng cách, bạn sẽ có thể xây dựng một layout như ý mà không gặp quá nhiều phiền toái.

display: inline-block

Có vô số giá trị cho thuộc tính display như chúng ta đã biết ở trên, một số thật sự hữu dụng, một số khác, tôi cá là bạn chưa bao giờ đụng đến. Cuộc thảo luận của chúng ta đã đi đến một trong những giá trị hữu dụng nhất của display đó là inline-block (khối nội tuyến)

Hãy xem chuyện gì sẽ xảy ra nếu chúng ta lấy hai đoạn văn bản ở ví dụ trên và gán giá trị display là inline-block

inlineBlock-6

Trông chúng giống float phải không nào? OK, vậy thì chuyện gì sẽ xảy ra với phần tử chứa nó (container hay parent) ? Không sao cả! Mọi thứ đều hoạt động như ý muốn của chúng ta.

inlineBlock-7

Những gì xảy ra ở đây đó là chúng ta khai báo cho trình duyệt hiển thị các đoạn văn bản nội tuyến (paragraph inline) nhưng cho phép chúng có thuộc tính của cấp độ khối (block-level). Có nghĩa là chúng ta có thể xác định chiều cao và chiều ngang tùy ý và vẫn có hai phần tử tách biệt, nhưng còn giữ cho chúng xếp cạnh nhau thành cột. Thật tuyệt vời!

Vấn đề so hàng (alignment)

Nhìn bề ngoài, có vẻ như inline-block là vị cứu tinh mà chúng ta chờ đợi. Chẳng ai muốn phiền toái phải dùng thủ thuật clearfix nếu áp dụng float. Phải chăng đây là phương pháp thay thế float hữu hiệu? Không hẵn như vậy, inline-block cũng có những vấn đề gây đau đầu không kém.

Điều đầu tiên, những phần tử float và inline-block sẽ trông khác nhau nếu bạn mỗi phần tử có chiều cao khác nhau. Ví dụ, đây là những gì bạn sẽ thấy nếu áp dung float:left cho loạt loạt văn bản (paragraph)

inlineBlock-8

Còn đây là những gì sẽ xảy ra nếu bạn áp dụng inline-block tên cùng các đoạn văn bản (paragraph). Bạn có nhận thấy rằng các đoạn văn bản so hàng theo đáy (bottom) với nhau thay vì so hàng theo đỉnh (top) như ở trên.

inlineBlock-12

May mắn đây không phải là vấn đề quá khó khăn, chúng ta có thể giải quyết bằng cách thiết lập thuộc tính so hàng theo chiều đứng (vertical-align) là đỉnh (top)

inlineBlock-11

Vấn đề khoảng trắng

Một vấn đề quan trong khác mà giữa inline-block và float có sự khác biệt. Đây cũng là vấn đề chung thường thấy của HTML và CSS đó là khoảng trắng trong thiết kế web layout. Hãy xem ví dụ sau đây:

inlineBlock-13

Chúng ta có thể thấy rằng, đối với một nhóm list-items khi được gán float, chúng xếp hàng sát cạnh nhau như chúng ta trông đợi, điều này cho phép chúng ta có thể thiết lập các khoảng hở giữa từng item chính xác mà không phát sinh thêm khoảng trắng dư thừa nào. Tuy nhiên, nếu thực hiện tương tự với cách dùng inline-block, có một khoảng hở mặc định không cách nào loại trừ ngay cả khi bạn thiết lập lề (margin) bằng 0.

Như các bạn có thể thấy, chúng ta cần một giải pháp để loại trừ các khoảng trắng trong trang HTML và đẩy các phần tử đứng ngay sát cạnh nhau. Một lần nữa, tôi tìm thấy một cách hơi có một chút rối rắm nhưng hiệu quả. Giải pháp này cho kết quả tốt mà không xáo trộn hệ thống phân cấp trong HTML đó là áp dụng lề (margin) -4px lên mỗi item.

inlineBlock-14

Sự hỗ trợ của các trình duyệt

Bây giờ bạn đã biết inline-block có tính năng khác biệt với float như thế nào, đây là lúc thảo luận chủ đề ưa thích của mọi người: sự hỗ trợ của các trình duyệt. Những kỹ thuật nêu trên có thật sự là giải pháp tốt để chúng có thể hoạt động tốt trên mọi trình duyệt ? Kết quả thật sự tốt hơn những gì chúng ta mong chờ.

inlineBlock-15

Chúng ta có thể thấy hầu hết các trình duyệt đều hỗ trợ tốt cho giải pháp trên ngoại trừ IE7 (đã bị loại bỏ trong danh sách trình duyệt phổ biến ngày nay), nếu bạn muốn cả IE6 và 7 hỗ trợ, bạn có thể dùng thủ thuật với thuộc tính zoom và dùng dấu * để nhắm đến chỉ áp dụng cho trình duyệt IE6/7 (ngày nay không còn cần thiết).

 li {
 display: inline-block;
 width: 100px;
 vertical-align: top;
 
 /*Dirty IE Hack - chỉ áp dụng cho IE6 và 7*/
 zoom: 1;
 *display: inline;
}

Xem thêm

Nếu bạn muốn nghiên cứu thêm về những gì chúng ta đã thảo luận, các bạn có thể xem thêm các bài viết sau:

Nguồn: biên dịch theo “What’s the Deal With Display: Inline-Block?” | Joshua Johnson | Designshack.net