22/10/2018, 22:43

Rắc rối với Floating và Clearfix

Bạn đã và đang làm việc với CSS, thì hẳn bạn chẳng hề xa lạ gì với float và clearfix, tuy nhiên có thể bạn chưa nắm rõ được chức năng của nó mà cứ dùng vậy thôi, miễn là nó hiển thị không sai ý đồ của bạn. Bài viết dưới đây mình sẽ giải thích về chức năng và cơ chế của float và clearfix trên cơ ...

Bạn đã và đang làm việc với CSS, thì hẳn bạn chẳng hề xa lạ gì với float và clearfix, tuy nhiên có thể bạn chưa nắm rõ được chức năng của nó mà cứ dùng vậy thôi, miễn là nó hiển thị không sai ý đồ của bạn.

Bài viết dưới đây mình sẽ giải thích về chức năng và cơ chế của float và clearfix trên cơ sở hiểu biết của mình.

Floating

Mặc định, một thẻ div sẽ chiếm hết một dòng, và không có một element nào có thể nằm ngay sau nó được, mà phải sang một dòng khác.

Ví dụ:

<div class="container">
    <div class="box red"> Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia
    </div>
    <div class="box blue"> 
      Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia
    </div>
    <div class="box green">
      Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia 
   </div>
</div>>

Ta được kết quả sau:

Nhưng nhiều lúc chúng ta muốn sắp xếp các đối tượng nối tiếp nhau trên cùng 1 dòng. Khi đó chúng ta sẽ phải dùng một thuộc tính của CSS gọi là float, chức năng của thuộc tính này là khiến cho các element nằm ngay sau nó bị trôi theo element mang thuộc tính float.

Chẳng hạn, ta gán thuộc tính float: left; cho các div có class là box như sau:

.box {
    float: left;
}

Kết quả là các thẻ box sẽ nằm lên cùng 1 dòng, như hình dưới:

Có 2 kiểu là float: left và float: right, tương ứng với 2 chiều trôi của element sang trái và phải.

Clear float

Trong trường hợp chúng ta muốn bỏ thuộc tính float của một element đi, ví dụ trong trường hợp ở hình sau:

Chúng ta không muốn box .green bị trôi theo box .blue mà muốn nó nằm trên một dòng riêng biệt, khi đó, chúng ta dùng thuộc tính clear.

Chức năng của thuộc tính này là dọn đường thông thoáng về bên trái left hoặc phải right hoặc cả 2 bên both, khi bị dọn dẹp sạch sẽ như vậy thì element đó sẽ ko bị trôi theo element trước đó nữa.

Ở ví dụ hình trên, ta sẽ gán thêm 1 thuộc tính clear: left cho box green, có class là .green, dọn dẹp phần bên trái của nó để không cho nó trôi theo box blue nữa.

.green {
    clear: left;
}

Rắc rối của float

Khi sử dụng float, chúng ta sẽ gặp phải những tình huống lỗi rất khó chịu như demo dưới đây:

Ở đây chúng ta có một thẻ div cha, chứa 3 thẻ div con mang thuộc tính float: left, nếu có thêm một nội dung nằm sau div cha, thì nội dung này sẽ bị 3 thẻ div con đè lên. Hoặc nếu các bạn dùng dev tool của trình duyệt để kiểm tra, sẽ thấy thuộc tính height của div cha này bằng 0.

Lý do là vì trình duyệt không thể tính được chiều cao của div cha chứa các div mang thuộc tính float, nên các element nằm sau div cha này sẽ bị các div con đó đè lên.

Giải quyết

Để giải quyết vấn đề trên, chúng ta có thể chèn thêm 1 thẻ div nằm ở vị trí cuối cùng, đằng sau các thẻ div float, thẻ div cuối cùng này được gán thuộc tính clear: both, có nhiệm vụ dọn dẹp 2 bên đường, và chui vào nằm ở vị trí dưới cùng, từ đó nó sẽ kéo thẻ div cha về lại đúng chiều cao của nó

ví dụ như sau:

<div class="container">
    <div class="box red"> Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia
    </div>
    <div class="box blue"> 
      Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia
    </div>
    <div class="box green">
      Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia Framgia 
   </div>
  <div class="clear"></div>
</div>

CSS:

.clear {
    clear: both;
}

Kết quả:

Nhưng cách làm này có rất nhiều hạn chế: đó là bạn phải tự thêm vào thẻ div .clear mỗi khi muốn sử dụng float, gây ra nhiều phiền phức và cấu trúc HTML của trang sẽ trở nên không đẹp.

Vì thế, chúng ta sử dụng một element ảo (pseudo element), đó là ::after đặt vào cuối của div cha để mang thuộc tính clear.

.container:after {
    content: "";
    display: block;
    visibility: hidden;
    clear: both;
}

Với đoạn CSS trên, khi trình duyệt hiển thị trang web ra, thì nó sẽ có cấu trúc như dưới:

Đoạn nội dung :after sẽ được chèn vào ở vị trí như trên, và mang thuộc tính clear: both giúp chúng ta dọn dẹp phần cuối của div cha, từ đó trình duyệt có thể tính được chiều cao thực tế của div cha.

Clearfix

Chúng ta thường tạo ra một class tên là clearfix để sử dụng lại pseudo element ::after ở trên cho những lần sau, và đây là nội dung của một class clearfix đơn giản:

.clearfix:after {
    content: ".";
    visibility: hidden;
    display: block; 
    clear: both;
}

Một thẻ luôn luôn phải có nội dung bên trong nó, và nội dung này không được rỗng, hoặc bằng ký tự trắng (space), nếu không nó sẽ không xuất hiện trên trình duyệt, chính vì thế, sau khi tạo ra pseudo element ::after, chúng ta sử dụng thuộc tính content: "." để gán nội dung bên trong nó là một dấu chấm.

Tuy nhiên, dấu chấm này không nên xuất hiện trên màn hình, chính vì thế chúng ta tạm ẩn nó đi bằng thuộc tính visibility: hidden, thuộc tính này giúp ẩn một element đi mà không làm nó biến mất.

Cuối cùng là đặt thuộc tính clear: both để làm cho nó nằm tách ra khỏi dòng nội dung đang chứa các div con.

Hy vọng bài viết sẽ hữu ích với bạn, cảm ơn bạn đã theo dõi !!

0