Tạo Slide ảnh bằng Javascript

Trong bài này, chúng ta sẽ cùng xây dựng một slide ảnh đơn giản sử dụng HTML và CSS. Bài viết này là một phần của bài CSS số 15 trong Series Tự Học Lập Trình Web Một Cách Thật Tự Nhiên mà mình đang thực hiện.

Trước khi bắt đầu, hãy để mình giả định là bạn đến từ series bài viết về CSS mà mình đang thực hiện. Và như vậy thì tính tới thời điểm hiện tại, chúng ta vẫn chưa biết gì nhiều về JavaScript, mặc dù Series bài viết về JavaScript của chúng ta đã bắt đầu sau khi giới thiệu xong Bootstrap, và đang được thực hiện song song với việc hoàn thiện kiến thức cơ bản về CSS ở đây.

Việc xây dựng một slide ảnh không sử dụng JavaScript sẽ có một số hạn chế về lựa chọn phương thức xử lý chức năng chuyển ảnh và cấu trúc HTML. Tuy nhiên điều này không đồng nghĩa với việc chúng ta sẽ khó xây dựng slide ảnh hơn mà chỉ đơn giản là chúng ta sẽ có những ràng buộc nhất định trong cấu trúc HTML và có phần ảnh hưởng tới việc canh chỉnh, dàn vị trí các thành phần.

Và đây là kết quả mà chúng ta dự kiến

Bắt tay vào việc thôi

Vẫn như thường lệ thì chúng ta khởi đầu với những công việc chuẩn bị quan trọng để kết quả hiển thị được đồng nhất ở các trình duyệt web khác nhau. Reset CSS và thiết lập một

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
2 giả định là một nơi nào đó trong trang web bất kỳ mà chúng ta sẽ đặt
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
3 vào.

doctype html>
<html lang="en">
<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">

   <title>Simple Carouseltitle>

   <link rel="stylesheet" href="carousel.css">  
head>
<body>
   <div class="container">
      
   div>
body>
html>
/* Reset CSS + Container */

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

.container {
   max-width: 720px;
   margin: 0 auto;
   padding: 30px 15px;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Carousel
 */
 
 /* bắt đầu viết code cho carousel tại đây */

Đầu tiên thì từ kết quả dự kiến chúng ta thấy là một

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
3 cơ bản gồm có 3 thành phần chính:

  1. Các tấm ảnh để hiển thị chuyển đổi qua lại.
  2. Các radio-button định vị số thứ tự của tấm ảnh đang được hiển thị. Đối với người dùng máy tính thì các radio-button này cũng được sử dụng làm các nút chuyển ảnh luôn.
  3. Các nút chuyển slide trái/phải để di chuyển trong danh sách các ảnh. Người dùng thiết bị di động với màn hình nhỏ rất cần 2 nút nhấn này.

1. Tạo khung hiển thị và các ảnh

Chúng ta sẽ cố gắng duy trì cấu trúc HTML đơn giản nhất có thể và bổ sung từng thành phần khi cần tới. Ở đây chúng ta sẽ xuất phát với một

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
5 làm khung ảnh có tên class là
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
6.

<div class="carousel">
   
div>

Lúc này công việc cần làm trong code CSS là chúng ta cần định dạng khung ảnh để chắc chắn trong mọi trường hợp ảnh sẽ được hiển thị tốt nhất có thể. Trong ví dụ này chúng ta giả định là đang trình bày các tấm ảnh nền cho người dùng máy tính tải về với tỉ lệ màn hình thông dụng là 16:9, tức là các ảnh cần hiển thị có kích thước chiều cao ~56% so với chiều rộng. Như vậy chúng ta cần cố định tỉ lệ của khung ảnh

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
6 với tỉ lệ này trong trường hợp không có ảnh đăng tải hoặc do kết nối internet chậm.

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}

Mặc định thì CSS không hỗ trợ chúng ta tạo ràng buộc giữa thuộc tính

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
8 và
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
9. Ví dụ chúng ta đặt
<div class="carousel">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
0 thì lúc này giá trị của
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
9 sẽ được tính theo
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
9 của container cha ở bên ngoài
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
6. Tuy nhiên
<div class="carousel">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
4 là trường hợp đặc biệt. Khi chúng ta thiết lập
<div class="carousel">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
4 với một trị giá
<div class="carousel">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
6 thì kết quả sẽ được tính toán dựa trên
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
8 của container cha ở bên ngoài.

Lúc này thì chúng ta đã có được một khung ảnh màu nền xám nhạt để hiển thị trạng thái không có ảnh

<div class="carousel">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
8 ở vị trí mà
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
3 này được đặt trên trang web.

Tạo Slide ảnh bằng Javascript

2. Các radio-button định vị

Tại sao lại sử dụng các

/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
2 mà không phải là một lựa chọn nào đó khác?

Như đã nói trước đó thì chúng ta vẫn chưa biết gì nhiều về JavaScript nên tác vụ chuyển ảnh đang được hiển thị cần phải được thực hiện bằng một thành phần nào đó có sẵn khả năng tương tác với người dùng, tức là nhận click chuột và đáp ứng lại. Lần trước khi xây dựng thanh điều hướng

/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
3 thì chúng ta đã sử dụng một
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
4 để làm chức năng tương tác với người dùng thiết bị di động màn hình nhỏ; Và mô phỏng tín hiệu thanh điều hướng đang ở trạng thái thu gọn hay trạng thái đầy đủ. Tác vụ mà chúng ta đang xử lý cho
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
3 ở đây cũng khá giống như vậy.

Tuy nhiên điểm khác biệt ở đây là ở mỗi thời điểm thì chúng ta sẽ chỉ có duy nhất một tấm ảnh được đánh dấu là đang hiển thị và khi người dùng click chọn ảnh khác thì tấm ảnh hiện tại phải được tự động bỏ đánh dấu. Và vì vậy nên

/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
4 không phải là lựa chọn phù hợp nhưng các
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
2 thì lại thật hoàn hảo cho tác vụ này.

<div class="carousel">
   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">

   <input class="carousel-indicator" type="radio" name="indicator" checked>
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>

Lúc này khi người dùng click chuột vào một

/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
8 bất kỳ thì chúng ta cần chắc chắn rằng phần tử
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
9 tương ứng đang được hiển thị và các phần tử
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
9 còn lại cần phải được ẩn đi. Để chọn được
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
9 cần hiển thị thì chúng ta chỉ cần kết hợp bộ chọn giống như trường hợp sử dụng
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
4 thôi. Cứ chọn cái
<div class="carousel">
   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">

   <input class="carousel-indicator" type="radio" name="indicator" checked>
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
3 nào đang được
<div class="carousel">
   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">

   <input class="carousel-indicator" type="radio" name="indicator" checked>
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
4 rồi trỏ tới
<div class="carousel">
   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">

   <input class="carousel-indicator" type="radio" name="indicator" checked>
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
5 đứng ngay bên cạnh bằng dấu
<div class="carousel">
   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">

   <input class="carousel-indicator" type="radio" name="indicator" checked>
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
6.

.carousel-indicator:checked + .carousel-image

Tuy nhiên để chọn tất cả những phần tử còn lại thì chúng ta không thể chọn trực tiếp bằng cách kết hợp các bộ chọn như vậy. Lúc này chúng ta có thể nghĩ tới giải pháp phần bù. Tức là cứ chọn hết tất cả các ảnh bằng

/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
9 và cho ẩn đi trước, rồi sau đó chọn ảnh hiện tại bằng bộ chọn ở trên và ghi đè lại thuộc tính
<div class="carousel">
   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">

   <input class="carousel-indicator" type="radio" name="indicator" checked>
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
8 để hiển thị.

/* Indicators */

.carousel-image {
   display: none;
}

.carousel-indicator:checked + .carousel-image {
   display: inline-block;
}

Tới đây thì về cơ bản

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
3 của chúng ta đã có thể hoạt động được rồi và bạn có thể thử click chuột vào các
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
2 để chuyển đổi qua lại giữa các ảnh. Tuy nhiên thì chúng ta vừa mới học xong cái thuộc tính
.carousel-indicator:checked + .carousel-image
1 nên mới quyết định mầy mò làm cái
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
3 này nên phải cố gắng suy nghĩ thêm một chút nữa về hiệu ứng chuyển ảnh. Nếu như là để đơn giản và dễ theo dõi nhất vị trí tương quan giữa các ảnh thì chắc chắn là hiệu ứng di chuyển các ảnh theo phương ngang. Vậy chúng ta chọn hiệu ứng này để triển khai đi.
Tạo Slide ảnh bằng Javascript

Khi người dùng chọn chuyển tới tấm ảnh tiếp theo ở phía bên phải trong dãy

/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
2 (đứng sau ảnh hiện tại trong code HTML) thì ảnh hiện tại sẽ di chuyển về phía bên trái và đi ra khỏi khung ảnh. Và ảnh mới được chọn sẽ di chuyển từ phía bên phải vào khung ảnh. Như vậy chúng ta sẽ có 3 trạng thái của các tấm ảnh được chọn trong code CSS:

  1. Các ảnh
    .carousel-indicator:checked + .carousel-image
    
    4 ảnh được đánh dấu sẽ ở vị trí bên trái khung hiển thị ảnh.
  2. Các ảnh
    .carousel-indicator:checked + .carousel-image
    
    5 ảnh được đánh dấu sẽ ở vị trí bên phải khung hiển thị ảnh.
  3. Ảnh đang được đánh dấu sẽ được hiển thị trong khung ảnh.

Lúc này trong code HTML chúng ta đang để tất cả các

<div class="carousel">
   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">

   <input class="carousel-indicator" type="radio" name="indicator" checked>
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
3 và
<div class="carousel">
   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">

   <input class="carousel-indicator" type="radio" name="indicator" checked>
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
5 đều là phần tử con của
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
6. Do đó từ
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
8 đang được đánh dấu, chúng ta có thể chọn tới các
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
9 đứng sau bằng cách sử dụng
/* Indicators */

.carousel-image {
   display: none;
}

.carousel-indicator:checked + .carousel-image {
   display: inline-block;
}
1 để kết hợp bộ chọn. Việc cần làm là di chuyển hết các ảnh này sang phía bên phải khung hiển thị ảnh bằng thuộc tính
/* Indicators */

.carousel-image {
   display: none;
}

.carousel-indicator:checked + .carousel-image {
   display: inline-block;
}
2 và sau đó chọn ảnh đang được đánh dấu để ghi đè lại vị trí trùng với khung hiển thị. Vẫn là cách xử lý phần bù như chúng ta đã làm ở phía trên thôi.
Tạo Slide ảnh bằng Javascript

Như vậy là chúng ta đã có được 2 trạng thái ảnh trong số 3 trạng thái ở trên. Chỉ còn lại trạng thái đầu tiên tức là các ảnh đứng trước ảnh được đánh dấu cần được di chuyển về phía bên trái khung ảnh. Nhóm này lại là phần bù của 2 nhóm đã xử lý trước đó nên chúng ta có thể xem là trạng thái mặc định của tất cả các

/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
9.

/* Indicators */

.carousel {
   overflow-x: hidden;
}

.carousel-image {
   transition: all 0.9s;
   left: -100%;
}

.carousel-indicator:checked ~ .carousel-image {
   left: 100%;
}

.carousel-indicator:checked + .carousel-image {
   left: 0;
}

Tạo Slide ảnh bằng Javascript

Ở đây bạn lưu ý là việc di chuyển các nhóm ảnh chỉ nên thực hiện bằng 1 thuộc tính

/* Indicators */

.carousel-image {
   display: none;
}

.carousel-indicator:checked + .carousel-image {
   display: inline-block;
}
2 hoặc
/* Indicators */

.carousel-image {
   display: none;
}

.carousel-indicator:checked + .carousel-image {
   display: inline-block;
}
5 chứ không nên sử dụng lẫn cả 2. Tức là hoặc canh chỉnh vị trí theo cạnh bên trái của
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
6 hoặc canh chỉnh theo cạnh phải. Tới đây chúng ta có thể xóa bớt 1 dòng
/* Indicators */

.carousel-image {
   display: none;
}

.carousel-indicator:checked + .carousel-image {
   display: inline-block;
}
2 ở đoạn
/* Indicators */

.carousel-image {
   display: none;
}

.carousel-indicator:checked + .carousel-image {
   display: inline-block;
}
8 mà chúng ta thiết lập khi mới đặt ảnh vào khung. Hoặc nếu bạn cũng dùng
/* Indicators */

.carousel-image {
   display: none;
}

.carousel-indicator:checked + .carousel-image {
   display: inline-block;
}
2 như trong ví dụ của mình thì để lại cũng được.

Việc còn lại là canh chỉnh vị trí cho dãy

/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
2 vào giữa thì chúng ta có thể xử lý như canh chỉnh nội dung văn bản bình thường của
/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
6 bởi vì đây là các thành phần được mặc định
/* Indicators */

.carousel {
   overflow-x: hidden;
}

.carousel-image {
   transition: all 0.9s;
   left: -100%;
}

.carousel-indicator:checked ~ .carousel-image {
   left: 100%;
}

.carousel-indicator:checked + .carousel-image {
   left: 0;
}
2 để dùng lẫn với các thành phần khác khi tạo các biểu mẫu nhập liệu. Mặt khác thì chúng ta không nên sử dụng
/* Indicators */

.carousel {
   overflow-x: hidden;
}

.carousel-image {
   transition: all 0.9s;
   left: -100%;
}

.carousel-indicator:checked ~ .carousel-image {
   left: 100%;
}

.carousel-indicator:checked + .carousel-image {
   left: 0;
}
3 cho các
<div class="carousel">
   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/34O6BZO">

   <input class="carousel-indicator" type="radio" name="indicator" checked>
   <img class="carousel-image" src="https://bit.ly/3ifqrjR">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/3wfhy26">

   <input class="carousel-indicator" type="radio" name="indicator">
   <img class="carousel-image" src="https://bit.ly/363szIQ">
div>
3 bởi vì như vậy sẽ không thể tạo ra dãy nối tiếp nhau được.

/* Reset CSS + Container */

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

.container {
   max-width: 720px;
   margin: 0 auto;
   padding: 30px 15px;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Carousel
 */
 
 /* bắt đầu viết code cho carousel tại đây */
0

Tạo Slide ảnh bằng Javascript

3. Các nút chuyển slide trái/phải

Như thường lệ thì sau khi viết code xong cho các thiết bị màn hình lớn chúng ta cần phải quan tâm tới người dùng các thiết bị di động có màn hình nhỏ. Các

/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
2 thực sự rất khó sử dụng đối với thao tác chạm trên màn hình điện thoại. Ở đây chúng ta có thể nghĩ đến cách xử lý giống với khi xây dựng thanh điều hướng responsive bằng cách sử dụng các thẻ
/* Reset CSS + Container */

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

.container {
   max-width: 720px;
   margin: 0 auto;
   padding: 30px 15px;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Carousel
 */
 
 /* bắt đầu viết code cho carousel tại đây */
07 làm nút nhấn và kết nối tới các
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
2 bằng các cặp
/* Reset CSS + Container */

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

.container {
   max-width: 720px;
   margin: 0 auto;
   padding: 30px 15px;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Carousel
 */
 
 /* bắt đầu viết code cho carousel tại đây */
09. Tuy nhiên lúc này chúng ta chỉ có 2 nút nhấn trái/phải làm sao để kết nối được với tất cả các
/* Images */

.carousel-image {
   width: 100%;
   height: auto;
}

/* Positioning Images */

.carousel {
   position: relative;
}

.carousel-image {
   position: absolute;
   top: 0;
   left: 0;
}
2?

Vấn đề mới của chúng ta lúc này lại rất giống với chức năng cơ bản của

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
3: "Chúng ta có rất nhiều ảnh nhưng lại chỉ cần hiển thị 1 tấm duy nhất tại một thời điểm" ~ "Chúng ta có rất nhiều nút nhấn nhưng chỉ cần hiển thị 1 hoặc 2 nút nhấn của các ảnh bên trái và bên phải so với ảnh đang được hiển thị".

Tuy nhiên thì trước hết chúng ta hãy cứ khiến cho các nút nhấn xuất hiện đã. Thêm vào đó là chúng ta cần chèn biểu tượng vào các nút nhấn trong các trạng thái: đứng trước, đứng sau, và đang được chọn.

/* Reset CSS + Container */

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

.container {
   max-width: 720px;
   margin: 0 auto;
   padding: 30px 15px;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Carousel
 */
 
 /* bắt đầu viết code cho carousel tại đây */
2
/* Reset CSS + Container */

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

.container {
   max-width: 720px;
   margin: 0 auto;
   padding: 30px 15px;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Carousel
 */
 
 /* bắt đầu viết code cho carousel tại đây */
3

Tạo Slide ảnh bằng Javascript

Tới đây thì có vẻ như mọi thứ đã hoàn thiện rồi. Tuy nhiên thì nếu như bạn thử sử dụng lại các nút nhấn thì sẽ có một vấn đề phát sinh. Đó là nếu như chúng ta sử dụng nút nhấn phía bên phải thì

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
6 sẽ nhảy tới ảnh cuối cùng. Còn nút nhấn bên trái thì lại hoạt động rất tốt. Lý do là vì chúng ta xếp chồng các nút nhấn ở 2 vị trí do đó nên cứ nút nhấn nào đứng sau thì sẽ được hiển thị cao nhất và nhận được click chuột. Điều này hoàn toàn phù hợp với logic hoạt động của chồng nút nhấn phía bên trái, tuy nhiên lại bị ngược so với chồng nút nhấn phía bên phải.

Vậy bây giờ chúng ta cần điều chỉnh lại logic hiển thị của chồng nút nhấn phía bên phải với logic là cứ nút nhấn nào đứng sau thì sẽ được hiển thị thấp hơn. Tới đây thì phiên bản CSS chính thức hiện tại chưa hỗ trợ chúng ta công cụ để tự động hóa tác vụ này. Chúng ta sẽ phải chọn thủ công từ nút nhấn cuối cùng và đặt

/* Reset CSS + Container */

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

.container {
   max-width: 720px;
   margin: 0 auto;
   padding: 30px 15px;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Carousel
 */
 
 /* bắt đầu viết code cho carousel tại đây */
18 - thấp nhất nhưng vẫn ở trên so với các ảnh; Sau đó lần lượt chọn tới các nút nhấn đứng trước và tăng dần
/* Reset CSS + Container */

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

.container {
   max-width: 720px;
   margin: 0 auto;
   padding: 30px 15px;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Carousel
 */
 
 /* bắt đầu viết code cho carousel tại đây */
04. Và chúng ta sẽ cần phải thiết lập CSS cho đủ số nút nhấn hay số ảnh có khả năng xuất hiện trong slide. Ở đây mình tạm giả định tối đa là 10 ảnh, bạn có thể code thêm nếu cần sử dụng nhiều hơn.

/* Reset CSS + Container */

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

.container {
   max-width: 720px;
   margin: 0 auto;
   padding: 30px 15px;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Carousel
 */
 
 /* bắt đầu viết code cho carousel tại đây */
5

Dọn dẹp code

Xin chúc mừng!!! Bạn đã xây dựng xong một slide ảnh đơn giản và có thể sử dụng cho trang web của bạn.

Tạo Slide ảnh bằng Javascript

Việc dọn dẹp code chỉ có một chút lưu ý là bạn cần cân nhắc khi gộp code ghi đè các thuộc tính được viết ở bên dưới lên các khối code ở trên có cùng bộ chọn. Code gọn gàng hơn và tập trung hơn thì tệp CSS sẽ nhẹ hơn và trang web được tải nhanh hơn nhưng cũng đánh đổi lại về khả năng đọc/sửa code sau một thời gian mà bạn không chạm vào.

Bạn đã hoàn thành một công việc thực sự nghiêm túc. Slide ảnh hiện tại của chúng ta khá hoàn thiện và có thể tương tác tốt với người dùng. Tuy nhiên nếu như người dùng mở trang web và không nhấn chuyển ảnh thì

/* Frame */

.carousel {
   background-color: lightgray;

   display: block;
   width: 100%;
   padding-top: 56%;
}
3 sẽ không tự động lưu chuyển giữa các ảnh mà bạn đã đăng tải. Điều này có thể hiểu đơn giản là chúng ta sẽ có thể làm tốt hơn nữa trong tương lai khi có trong tay thêm nhiều công cụ hơn nữa.

Bạn đã sẵn sàng học thêm những kiến thức mới để kiến tạo tốt hơn? 😄

Hãy cùng quay trở lại bài viết về CSS mà chúng ta đang bỏ dở. Vẫn còn rất nhiều thứ thú vị đang chờ đợi chúng ta ở phía trước.