Hướng dẫn cắt PSD sang HTML toàn tập phần cuối

cắt psd sang html phần cuối

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-directioncolumn 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 labelcollapse 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__bgtransform: 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-leftpadding-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.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-directionrow. 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 ^^..

Subscribe
Notify of
guest

14 Comments
Inline Feedbacks
View all comments
Việt Anh
Việt Anh

Cảm ơn anh vì series hữu ích này

Nhaan
Nhaan

bài viết hay quá cảm ơn anh

Vinh
Vinh

Bài viết chi tiết quá. Cảm ơn admin đã chia sẻ!

Dream
Dream

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

Quang Tuyền
Quang Tuyề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”

Trần Dong Thanh
Trần Dong Thanh

Ông làm công ty nào thế

Duy Linh Dang
Duy Linh Dang

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ị

Hiếu
Hiếu
Reply to  evondev

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.