Floating trong css

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ới width 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.
block-level-elements
Cách bố trí các phần tử block
  • 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,...

      inline-elements
      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
inline-elements-resize
Các phần tử inline được bố trí lại

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 :

Thì ta có kết quả

no-float-element
HIển thị mặc định, không có phần tử nào được float

Nhưng gán thuộc tính float cho img ta sẽ được

img-float-right.png
Float right phần tử img

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).

img-float-right-2.png

Để ý <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.

 Standing-Like-a-Rock-in-the-Stream.jpg

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

Với đoạn CSS này

Và kết quả như này

float-inline-element-without-width

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

float-inline-element-have-width.png

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

margin-not-collapse.png
Page 194 – Fundamentals of Web Development

Float phần thử block-level

Với đoạn html và CSS như sau

Ta sẽ có kết quả

block-float-width.png

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ử được float: left
  • clear: right, không chạy theo phần tử được float: right
  • clear: both, không chạy theo cả phần tử được float: left, và phần tử được float: 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

CSS (chưa có clear)

Kết quả:

footer-no-clearing.png

Thêm clear vào cho footer

Kết quả

footer-have-clearing.png

Leave a Reply

Your email address will not be published. Required fields are marked *