Nội dung bài viết
Helloooo các bạn. Tiếp nối phần 2 của series CSS Grid thì hôm nay chúng ta sẽ tìm hiểu nốt những thuộc tính, giá trị và các hàm còn lại khác của CSS Grid cũng như cách sử dụng hiệu quả khi làm.
Đặc biệt thì mình sẽ có một Project nho nhỏ là grid gallery làm bằng CSS Grid và áp dụng những thứ chúng ta đã học qua series css grid này luôn.
# grid-auto-flow: dense
Ở bài trước mình có nói qua thuộc tính này kèm theo đó là hai giá trị row
và column
. Tuy nhiên còn một giá trị khác nữa đó là dense
. Giá trị này sẽ làm cho các phần tử tự động fill vào các chỗ trống trong grid một cách hợp lý sao cho không bị dư khoảng trống.
Giá trị này sẽ làm cho các phần tử sắp xếp không còn theo thứ tự nữa miễn sao nó cố gắng fill đầy khoảng trống trong container mà thôi. Các bạn có thể tham khảo Codepen(codepen mình tham khảo) dưới đây là sẽ hiểu thôi nè
See the Pen GRID-auto-flow DENSE by Gabi (@enxaneta) on CodePen.
# auto-fit vs auto-fill
Hai giá trị thường được sử dụng trong hàm repeat()
mà chúng ta đã tìm hiểu ở bài trước đó. Thật tình hai giá trị này mình không biết giải thích sao cho các bạn dễ hiểu được nên mình có tìm một bài trình bày rất chi tiết về hai giá trị này để cho các bạn tham khảo. Các bạn có thể đọc nó tại đây nha.
Để các bạn có thể hình dung và hiểu sự khác biệt giữa chúng nên mình có để thêm phần Codepen dưới đây để các bạn tham khảo nè. Lưu ý là các bạn phải bấm nút “Edit on Codepen” để vào trang Codepen xem cho chính xác và phải co giãn trình duyệt thì mới thấy được sự khác biệt nha.
See the Pen auto-fill vs auto-fit by Sara Soueidan (@SaraSoueidan) on CodePen.
# “simple” project
Đây là phần hot nhất đây. Mình sẽ làm một demo kèm code cho các bạn theo dõi và làm theo luôn cũng như chia sẻ vài tips mà mình hay dùng khi làm cho các bạn. Đây là kết quả sau khi làm xong.
Và điều trước tiên là các bạn phải làm đó là tải code mẫu của mình về ở đây. Sau đó mở lên và bắt đầu theo dõi bài này và code theo nhé. Mình có note trong file style.css
đoạn /* Code follow from here*/
các bạn mở file style.css
và kéo xuống dưới cùng nhé.
= Phân tích design
Kinh nghiệm của mình là tạo ra grid sao cho phù hợp. Mình bắt đầu đo kích thước của design và thấy rằng khoảng cách giữa các phần tử vàpadding
của gallery đều là 15px.
Thì việc đầu tiên mình làm đó là css cho gallerydisplay: grid
đồng thời mình cũng set luôn grid-gap: 1.5rem và padding 1.5rem
Lưu ý do mình set html
font-size
về 62.5% nên lúc này1rem = 10px
. Các bạn có thể tham khảo bài viết về hướng dẫn sử đụng đơn vị em và rem của mình trước đó để hiểu lý do tại sao nhé.
.gallery { background-color: #f9f7f6; padding: 1.5rem; grid-gap: 1.5rem; display: grid; }
Tiếp đến mình nhìn vào tấm hình nhỏ nhất trong design. Mình có đánh dấu ô màu xanh trong hình dưới đây và mình thấy rằng kích thước của nó là 145x70(px)
. Và khung gallery là 1270px
sau khi trừ đi padding 2 bên(30px) và các grid-gap
(line màu đỏ) giữa các phần tử là 4×15(60) thì khung gallery còn 1270 - 30 - 60 = 1180px.
= Tạo lưới(grid) cơ bản
Sau khi đã có chiều rộng và độ cao của phần tử nhỏ nhất 145x70
và chiều rộng của gallery là 1180px
. Giờ là bước tạo lưới chỗ này quan trọng nè các bạn nhớ làm theo nha.
Xin lưu ý đây là cách làm của mình và mình chia sẻ cho các bạn. Nếu các bạn thấy không đúng hoặc có cách khác hay hơn thì góp ý giúp mình nha.
Mình sẽ lấy độ rộng của gallery là 1180 chia cho độ rộng của phần tử nhỏ nhất rồi làm tròn xuống ta được 1180/145 = 8
. Từ đó ta tạo ra được 8 cột và mình sẽ cho các cột này đều bằng nhau vì thế code của mình lúc này sẽ có grid-template-columns: repeat(8, 1fr)
.gallery { background-color: #f9f7f6; padding: 1.5rem; grid-gap: 1.5rem; display: grid; grid-template-columns: repeat(8, 1fr); }
Còn về grid-template-rows
thì mình cũng tính tương tự cho chiều cao của gallery sau khi trừ padding
và các grid-gap
ta được 540px. Ta lấy 540 chia cho chiều cao của phần tử nhỏ nhất là 70 và làm tròn xuống ta được 540/70 = 7
. Từ đó sẽ có 7 hàng(row) ứng với chiều cao của phần tử nhỏ nhất là 70px(7rem)
.gallery { background-color: #f9f7f6; padding: 1.5rem; grid-gap: 1.5rem; display: grid; grid-template-columns: repeat(8, 1fr); grid-template-rows: repeat(7, 7rem); }
Các bạn nhớ dùng Firefox rồi F12 lên chọn vào thẻ gallery rồi click vào cái thuộc tính display: grid
mà mình có gạch chân màu đen dưới đây khi check code css nhá.
Sau khi click vào đó các bạn nhìn vào kết quả sẽ trông như thế này
= Căn chỉnh vị trí cho các phần tử
Bây giờ là bước sắp xếp vị trí cho các phần tử đúng nơi mà nó hiển thị. Các bạn nhớ làm bước trên để thấy các track line nhé. Vì nó rất quan trọng trong việc thiết lập vị trí cho các phần tử đó.
Đây là hình mà mình đã minh họa và phân tích ra cho các bạn tiện theo dõi và hình dung. Design này bao gồm tất cả là 14 hình.
Các số màu đỏ là vị trí tương ứng cho các hình, số màu đen là các track line để chúng ta xác định vị trí cột và hàng cho phần tử và màu xanh là tương ứng số cột và số hàng của phần tử đó chứa.
Các bạn nhớ tải hình này về để tiện theo dõi hơn chứ vừa đọc code vừa kéo chuột lên mất thời gian lắm đó. Giờ thì bắt đầu từng tấm một nhé. Trong source code mẫu thì đã có html css đặt tên đúng chuẩn rồi nhé.
Đừng quên rằng track line mình đã nói rõ cho các bạn ở phần trước rồi nhé các bạn nhớ theo dõi thì mới hiểu, cột thì track line theo chiều ngang còn hàng thì track line theo chiều dọc.
Tấm số 1 : Dựa vào hình ta thấy nó chiếm 2 cột và 2 hàng. Cột thì bắt đầu từ track line số 1 tới track line số 3 còn hàng thì từ track line số 1 tới track line số 3 luôn. Suy ra ta có
.gallery__item--1 { grid-column: 1 / 3; grid-row: 1 / 3; }
Tấm số 2 : Dễ dàng ta thấy theo cột thì nó bắt đầu từ line số 3 tới line số 6 và hàng thì bắt đầu từ line số 1 tới line số 4 nên ta có
.gallery__item--2 { grid-column: 3 / 6; grid-row: 1 / 4; }
Tấm số 3 : Quá đơn giản cột từ line 6 – 7 còn hàng thì line 1 – 3 nên ez
.gallery__item--3 { grid-column: 6 / 7; grid-row: 1 / 3; }
Tấm số 4 : Cột thì từ line 7 – 9 và hàng thì giống tấm số 3 từ line 1 – 3
.gallery__item--4 { grid-column: 7 / 9; grid-row: 1 / 3; }
Tấm số 5 : Cột từ line 1 – 3 và hàng thì từ line 3 tới line 6
.gallery__item--5 { grid-column: 1 / 3; grid-row: 3 / 6; }
Tấm số 6 : Ta lại thấy cột thì bắt đầu từ line số 3 – 5 và hàng thì từ line số 4 tới line số 6 nên ta cũng có
.gallery__item--6 { grid-column: 3 / 5; grid-row: 4 / 6; }
Tấm số 7 : Tiếp tục phân tích lại thấy theo cột thì nó nằm từ line số 5 – 6 và hàng thì từ line 4 -5
.gallery__item--7 { grid-column: 5 / 6; grid-row: 4 / 5; }
Tấm số 8 : Ez ta lại thấy nó nằm ở cột từ line số 6 – 8 và hàng thì từ line 3 – 5
.gallery__item--8 { grid-column: 6 / 8; grid-row: 3 / 5; }
Tấm số 9 : Sắp xong rồi cố lên. Cột nằm từ line số 8 đến line số 9 còn hàng thì từ line 3 – 6.
.gallery__item--9 { grid-column: 8 / 9; grid-row: 3 / 6; }
Tấm số 10 : Nó nằm đầu tiên thì theo cột tất nhiên là line số 1 tới line số 2 và hàng thì từ line số 6 – 8
.gallery__item--10 { grid-column: 1 / 2; grid-row: 6 / 8; }
Tấm số 11 : Xuất phát từ line số 2 tới line số 4 của cột và hàng cũng tương tự của tấm số 10 đó là 6 – 8
.gallery__item--11 { grid-column: 2 / 4; grid-row: 6 / 8; }
Tấm số 12 : Hàng thì cũng tương tự ở tấm số 11 là từ line 6 – 8 luôn còn cột thì từ line số 4 – 5
.gallery__item--12 { grid-column: 4 / 5; grid-row: 6 / 8; }
Tấm số 13 : Chút xíu nữa thôi. Nhìn kỹ ta thấy theo cột nó bắt đầu từ line 5 – 8 và theo hàng cũng từ line 5 – 8.
.gallery__item--13 { grid-column: 5 / 8; grid-row: 5 / 8; }
Tấm cuối cùng số 14 : oh yeah nó nằm cuối có line cột từ số 8 – 9 và line hàng từ 6 – 8 giống tấm số 12 nè
.gallery__item--14 { grid-column: 8 / 9; grid-row: 6 / 8; }
Phù cuối cùng cũng xong rồi nè anh em ơi. Đây là fullsource code sau khi các bạn làm xong. Nhớ tham khảo và đối chiếu xem đúng không nè.
.gallery { background-color: #f9f7f6; padding: 1.5rem; grid-gap: 1.5rem; display: grid; grid-template-columns: repeat(8, 1fr); grid-template-rows: repeat(7, 7rem); } .gallery__img { width: 100%; height: 100%; object-fit: cover; display: block; } .gallery__item--1 { grid-column: 1 / 3; grid-row: 1 / 3; } .gallery__item--2 { grid-column: 3 / 6; grid-row: 1 / 4; } .gallery__item--3 { grid-column: 6 / 7; grid-row: 1 / 3; } .gallery__item--4 { grid-column: 7 / 9; grid-row: 1 / 3; } .gallery__item--5 { grid-column: 1 / 3; grid-row: 3 / 6; } .gallery__item--6 { grid-column: 3 / 5; grid-row: 4 / 6; } .gallery__item--7 { grid-column: 5 / 6; grid-row: 4 / 5; } .gallery__item--8 { grid-column: 6 / 8; grid-row: 3 / 5; } .gallery__item--9 { grid-column: 8 / 9; grid-row: 3 / 6; } .gallery__item--10 { grid-column: 1 / 2; grid-row: 6 / 8; } .gallery__item--11 { grid-column: 2 / 4; grid-row: 6 / 8; } .gallery__item--12 { grid-column: 4 / 5; grid-row: 6 / 8; } .gallery__item--13 { grid-column: 5 / 8; grid-row: 5 / 8; } .gallery__item--14 { grid-column: 8 / 9; grid-row: 6 / 8; }
Sau khi làm xong mà kết quả của các bạn ra giống như với tấm hình ban đầu thì chúc mừng bạn đã thành công mỹ mãn còn không thì chắc các bạn sai chỗ nào đó rồi đó. Cố gắng lên nhé.
# Lời kết
Hix. Cuối cùng cũng xong cái series CSS Grid hại não này. Mệt quá luôn nà. Hi vọng với những kiến thức ít ỏi của mình sẽ giúp các bạn phần nào trong việc học và chinh phục kiến thức để một ngày càng giỏi hơn nhé. Chúc các bạn một ngày tốt lành và đừng quên comment giúp mình có động lực để viết bài tiếp nhé..
Mình học thấy rối mù mà bạn làm nhìn đơn giản ghê hix. Cám ơn bạn nhiều nhé nhờ series của bạn mà mình hiểu thêm được khá nhiều. chúc blog bạn ngày càng phát triển nha
“Và khung gallery là 1270px sau khi trừ đi padding 2 bên(30px) và các grid-gap(line màu đỏ) giữa các phần tử là 4×15(60) thì khung gallery còn 1270 – 30 – 60 = 1180px”
Đoạn này mình chưa hiểu chỗ 4 grid-gap . Tại sao lại là 4 line, rất mong bạn giải đáp cho mình ạ 🙁
Cái này là dựa vào Design nha bạn. Chứ không phải mình đề ra nhé. Nghĩa là theo design nó rộng 1270px có padding left và right là 15px. Và grid-gap là 15px. Thì theo design ta thấy có 4 khoảng trống đó nên là 4×15 đó hi
Cảm ơn bạn rất nhiều, mình đã hiểu rồi ạ!
keke
grid gap thì mỗi mình thì nó căn ra thôi chứ 4 line gì hả bạn
Ý bạn là nó tự động chứ không cần set ah ???
khoảng cách giữa các item đó ông là 1.5 rem là 15*4=60 – padding 30*2=60
1270px – 120px =1180px
thanks ad nhiều
Cam on na <3
Bài viết rất tỉ mỉ và bổ ích,mong bạn ra nhiều bài hơn
Đang cố gắng nà kêke
Đoạn bạn tính công thức để ra được số cột và số dòng ý hay vãi =)),đây là kinh nghiệm của bạn hay là nếu làm với các layout như ở trên thì mình cứ tính theo công thức như vậy
Ah Mình làm nhiều rồi phân tích ra được thôi á bạn. Chứ không có công thức nào cả kaka
Anh viết bài về dùng Gulp và Webpack đi anh
Sau này có thời gian a sẽ nghiên cứu viết
cám ơn bạn nhiều nhé, rất chi tiết và thiết thực :).
rất hay, em cảm ơn anh nhiều ạ
của em ô lớn gấp rưỡi ô nhỏ thì phải làm sao ạ
tỉ lệ 1.5 nè em, nếu cái kia 1fr thì cái còn lại 1.5fr
hay lam
Cảm ơn những chia sẻ rất chi tiết, rất rõ ràng của bạn <3
Hi vọng có ích cho bạn nhen
Tuyệt vời, a viết bài chất lượng và tận tâm, quá dễ hiểu luôn ạ!