Bài tập

Xây dựng giao diện trang Đăng nhập Netflix

Huy Erick

Chào các bạn, Tiếp theo bài viết về HTML & CSS cơ bản: Bài 1 - Tìm hiểu về HTML và CSS, chúng ta sẽ đến với phần thực hành áp dụng những kiến thức...

Chào các bạn,

Tiếp theo bài viết về HTML & CSS cơ bản: Bài 1 - Tìm hiểu về HTML và CSS, chúng ta sẽ đến với phần thực hành áp dụng những kiến thức đã tìm hiểu về HTML & CSS.

Trong bài này mình sẽ chia sẻ cách xây dựng giao diện trang Đăng nhập Netflix

1. Yêu cầu kiến thức và các tool

Để làm được layout Đăng nhập Netflix, các bạn cần nắm vững các kiến thức sau:

  • Các thẻ HTML, CSS cơ bản
  • Position CSS
  • Flexbox CSS - Một trong những cách giúp căn chỉnh phân chia không gian và vị trí của các phần tử trong một vùng chứa (container) một cách hiệu quả và dễ dàng.

Trong bài này, mình sẽ sử dụng các công cụ sau:

  • Visual Studio Code
  • Tiện ích ColorZilla extension để lấy mã màu trên website: ColorZilla
  • Tiện ích Page Ruler Redux để đo kích thước các thành phần trên website: Page Ruler Redux

2. Phân tích layout

Trước khi bắt tay vào xây dựng giao diện website, ta cần phân tích layout. Khi làm việc thực tế, front-end developer thường nhận file layout từ designer, sau đó phân tích layout và bắt đầu code HTML & CSS.

Để phân tích layout, ta cần xem xét bố cục của layout, bao gồm các phần như header, content, footer, slider, navbar, và xác định các điểm đặc biệt của layout.

Phân tích layout trang Đăng nhập của Netflix, ta có layout gồm 3 phần chính:

  • Header chứa logo chữ "Netflix" in đậm ở góc trái.
  • Content gồm một popup chứa form đăng nhập và các thông tin liên quan.
  • Cuối cùng là footer.

Layout này thuộc kiểu modal CSS, bao gồm một hình nền và một lớp phủ màu đen, cùng với popup form đăng nhập nổi lên trên để nhập thông tin.

3. Xây dựng giao diện Đăng nhập Netflix

Để bắt đầu, ta tạo một file index.html và style.css, sau đó liên kết file style.css vào file index.html:

<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Netflix</title>
</head>
<body>
</body>
</html>

Tiếp theo, ta tạo một thẻ div với class "login-container" để chứa toàn bộ layout:

<div class="login-container">
</div>

Bên trong thẻ div "login-container", ta tạo các division: lớp phủ mờ (login-overlay), header (login-header), body (login-body), và footer (login-footer) theo code sau:

<div class="login-container">
<div class="login-overlay">
</div>
<div class="login-header">
</div>
<div class="login-body">
<!-- Form Đăng nhập -->
</div>
<div class="login-footer"></div>
</div>

Tiếp theo, ta thêm reset CSS để thiết lập các style của các phần tử HTML theo một chuẩn nhất định.

*{ padding: 0; margin: 0; box-sizing: border-box; }

Giải thích:

  • Padding và margin có giá trị 0 giúp đưa padding và margin của border box CSS cho các phần tử HTML về 0. So sánh khi có và không có reset CSS để thấy rõ sự khác biệt.
  • Box-sizing là thuộc tính CSS3, có giá trị border-box giúp giữ nguyên kích thước (width, height) của phần tử khi ta thêm padding, margin và border cho phần tử HTML. Lúc này, width = content + padding + border. Khuyến khích sử dụng box-sizing: border-box để dễ tính toán kích thước phần tử trên website.

Sau đó, ta tải hình nền trang Đăng nhập của Netflix và thiết lập background-image cho trang Đăng nhập:

.login-container{
background-image: url("./netflix_login_bgr.jpg");
background-size: cover;
height: 1086px;
position: relative;
width: 100%;
}

Giải thích:

  • Background-image: URL của hình nền.
  • Background-size: Cover để hình nền lấp đầy diện tích của phần tử. (Đôi lúc hình sẽ bị cắt bớt ở bên phải hoặc dưới nếu tỉ lệ chiều cao, chiều rộng của hình không phù hợp với phần tử). So sánh hình gốc và hình nền để hiểu rõ.
  • Relative: Định vị trí của phần tử so với vị trí ban đầu. Mặc định là giữ nguyên. Ta có thể điều chỉnh top: 10px, left: 10px để xem thay đổi.

Tiếp theo, ta thêm CSS cho lớp phủ mờ (login-overlay):

.login-overlay{
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}

Absolute: Giá trị này dùng để thiết lập vị trí của một phần tử theo phần tử cha có giá trị thuộc tính position là relative hoặc absolute. Ở đây, phần tử cha là thẻ div với class "login-container". Mặc định giá trị là 0.

Mã màu rgba với giá trị 3 màu (red, green, blue từ 0 - 255) và cuối cùng là độ mờ (opacity) với giá trị từ 0 tới 1.

Tiếp theo, ta thêm HTML cho phần header (login-header). Trong trang Đăng nhập Netflix, phần header sử dụng một file icon SVG. Tuy nhiên, để đơn giản, ta sẽ sử dụng thẻ a thay thế:

<div class="login-container">
<div class="login-header">
<a href="/">Netflix</a>
</div>
<div class="login-body">
<!-- Form Đăng nhập -->
</div>
<div class="login-footer"></div>
</div>

Tiếp theo, ta xây dựng phần login body:

<div class="login-body">
<!-- Form Đăng nhập -->
<div class="login-form-container">
<div class="login-form-header">
<h4>Đăng nhập</h4>
</div>
<div class="login-form">
<!-- Giao diện form -->
</div>

Tiếp theo, ta thêm CSS chung cho HTML:

html{
font-size: 10px;
font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;
}

Tiếp theo, ta thêm CSS cho phần header:

.login-header{
padding-top: 20px;
padding-left: 44px;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}

.login-header a{
font-size: 5rem;
font-weight: 700;
text-decoration: none;
text-transform: uppercase;
color: #E50914;
}

Giải thích:

  • Z-index: giúp sắp xếp các phần tử hiển thị theo thứ tự được thiết lập. Phần tử có giá trị z-index cao sẽ hiển thị trên phần tử có giá trị z-index thấp hơn. Mặc định, các phần tử sẽ hiển thị theo thứ tự mà chúng được khai báo trong HTML. Trong trường hợp của chúng ta, phần tử login-overlay được khai báo trước nên sẽ hiển thị phủ lên trên phần tử login-header và login-body. Nếu ta thay đổi vị trí của các phần tử, chúng sẽ bị chìm xuống phía dưới.
  • Absolute: Giá trị này dùng để thiết lập vị trí của một phần tử theo phần tử cha có giá trị thuộc tính position là relative hoặc absolute. Ở đây, phần tử cha là thẻ div với class "login-container".

Tiếp theo, ta thêm CSS cho phần login body:

.login-body{
width: 448px;
height: 660px;
background-color: rgba(0, 0, 0, 0.75);
position: absolute;
left: 0;
right: 0;
margin: auto;
top: 88px;
border-radius: 5px;
z-index: 1;
}

Giải thích:

  • Màu nền với độ mờ 0.75.
  • Để canh giữa, ta dùng thuộc tính margin: auto.

Tiếp theo, ta thêm CSS cho phần login form container:

.login-form-container{
padding: 60px 70px 0;
}

Có thể viết tắt: padding: 60px 70px 0;

Tiếp theo, ta thêm form input gồm 2 thẻ input text: username và password:

<div class="login-form-container">
<div class="login-form-header">
<h4>Đăng nhập</h4>
</div>
<div class="login-form">
<input type="text" class="login-form-input" placeholder="Email hoặc số điện thoại">
<input type="password" class="login-form-input" placeholder="Mật khẩu">
</div>

Do định dạng của 2 thẻ input giống nhau, ta đặt class chung cho chúng.

Tiếp theo, ta thêm CSS cho thẻ input:

.login-form-input{
width: 100%;
height: 50px;
margin-top: 16px;
padding: 0 16px;
color: #fff;
font-size: 1.6rem;
background-color: #333333;
border: 1px solid #333333;
border-radius: 4px;
outline: none;
}

Tiếp theo, ta thêm CSS để khi click vào input nhập thông tin, thẻ input có viền phía dưới:

.login-form-input:focus{
border-bottom: 3px solid #eeaf67;
}

Chỉnh khoảng cách của thẻ input đầu tiên tới login header:

.login-form-input:first-child{
margin-top: 30px;
}

Lưu ý: Để chỉnh các phần tử tiếp theo, ta có thể sử dụng :nth-child(n).

Thêm button "Đăng nhập":

<button class="login-form-button">Đăng nhập</button>

CSS cho button:

.login-form-button{
color: #fff;
background-color: #e50914;
width: 100%;
font-size: 1.6rem;
padding: 16px;
border-radius: 4px;
border: 0px;
margin: 40px 0 14px;
font-weight: 700;
}

Thêm HTML cho phần checkbox "Ghi nhớ tôi" và link "Cần trợ giúp":

<div class="login-form-help">
<div class="login-form-rememberMe">
<input type="checkbox" class="rememberMe-cbx" id="checkbox_id">
<label class="remember-lbl" for="checkbox_id">Ghi nhớ tôi</label>
</div>
<a class="help-link" href="/">Cần trợ giúp?</a>
</div>

CSS cho phần login form helper:

.login-form-help{
color: #737373;
font-size: 1.3rem;
display: flex;
justify-content: space-between;
}

Giải thích:

  • Justify-content: giúp căn chỉnh các phần tử nằm bên trong theo chiều dọc hoặc chiều ngang. Giá trị này giúp cho các khoảng cách giữa các thành phần luôn bằng nhau. Tuy nhiên, phần tử đầu luôn nằm sát trái, phần tử cuối luôn nằm sát phải. Tham khảo: A Complete Guide to Flexbox

Thêm CSS cho checkbox:

.rememberMe-cbx{
height: 16px;
width: 16px;
border-radius: 2px;
accent-color: #737373;
}

.remember-lbl{
position: relative;
bottom: 3px;
}

Để click vào label chọn checkbox, ta dùng id:

<div class="login-form-rememberMe">
<input type="checkbox" class="rememberMe-cbx" id="checkbox_id">
<label class="remember-lbl" for="checkbox_id">Ghi nhớ tôi</label>
</div>

Để tạo nhiều định dạng hơn cho checkbox, ta cần viết CSS để tạo kiểu checkbox tùy chỉnh.

Thêm vào phần "Đăng nhập bằng Facebook":

<a href="/" class="login-fb">
<img class="login-fb-icon" src="https://nanado.edu.vn/uploads/images/blog/admin/2024/02/16/html-cssxay-dung-giao-dien-trang-login-netflix-1708054926.webp" alt="">
<span class="login-fb-text">Đăng nhập bằng Facebook</span>
</a>

CSS cho phần Đăng nhập bằng Facebook:

.login-form-other{
margin-top: 60px;
}

.login-fb{
text-decoration: none;
}

.login-fb-icon{
height: 20px;
width: 20px;
margin-right: 10px;
}

.login-fb-text{
font-size: 1.3rem;
color: #737373;
font-weight: 500;
position: relative;
bottom: 6px;
}

4. Tổng kết

Vậy là chúng ta đã cùng nhau xây dựng thành công giao diện trang Đăng nhập Netflix.

Toàn bộ source code mọi người tham khảo:

HTML:

<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Netflix</title>
</head>
<body>
<div class="login-container">
<div class="login-header">
<a href="/">Netflix</a>
</div>
<div class="login-body">
<!-- Form Đăng nhập -->
<div class="login-form-container">
<div class="login-form-header">
<h4>Đăng nhập</h4>
</div>
<div class="login-form">
<input type="text" class="login-form-input" placeholder="Email hoặc số điện thoại">
<input type="password" class="login-form-input" placeholder="Mật khẩu">
<button class="login-form-button">Đăng nhập</button>
<div class="login-form-help">
<div class="login-form-rememberMe">
<input type="checkbox" class="rememberMe-cbx" id="checkbox_id">
<label class="remember-lbl" for="checkbox_id">Ghi nhớ tôi</label>
</div>
<a class="help-link" href="/">Cần trợ giúp?</a>
</div>
</div>
<div class="login-form-other">
<a href="/" class="login-fb">
<img class="login-fb-icon" src="https://nanado.edu.vn/uploads/images/blog/admin/2024/02/16/html-cssxay-dung-giao-dien-trang-login-netflix-1708054926.webp" alt="">
<span class="login-fb-text">Đăng nhập bằng Facebook</span>
</a>
<div class="login-form-signupnow">
Bạn chưa có tài khoản? <a href="/" class="login-form-signupnow-link">Đăng ký ngay.</a>
</div>
<div class="login-term">
<p>Trang này được bảo vệ bởi Google reCAPTCHA để đảm bảo bạn không phải là robot.</p>
<a href="">Tìm hiểu thêm.</a>
</div>
</div>
</div>
</div>
<div class="login-overlay">
</div>
<div class="login-footer">
</div>
</div>
</body>
</html>

CSS:

*{ padding: 0; margin: 0; box-sizing: border-box; }

html{
font-size: 10px;
font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;
}

.login-container{
background-image: url("./netflix_login_bgr.jpg");
background-size: cover;
height: 1086px;
position: relative;
width: 100%;
}

.login-overlay{
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}

.login-header{
padding-top: 20px;
padding-left: 44px;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}

.login-header a{
font-size: 5rem;
font-weight: 700;
text-decoration: none;
text-transform: uppercase;
color: #E50914;
}

.login-body{
width: 448px;
height: 660px;
background-color: rgba(0,0,0,0.75);
position: absolute;
left: 0;
right: 0;
margin: auto;
top: 88px;
border-radius: 5px;
z-index: 1;
}

.login-form-container{
padding: 60px 70px 0;
}

.login-form-input{
width: 100%;
height: 50px;
margin-top: 16px;
padding: 0 16px;
color: #fff;
font-size: 1.6rem;
background-color: #333333;
border: 1px solid #333333;
border-radius: 4px;
outline: none;
}

.login-form-input:focus{
border-bottom: 3px solid #eeaf67;
}

.login-form-input:first-child{
margin-top: 30px;
}

.login-form-button{
color: #fff;
background-color: #e50914;
width: 100%;
font-size: 1.6rem;
padding:16px;
border-radius: 4px;
border: 0px;
margin: 40px 0 14px;
font-weight: 700;
}

.login-form-help{
color: #737373;
font-size: 1.3rem;
display: flex;
justify-content: space-between;
}

.rememberMe-cbx{
height: 16px;
width: 16px;
border-radius: 2px;
accent-color:#737373;
}

.remember-lbl{
position: relative;
bottom: 3px;
}

.login-form-other{
margin-top: 60px;
}

.login-fb{
text-decoration: none;
}

.login-fb-icon{
height: 20px;
width: 20px;
margin-right: 10px;
}

.login-fb-text{
font-size: 1.3rem;
color: #737373;
font-weight: 500;
position: relative;
bottom: 6px;
}

.login-form-signupnow{
font-size: 16px;
color: #737373;
margin-top: 16px;
}

.login-form-signupnow-link{
color: #fff;
text-decoration: none;
}

.login-term{
color: #737373;
font-size: 1.3rem;
margin-top: 16px;
color: #737373;
}

.login-term p{
display: inline;
}

.login-term a{
color: #0071eb;
text-decoration: none;
}

.login-term a:hover{
text-decoration: underline;
}

.login-footer{
width: 100%;
background-color: rgba(0,0,0,0.75);
height: 220px;
position: absolute;
left: 0;
bottom: 0;
padding: 30px 0;
}

Đó là toàn bộ hướng dẫn để xây dựng giao diện trang Đăng nhập Netflix. Hy vọng rằng bài viết này sẽ giúp ích cho bạn trong việc áp dụng kiến thức về HTML và CSS.

Nguồn tham khảo:

1