Nội dung bài viết
Xin chào các bạn đã lâu lắm rồi mình không viết bài mới, tình hình là sắp qua năm mới 2019 rồi mà còn một bài cuối cùng nên hôm nay tranh thủ hoàn thành nó luôn cho các bạn, và ở bài trước chúng ta đã hoàn thành các blocks còn lại của Design và tìm hiểu sơ qua về Responsive.
Thì trong bài hôm nay chúng ta sẽ áp dụng Responsive vào và kết thúc series này luôn. Trước khi đi vào bài viết thì các bạn có thể tải source code mới nhất tại đây về sau đó mở lên xem kết quả hiện tại và sẵn sàng code theo nhé. Chúng ta tiến hành phân tích và làm thôi nào.
# block Header
Theo hình Gif mình đã làm thì khi resize trình duyệt mình thấy ở màn hình nhỏ hơn 768px thì giao diện menu bị lỗi là vì lúc trước mình làm mình dùng flexbox mà quên set thuộc tính flex-wrap
vì mặc định là nowrap
nên các phần tử menu sẽ không rớt xuống mà nằm trên một hàng gây vỡ giao diện.
Vì thế để hiển thị đẹp ở mobile mình sẽ cho các phần tử menu nằm dọc cho nên mình sẽ dùng thuộc tính flex-direction
là column
cho thẻ ul
có class là nav__list
.nav__list { flex-direction: column; }
Chúng ta sẽ được kết quả như hình dưới đây. Tuy nhiên hiển thị như vậy thì không đẹp tẹo nào. Cho nên mình sẽ gom các phần tử trong menu lại vào một cái nút(toggle menu), và khi chúng ta nhấn vào cái nút đó thì menu nó sẽ hiện ra.
Để làm như vậy thì nhiều bạn sẽ nghĩ ngay đến thư viện Javascript nào đó liền, nhưng không. Ở đây chúng ta sẽ làm nó chỉ bằng HTML & CSS mà thôi. Và mình sẽ chỉ cho các bạn ngay đây. Đầu tiên chúng ta cần thêm vài thẻ HTML vào block Header ta được cấu trúc HTML như sau:
Mình có Note ở trong hình cho các bạn đó, các bạn code theo nhé nhưng bỏ cái note đi nó mới hiện được HTML ra nà.
Nó sẽ hiện ra một cái nút có 3 dấu gạch ngang ở thẻ label
có class là btn__collapse
, nhưng chúng ta chỉ muốn nó hiện ở màn hình nhỏ hơn 768px mà thôi vì thế chúng ta sẽ code nó ẩn đi ở màn hình lớn hơn 768px như sau
@media only screen and (min-width: 768px) { .btn__collapse { display: none; } }
Bây giờ chúng ta sẽ vào phần phân tích chính cho cái menu đó với cấu trúc HTML mình đã note ở trên như sau
<label for="collapse" class="btn__collapse"> <i class="fa fa-bars"></i> </label> <input type="checkbox" id="collapse" style="display: none" class="inp__collapse"> <div class="nav__bg"></div>
Mục đích sử dụng label
là khi chúng ta nhấn vào nó nó sẽ trỏ tới cái #id của thẻ input
theo thuộc tính for
của label
. Ở đây thuộc tính for
của label
là collapse nghĩa là khi nhấn vào label
nó sẽ trỏ tới input
có id là collapse mà input
ở đây là checkbox thì nó sẽ checked
Và một thẻ nav__bg
mình dùng thêm để làm background phủ hết toàn trang khi chúng ta nhấn vào cái nút toggle thì menu sẽ xuất hiện và background sẽ nằm dưới. Thế là phân tích xong cấu trúc HTML của toggle menu. Giờ thì chúng ta sẽ CSS cho nó nhé
Toàn bộ những thứ này đều nằm dưới mobile tức là nhỏ hơn 768px
@media only screen and (max-width: 767px) {code here}
Đầu tiên mình thấy cái phần tử menu nằm sát nhau quá với lại mình không còn dùng cái dấu chấm phía sau như ở màn hình Pc nữa cho nên mình sẽ CSS như sau
nav { width: 100%; } .nav__item { margin-top: 1.5rem; margin-bottom: 1.5rem; } .nav__item:after { display: none; }
Đồng thời ở màn hình Pc ở block Header do mình dùng justify-content: center
nên cái nav
nó nằm giữa không full width cho nên mình sẽ code thêm cho thẻ nav
có độ rộng là 100% để tí nữa code hiệu ứng cho cái nút toggle menu và cái menu__list.
Bây giờ mình muốn cái nút nó có hình tròn và nằm góc trên bên phải cố định ở đó luôn cho dù khi scroll trình duyệt vì thế mình sẽ dùng thuộc tính position: fixed
và CSS như sau
.btn__collapse, .nav__bg { position: fixed; top: 1.5rem; right: 1.5rem; width: 5rem; height: 5rem; font-size: 2rem; border-radius: 5rem; text-align: center; line-height: 5rem; background-color: var(--primary); color: white; cursor: pointer; z-index: 10; }
Vì cái nav__bg
cũng nằm chính vị trí của cái nút luôn nên mình gộp CSS chung lại như ở trên. Nhưng mình muốn cái background của nav__bg
màu khác và nó nằm dưới cái nút đó nên mình sẽ set thêm vài thuộc tính CSS riêng cho nó
.nav__bg { background-color: #eee; z-index: 8; transition: transform .25s linear; }
Tạm thời được kết quả như sau:
Giờ mình ẩn cái menu đi (.nav__list
) và khi nhấn vào cái nút ở góc nó mới hiện ra thì mình sẽ code cho .nav__list
và mình muốn nó cũng fixed luôn để khi nhấn ra rồi cho dù scroll thì vẫn thấy nó. Mình code như sau
.nav__list { flex-direction: column; position: fixed; left: 0; width: 100%; z-index: 9; transform: translateX(-100%); transition: transform .25s linear; }
Mình cho width: 100%
rồi sau đó dùng thuộc tính transform: translateX(-100%)
để nó chạy lùi tuốt về bên trái nằm ngoài rìa giao diện và mình dùng z-index: 9 để cho nó nằm trên nav__bg
(z-index: 8) và nó nằm dưới cái nút toggle menu(z-index: 10).
Giờ là lúc quan trọng, chúng ta muốn khi nhấn vào cái nút thì sẽ hiện ra menu và cái background, như mình đã nói ở trên khi nhấn vào label
thì cái input
checkbox có #id tương ứng sẽ checked mình có CSS như sau
.inp__collapse:checked + .nav__bg { transform: scale(80); } .inp__collapse:checked ~ .nav__list { transform: translateX(0) }
Khi cái input:checked
thì mình sẽ cho .nav__bg
có transform: scale(80)
cho nó phủ hết toàn bộ trang web còn cái .nav__list
mình cho transform: translateX(0)
thì nó sẽ chạy ra lại vị trí ban đầu, ta được kết quả như mong đợi. Thế là xong block Header nhé. Chúng ta sẽ tiếp tục đến block Feature
# block Feature
Nhìn vào hình Gif thì ta thấy rằng ở block Feature Header hiển thị ở tất cả màn hình đều đẹp cho nên chúng ta sẽ không cần phải tùy chỉnh CSS gì thêm. Tuy nhiên ở block Feature List thì ở dưới màn hình 1280px thì ta thấy content đã bị thu hẹp lại ở class .feature__item-content-top
do ban đầu chúng ta CSS cho nó padding: 0 7rem.
Cho nên để cho nó hiển thị đẹp ở màn hình nhỏ hơn 1280px mình sẽ giảm padding-left
và padding-right
lại còn 2rem thôi nhé. Ta sẽ được kết quả đẹp như mong đợi
@media only screen and (max-width: 1179px){ .feature__item-content-top { padding-left: 2rem; padding-right: 2rem; } }
Khoan vội mừng, khi xuống màn hình nhỏ hơn 768px tức là ở mobile. Giao diện nó nát bét luôn kaka. Thì chúng ta sẽ phân tích và fix nó ngay sau đây.
Đầu tiên là feature__item
ở Pc chúng ta set cứng chiều cao cho nó là 60rem(600px) nhưng ở mobile chúng ta muốn nó hiển thị hàng dọc chứ hàng ngang không đủ cho nên chúng ta sẽ thay flex-direction
sang column
kèm theo đó là set lại height: auto
ta có
@media only screen and (max-width: 767px){ .feature__item { height: auto; flex-direction: column; } }
Ôi sao nó lại bị như vậy nhỉ, đừng lo lắng, là vì do code ở trên Pc chúng ta đã code cho .feature__item-img
và .feature__item-content
có độ rộng không phải là 100% cho nên nó như vậy là đúng thôi. Vì thế chúng ta phải CSS lại cho chúng thành 100% như sau và đạt được kết quả
@media only screen and (max-width: 767px){ .feature .feature__item > .feature__item-img, .feature .feature__item > .feature__item-content { width: 100%; } }
Nhìn cũng khá là đẹp tuy nhiên content của phần .feature__item-content-top
nó sát quá nên nhìn hơi xấu cho nên mình sẽ thêm một đoạn CSS padding
cho nó trông đẹp hơn. Thế là xong, chúng ta tiếp tục đến block Images Shop nào.
@media only screen and (max-width: 767px){ .feature__item-content-top { padding-top: 2rem; padding-bottom: 2rem; } }
# block Images Shop
Ở block này thì mọi màn hình đều oke nhưng ở màn hình nhỏ hơn 768px thì lại hiển thị không đẹp cho lắm. Cho nên chúng ta sẽ lại tiếp tục phân tích và fix nó thôi keke.
Cũng giống như .feature__item
block này ở Pc chúng ta set CSS cho .images
có chiều cao cố định 53.5rem(535px) và flex-direction
là row
. Nhưng ở màn hình này chúng ta muốn cho nó hiển thị dạng cột và có chiều cao tự động cho nên mình sẽ CSS cho .images
như sau và được kết quả
@media only screen and (max-width: 767px){ .images { height: auto; flex-direction: column; } }
Vẫn chưa đẹp nhỉ, đời không như là mơ. Chúng ta tiếp tục fix tiếp. Vì images__block
ở Pc chúng ta set width: 33.33%
nên nó chỉ chiếm 1/3 là đúng rồi nhưng ở mobile chúng ta muốn nó rộng ra nên đơn giản chúng ta set lại width: 100%
là oke
@media only screen and (max-width: 767px){ .images__block { width: 100% } .images__item { height: auto; } }
Một điểm nữa đó là images__item
ở Pc chúng ta set cho nó height: 100%
vì chúng ta set block images chiều cao cố định. Tuy nhiên ở mobile thì block images chúng ta không set cố định mà là auto và vì một vài trường hợp hình ảnh không bằng nhau nên hiển thị không như mong muốn nên chúng ta sẽ dùng auto thay vì 100%
Lưu ý: Còn block Tweet, Discover và Mail thì ở tất cả màn hình đều hiển thị đẹp và không bị lỗi gì cho nên mình sẽ không phân tích nhé.
# Kết thúc
Như vậy là đã xong một chặng đường dài ơi là dài. Chúng ta đã đi từ lúc bắt đầu phân tích Design cho đến khi ra kết quả cuối cùng trong bài ngày hôm nay. Cám ơn các bạn rất là nhiều. Hi vọng với chút kiến thức chia sẻ ít ỏi của mình sẽ giúp các bạn phần nào trong việc học và luyện tập cắt PSD nhé.
Và đừng quên xem kết quả online cuối cùng tại đây và tải source code mới nhất tại đây về tham khảo nhé. Chúc các bạn học tập thật tốt và một ngày tốt lành. Đừng quên theo dõi blog mình để đón đọc những siêu phẩm sẽ ra trong năm 2019 sắp tới ^^..
Cảm ơn anh vì series hữu ích này
Cám ơn em vì đã theo dõi series này keke
bài viết hay quá cảm ơn anh
Bài viết chi tiết quá. Cảm ơn admin đã chia sẻ!
Mình có thắc mắc là cái khoản cách chữ trong photoshop nó khác ở browser quá, ở photoshop căn rule đúng rồi mà ở trình duyệt nó dư một vài px, thế là căn lề gì cũng trật hết. Bạn có thể giải đáp cho mình không
Bạn chỉ cần làm đúng 80 – 90% là quá ngon rồi ko cần phải chính xác từng li từng tí làm gì cho mất thời gian nè
Em chào anh ạ! Em đang học Css Grid và áp dụng luôn vào product này, anh có thể ghé thăm qua và nhận xét “cách đặt tên class, cách viết code,…” của em được không ạ? Em cảm ơn anh rất nhiều ạ! File Drive “https://drive.google.com/open?id=1FMGDZsA8RbAO3jfTMd9siRYK4QWps7v7”
Nếu em có product thì em nên đăng lên Codepen.io thì a mới xem được hoặc Github chứ Drive a ko có thời gian để tải về và xem đâu em ơi.
Ông làm công ty nào thế
Bí mật :3
e responsive theo a mà kéo xuống màn hình nhỏ hơn 400 là n bị thừa 1 khoảng trắng ở bên phải
ko biết là do đâu a nhỉ
e xem code a làm thì cũng bị
A check rồi bình thường nè em
chắc ý bạn ấy là như cái hình cuối cùng của cái gif đầu tiên trong bài đó anh (cái phần vỡ giao diện ở block header ấy ạ), em cũng có chung thắc mắc.
Bạn này a rep lâu rồi, bạn kéo xuống màn hình 315, mà thiết bị giờ ít nhất cũng 320 nên trống thôi em