Về ba cái thứ này thì dân tình chơi web chắc hẳn phải biết, nhưng với các bạn mới bắt đầu với html, css thì có lẽ cũng còn mông lung lắm, hoặc các bạn năm học NMĐT ở BKU thì chắc cũng như mình hồi đó, rối não với cái vụ float, và position, … Tối nay đọc sách về design, cũng liên quan đến mấy cái trên tiêu đề, mình note lại đây để lưu trữ, cũng như bổ sung lại kiến thức cho các bạn còn mông lung …… Oke, đã xong phần intro, chúng ra bắt đầu đi tìm triệu phú, … à nhầm, đi vào khái niệm cơ bản đầu tiên :p
Normal Flow
(Thiệt tình mình chả biết dịch cái cụm này ra Tiếng Việt như nào đâu, không lẽ là “dòng chảy bình thường”, nghe nó cứ sida, nên để vậy nhé, chỉ cần hiểu nghĩa của nó là tự tin chiến tốt rồi, sau này đọc sách có gặp thì cũng đỡ bàng hoàng)
Normal flow nói đến cách mà trình duyệt hiển thị các phần tử thuộc loại block (block-level elements) và các phần tử thuộc loại inline (inline elements) theo cách bình thường từ trên xuống dưới, từ trái sang phải.
- Các block-level element như
<div>, <p>, <ul>, <table>, <h1>, <h2>, ...
sẽ được bố trí từ trên xuống (top-to-bottom), thằng nào được định nghĩa trước thì nằm trên, mỗi thằng sẽ bắt đầu bởi một hàng ngang mới và cówidth
bằng vớiwidth
của cái “nơi chứa nó” (container), như vậy nó sẽ chiếm dụng nguyên một hàng, vì thế 2 block-level element sẽ không thể tồn tại trên cùng một hàng.

- Ngược lại, inline element như
<a>, <img>, <em>, <span>,...
sẽ được bố trí trên cùng một hàng ngang, từ trái sang phải cho đến khi không còn chỗ trống trên hàng đó thì nó sẽ tự động sang hàng mới. Có 2 loại phần tử inline là replaced và nonreplaced- Replaced inline elements: Là các phần tử có nội dung là hình dáng được định nghĩa ở nguồn ngoài file html như
<img>, <video>, <embed>, <iframe>
. Loại này sẽ cówidth
vàheight
được quy định bởi nguồn của nó. - Nonraplaced inline elements: Là các phần tử có nội dung được định nghĩa ngay trong file html, những phần tử loại này có
width
vàheight
phụ thuộc vào nội dung của nó và các thuộc tính khác nhưfont-size, letter-spacing,...
Cách bố trí các phần tử inline - Các phần tử inline sẽ tự sắp xếp lại để phù hợp với kích thước của cửa sổ trình duyệt khi nó thay đổi hoặc khi cái container của nó thay đổi kích thước
- Replaced inline elements: Là các phần tử có nội dung là hình dáng được định nghĩa ở nguồn ngoài file html như

Với normal flow thì block-level elements và inline element thường được dùng cùng nhau. Block-level bố trí từ trên xuống, inline bố trí từ trái sang phải. Nếu một block chứa một block khác thì cũng xảy normal flow vẫn đúng cho cái block đó.
Floating
float
là thuộc tính trong CSS có tác dụng lôi một phần tử nào đó ra khỏi normal flow của nó và ném nó về phía bên trái hoặc phải (chỉ trái phải thôi, không có trên dưới đâu). Các phần tử khác vẫn theo đúng normal flow.
float
Values: left | right | none | inherit
Default: none
Applies to: All elements
Inherit: no
Với đoạn code html
:
1 2 3 4 5 6 7 8 9 10 11 |
<html> <p> <img src="picture.png" alt="">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi blandit id lectus vel mollis. Sed consectetur lorem risus, non varius nibh dictum quis. In tincidunt lacinia tortor egestas elementum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce fringilla fringilla mauris. Nulla sollicitudin iaculis dolor sit amet auctor. Pellentesque eget euismod libero, vel facilisis massa. In hac habitasse platea dictumst. Curabitur nibh dolor, pharetra ac fermentum vitae, vestibulum non nisl. Maecenas rhoncus nisl felis, a ornare nunc tincidunt eget. Donec ornare libero laoreet vestibulum ornare. Proin vel purus volutpat, ultrices lacus vitae, cursus diam. Phasellus ultricies eu dolor sed rhoncus. In pellentesque elit erat, nec commodo nunc rhoncus vitae. Vivamus ac venenatis enim. Phasellus sed tellus tincidunt, porttitor neque vel, tempor tellus. Praesent nisl lectus, suscipit a eleifend eu, vestibulum non libero.</p> </html> |
Thì ta có kết quả

Nhưng gán thuộc tính float
cho img
ta sẽ được
1 2 3 |
img { float: right; } |
Ta có hình dung phần tử được float (floated element) giống như một hòn đá nổi lên giữa dòng suối đang chảy, các phần tử khác sắp xếp theo normal flow nhưng nội dung của chúng không bị phần tử được float đè lên mà hiển thị bao quanh phần tử được float, như dòng nước chảy quanh hòn đá (tất nhiên là trừ cái phần nước không chảy được, phía sau hòn đá ra nhé, float element cũng vậy, cái phần nó tiếp giáp với cái container của nó ấy).
Để ý <p>...</p>
vẫn nằm theo đúng normal flow nhé, nó bị <img>
đè lên nhưng phần nội dung của nó thì tự động sắp xếp xung quanh <img>
và không bị đè lên.
Mặc dù bị lôi ra khỏi normal flow nhưng floated elements vẫn nằm trong khu vực nội dung của container chứa nó (như ví dụ trên thì container của img
là <p>..</p>
Float phần tử inline
html
như này
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<html> <p> <span class="alert">In lacinia elit mi, id viverra justo suscipit eget. Cras tempor augue ligula, in ultricies mi fermentum nec. Morbi aliquet venenatis mi, vitae molestie turpis congue placerat </span> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi feugiat, nibh id consectetur eleifend, quam arcu euismod ligula, ac dictum felis lorem in enim. Suspendisse nec elit nec dolor ultrices dictum. Donec suscipit ornare odio vel laoreet. Pellentesque ullamcorper eu ex vitae varius. Morbi auctor lacus sem, sed pharetra massa tincidunt eget. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam semper laoreet odio, nec fermentum erat. Cras malesuada aliquam volutpat. Aliquam neque lacus, dapibus ut nisl nec, lobortis mattis metus. Nullam imperdiet metus a laoreet dapibus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam et ante mauris. Morbi faucibus massa ac metus lacinia ullamcorper. Donec porta cursus nunc, eu placerat enim congue sed. </p> </html> |
Với đoạn CSS này
1 2 3 4 5 6 7 8 9 10 11 12 |
.alert { float: right; margin: 12px; background: yellow; padding: 8px; border: 1px solid green; } p{ border: 1px solid red; padding: 16px; } |
Và kết quả như này
Và quá dễ để thấy rằng cái phần màu vàng kia nó đã không float right
như theo ý muốn, vấn đề do đâu? – Do là ta đã không set width
cho nó, thì mặc nhiên nó sẽ lấy with theo cái container
, đúng theo phần normal flow ở trên đã nói. Inline element sẽ hiển thị nội dung của nó cho đến khi hết độ rộng của hàng đó thì nó xuống hàng kế tiếp, nếu không set width
thì rõ ràng witdth
của nó sẽ được tính theo width
của container. Thực chất nó vẫn float right
nhưng vì width
bằng với container
nên ta không thể thấy rõ ràng được.
Chỉ cần set width
lại là xong
1 2 3 4 5 |
.alert { width: 300px; float: right; .... } |
Vậy thì sao ở ví dụ trước thì img
cũng là inline element mà ta không phải set width cho nó? – Bởi vì img
thuộc loại replaced inline element, nên width nó đã được quy định, còn span
là nonreplaced inline element, width
của nó phục thuộc vào nội dung.
Có một vài lưu ý nữa đó là khi một phần tử inline được float thì nó sẽ giống như một phần tử block-level. Nó tuân theo normal flow của phần tử block-level, nếu như nó có margin thì margin sẽ có tác dụng ở cả 4 hướng, trong khi inline thì margin-top và margin-bottom thường bị bỏ qua. Nếu như margin của phần tử float kề với marign của một phần tử bình thường khác thì nó sẽ không được gộp chung như thông thường. Như hình sau thì bạn thấy marign của tấm hình là màu đỏ, của đoạn văn là màu tím, chúng tách biệt, không được gộp chung như giữa 2 đoạn văn với nhau

Float phần thử block-level
Với đoạn html
và CSS như sau
1 2 3 4 5 6 7 8 9 10 11 |
<html> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vel mauris sapien. Mauris tincidunt orci et augue mattis, id ultrices erat consectetur. Aenean id ante sed neque ultricies mattis. Nunc posuere neque vel consectetur commodo. Morbi maximus nisl eget lectus posuere lobortis. Cras aliquet erat in elementum lacinia. Nullam diam nunc, rhoncus eget tortor sit amet, condimentum rutrum nisi. Integer id porttitor ligula, vel cursus dui. Aenean quis risus eget dolor varius congue. </p> <p id="second"> Curabitur eu lectus non nunc imperdiet porta. Phasellus vitae nulla consequat, ultrices ex nec, ornare lectus. Curabitur et consequat dui. Vivamus fringilla mi ac odio rhoncus auctor. Vestibulum a lacinia quam. Fusce accumsan facilisis finibus. Fusce quis lorem cursus, rhoncus tellus in, vulputate felis. Aliquam elementum ante tincidunt, suscipit turpis id, malesuada ex. Duis sit amet tincidunt diam, in mollis lorem. </p> <p> Nam consequat, sapien in interdum blandit, lectus massa tempus felis, vel feugiat tellus velit non sem. Mauris scelerisque justo mauris, at convallis felis porta nec. Integer luctus, augue vel viverra egestas, sapien lorem fermentum leo, sit amet porttitor felis erat eu diam. Duis ut scelerisque lacus. Nulla placerat ligula eu felis tristique porta. Nulla euismod tempus arcu. Aliquam posuere pretium sapien, a elementum enim consequat ac. Fusce ut justo eu enim vehicula interdum nec ut eros. Duis sit amet suscipit odio, ac semper turpis. Quisque eleifend enim in leo ullamcorper, faucibus accumsan lacus aliquet. Donec pretium vel ante quis venenatis. Proin dapibus consequat turpis at imperdiet. Curabitur eu lectus non nunc imperdiet porta. Phasellus vitae nulla consequat, ultrices ex nec, ornare lectus. Curabitur et consequat dui. Vivamus fringilla mi ac odio rhoncus auctor. Vestibulum a lacinia quam. Fusce accumsan facilisis finibus. Fusce quis lorem cursus, rhoncus tellus in, vulputate felis. Aliquam elementum ante tincidunt, suscipit turpis id, malesuada ex. Duis sit amet tincidunt diam, in mollis lorem. </p> </html> |
1 2 3 4 5 6 7 8 9 10 |
#second { float: left; background: yellow; width: 200px; margin-top: 0; } p { border: 1px solid blue; } |
Ta sẽ có kết quả
Việc float các phần tử block-level cũng có một số điểm tương tự như float các phần tử inline, ta cũng phải set width cho phần tử được float, nếu không thì width của phần tử đó sẽ nhận giá trị auto, tương tự như inline element trên kia, nó sẽ được tính theo width của container chứa nó.
Một đặc điểm nữa của float đó là phần tử được float nó sẽ di chuyển theo phương ngang về phía trái hoặc phải nhưng vị trí của nó theo chiều dọc vẫn được giữ nguyên, nghĩa là nó sẽ vẫn nằm ngay sau phần tử đứng trước nó (chú ý là block-level element bắt đầu vị trí của nó bằng một hàng mới), những phần tử đứng sau nó thì sắp xếp nội dung xung quanh nó. Như vậy nếu ta muốn float một phần tử nào đó để nó bắt đầu hiển thị ngay từ đầu trang thì nó phải nằm ở vị trí đầu trong source code. Bạn nên chú ý điều này khi sử dụng float để tạo layout nhiều cột, giả sử như layout của bạn có cột navigation bar nằm ở phía bên trái thì trong souce code, phần code cho navigation bar phải nằm trên phần code cho việc hiển thị nội dung. Mình sẽ nói rõ hơn về vấn đề này trong bài viết về layout.
Ở ví dụ trên ta thấy phần nội dung được float (màu vàng) nằm sau đoạn văn thứ nhất, còn đoạn văn thứ 3 hiển thị kế tiếp theo.
Clearing
Bên cạnh float
thì CSS có thêm clear
, một phần tử được áp dụng thuộc tính clear thì nó sẽ không phải xếp nội dung chạy theo phần tử được float nữa và sẽ bắt đầu ở khoảng trống tiếp theo phần tử được float (đa số trường hợp là hàng (line) mới).
float
Values: left | right | both | none | inherit
Default: none
Applies to: block-level elements only
Inherits: no
clear: left
, không chạy theo phần thử đượcfloat: left
clear: right
, không chạy theo phần tử đượcfloat: right
clear: both
, không chạy theo cả phần tử đượcfloat: left,
và phần tử đượcfloat: right
Lưu ý một điều là áp dụng clear với phần tử bạn muốn nội dung của nó không chạy theo phần tử được float nữa chứ không phải phần tử được float nhé.
Clear được áp dụng nhiều khi tạo footer, hay xử lý các vụ overflow khi sử dụng float.
Ví dụ nhé
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<html> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vel mauris sapien. Mauris tincidunt orci et augue mattis, id ultrices erat consectetur. Aenean id ante sed neque ultricies mattis. Nunc posuere neque vel consectetur commodo. Morbi maximus nisl eget lectus posuere lobortis. Cras aliquet erat in elementum lacinia. Nullam diam nunc, rhoncus eget tortor sit amet, condimentum rutrum nisi. Integer id porttitor ligula, vel cursus dui. Aenean quis risus eget dolor varius congue. </p> <p id="second"> Curabitur eu lectus non nunc imperdiet porta. Phasellus vitae nulla consequat, ultrices ex nec, ornare lectus. Curabitur et consequat dui. Vivamus fringilla mi ac odio rhoncus auctor. Vestibulum a lacinia quam. Fusce accumsan facilisis finibus. Fusce quis lorem cursus, rhoncus tellus in, vulputate felis. Aliquam elementum ante tincidunt, suscipit turpis id, malesuada ex. Duis sit amet tincidunt diam, in mollis lorem. </p> <p> Nam consequat, sapien in interdum blandit, lectus massa tempus felis, vel feugiat tellus velit non sem. Mauris scelerisque justo mauris, at convallis felis porta nec. Integer luctus, augue vel viverra egestas, sapien lorem fermentum leo, sit amet porttitor felis erat eu diam. Duis ut scelerisque lacus. Nulla placerat ligula eu felis tristique porta. Nulla euismod tempus arcu. Aliquam posuere pretium sapien, a elementum enim consequat ac. Fusce ut justo eu enim vehicula interdum nec ut eros. Duis sit amet suscipit odio, ac semper turpis. Quisque eleifend enim in leo ullamcorper, faucibus accumsan lacus aliquet. Donec pretium vel ante quis venenatis. Proin dapibus consequat turpis at imperdiet. Curabitur eu lectus non nunc imperdiet porta. Phasellus vitae nulla consequat, ultrices ex nec, ornare lectus. Curabitur et consequat dui. Vivamus fringilla mi ac odio rhoncus auctor. Vestibulum a lacinia quam. Fusce accumsan facilisis finibus. Fusce quis lorem cursus, rhoncus tellus in, vulputate felis. Aliquam elementum ante tincidunt, suscipit turpis id, malesuada ex. Duis sit amet tincidunt diam, in mollis lorem. </p> <footer> <p> Curabitur eu lectus non nunc imperdiet porta. Phasellus vitae nulla consequat, ultrices ex nec, ornare lectus </p> </footer> </html> |
CSS (chưa có clear)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#second { float: left; background: yellow; width: 200px; margin-top: 0; } p { border: 1px solid blue; } footer { background: grey; } |
Kết quả:
Thêm clear vào cho footer
1 2 3 4 5 |
... footer { ... clear: both; } |
Kết quả