0

Giữ tỉ lệ khung hình với width động bằng CSS

Tầm quan trọng của tỉ lệ hình trên website

Trên một trang web, hình ảnh hầu như chiếm phần trăm đáng kể trong website hiện nay. Và việc xử lý hình ở khâu nhập liệu nội dung cũng rất là phức tạp nếu như web của chúng ta chưa tính toán đến việc xử dụng ratio trong thiết kế lẫn develop.

Ta lấy ví dụ hình ảnh thumbnail của một tin tức và hình ảnh banner cho trang chi tiết tin tức đó.

thumbnail

Thumbnail bài viết

 

feature image

Banner bài viết chi tiết

 

mobile

Và trên di động

Ta có thể nhẩm được tất cả hình bên trên đều có tỉ lệ là 2:1. Vậy tại sao chúng ta phải giữ tỉ lệ cho hầu hết các hình cho một bài viết xuyên suốt từ thumbnail, feature image và kể cả trên điện thoại. Mình tin chắc có vài cá nhân đã ngộ ra được chân lý rồi phải không, ở đây mình cũng khẳng định thêm:

Trong thiết kế:

  • Giữ tỉ lệ hình là một trong những quy tắt bất di bất dịch rồi, không ai muốn web của mình (do chính mình thiết kế) mà khách hàng lại úp một cái hình méo mó, cảm giác lúc đó rất ức chế và bực bội.

Trong lập trình:

  • Một hình ảnh mặc dù view ở những chổ khác nhau, kích thước khác nhau nhưng việc giữ đúng tỉ lệ sẽ giúp cho các coder quản lý resource đỡ vất vả hơn. Hầu hết các bộ CMS hiện nay đều có công cụ resize chứ không phải khách hàng tùy ý up một tấm hình 3000×1500 lên là lôi cái hình đó là làm thumbnail, băng thông gì chịu nổi.

Nhập liệu:

  • Cái này mới là quan trong, người dùng đỡ vất vả hơn khi phải tự design hình cho nhiều chổ khác nhau.

Làm sao để giữ tỉ lệ khung hình với width động

Website bây giờ hầu hết đều có responsive. Width không còn là một con số cứng ngắt, chúng thay đổi linh hoạt với kích thước của viewport. Vậy câu hỏi đặt ra làm sao để height cũng động để giữ tỉ lệ khung hình với width. Tôi tin chắc có nhiều bạn sẽ buộc miệng và trả lời câu hỏi đó “Xời, Javascript làm được hết”.

Đúng JavaScript có thể làm được hết, nhưng đối với tôi, khi nào search không ra cách bằng CSS thì mới dùng JavaScript. JavaScript như một loại phép thuật, nhưng bạn có coi mấy cái film phép thuật, khi mà phù thủy dùng nhiều phép thuật quá họ sẽ già nua đó, đại loại vậy, khi trang web của bạn sử dụng quá nhiều JavaScript thì nó sẽ chậm chạp, biết rằng một đoạn script sẽ chẳng tốn bao nhiêu nhưng nhiều sẽ thấy hậu quả, nên hạn chế được cái nào thì vẫn hay cái đó.

Vậy thì chúng ta sẽ sử dụng CSS để làm chuyện này và mình cũng sử dụng luôn kỹ thuật Cách css tự động resize ảnh nền theo thẻ div mà Webfaver đã làm trước đó.

Demo

Giải thích

Ở đây, mình sử dụng kỹ thuật padding (top/bottom) cho một before (hay after) để đành 1 khoảng trắng, và sau đó dùng div với background-image để lấp vào khoảng trắng đó. Mình dùng những class ratio-1-1 hoặc ratio-5-3 để định nghĩa phần trăm chiều cao (height) / chiều rộng (width), ví dụ: ở ratio-1-1 là tỉ lệ 1:1 tức là chiều cao bằng chiều rộng, tức nhiên sẽ là 100%, còn ở ratio-5-3 thì chiều rộng bằng 5 còn chiều cao là 3 trên tỉ lệ chiều rộng bằng 100% thì theo quy tắt tam suất thì chiều cao sẽ là 100*3/5 = 60%.

Nhưng chắc nhiều người vẫn chưa hiểu tại sao lại chọn padding. Vậy thì chúng ta lại quay về cốt lõi của css thông qua bài này Box model của W3C. Ở đây họ có nhắc tới là:

The percentage is calculated with respect to the width of the generated box’s containing block, even for ‘padding-top’ and ‘padding-bottom’. If the containing block’s width depends on this element, then the resulting layout is undefined in CSS 2.1.

Padding nếu để percent thì nó sẽ được tính dựa trên width của block chứa nó, ngay cả cho padding-top và padding-bottom. Và nếu chiều rộng block chứa nó phụ thuộc vào chiều rộng bên trong thì con số phần trăm này trở nên vô nghĩa.

Thực hiện

HTML

Ở đây mình dùng hệ thống col của Bootstrap để biểu đạt cho sự thay đổi của width của vùng hiển thị nội dung.

CSS

CSS mình phân ra thành những thành phần tái sử dụng .image-box và những class dành để custom tỉ lệ, mình để sẳn những tỉ lệ cơ bản nhất mà các bạn sẽ phải gặp, ví dụ 1:1, 1:2, 2:1, 4:3, 5:3, 16:9.

Chúc các bạn thành công!

 

 

Nguyễn Quốc Tuấn

I don’t know who I am!?

Leave a Reply

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