🔗 Bài 3: Links & Media

Học cách tạo liên kết, chèn hình ảnh, video, audio và nội dung multimedia

🔗 1. Liên kết (Links)

Thẻ <a> được sử dụng để tạo liên kết đến trang khác, file, email hoặc vị trí khác trên cùng trang.

Liên kết cơ bản

<a href="https://www.google.com">Đi đến Google</a>
<a href="mailto:email@example.com">Gửi email</a>
<a href="tel:+84123456789">Gọi điện thoại</a>

📋 Các thuộc tính quan trọng của thẻ <a>

Thuộc tính Ý nghĩa Giá trị Ví dụ
href Đường dẫn đích - xác định nơi liên kết sẽ dẫn đến URL, email, số điện thoại, anchor href="https://example.com"
target Cách mở liên kết - quyết định liên kết mở ở đâu _blank, _self, _parent, _top target="_blank"
rel Mối quan hệ giữa trang hiện tại và trang đích noopener, noreferrer, nofollow rel="noopener"
download Yêu cầu tải xuống file thay vì mở tên file hoặc để trống download="document.pdf"
title Tooltip hiển thị khi hover - thông tin bổ sung văn bản mô tả title="Mở trong tab mới"
hreflang Ngôn ngữ của trang đích mã ngôn ngữ (vi, en, ja...) hreflang="en"
<!-- Liên kết bên ngoài - mở tab mới + bảo mật -->
<a href="https://www.example.com" target="_blank" rel="noopener noreferrer">
  Trang web bên ngoài
</a>

<!-- Liên kết download -->
<a href="document.pdf" download="TaiLieu.pdf" title="Tải xuống tài liệu">
  Tải tài liệu PDF
</a>

<!-- Liên kết nội bộ -->
<a href="about.html" target="_self" title="Trang giới thiệu">
  Giới thiệu
</a>

Liên kết nội bộ (Anchors)

Liên kết nội bộ cho phép nhảy đến vị trí cụ thể trong cùng trang. Hữu ích cho navigation và mục lục.

<!-- Tạo liên kết anchor -->
<a href="#section1">Đi đến phần 1</a>
<a href="#top">Về đầu trang</a>

<!-- Phần tử đích -->
<section id="section1">
  <h2>Nội dung phần 1</h2>
</section>

💡 Mục lục (Table of Contents)

Lưu ý: "Table of Contents" là mục lục, dùng <nav> + <ul>, không phải thẻ <table>.

<nav class="table-of-contents">
  <h3>📚 Mục lục</h3>
  <ul>
    <li><a href="#gioi-thieu">Giới thiệu</a></li>
    <li><a href="#noi-dung">Nội dung chính</a></li>
    <li><a href="#ket-luan">Kết luận</a></li>
  </ul>
</nav>

💡 Lưu ý quan trọng:

🖼️ 2. Hình ảnh (Images)

Thẻ <img> được sử dụng để chèn hình ảnh vào trang web.

Cú pháp cơ bản

<img src="duong-dan-hinh-anh.jpg" alt="Mô tả hình ảnh">

<!-- Với kích thước cụ thể -->
<img src="logo.png" alt="Logo công ty" width="200" height="100">

<!-- Từ URL bên ngoài -->
<img src="https://images.unsplash.com/photo-1461988320302-91bde64fc8e4?w=300&h=200&fit=crop&auto=format" alt="Hình ảnh demo">

📋 Thuộc tính quan trọng của thẻ <img>

Thuộc tính Ý nghĩa & Vai trò Các giá trị có thể Ví dụ & Khi nào dùng
src Bắt buộc - Đường dẫn đến file hình ảnh Relative path: images/photo.jpg
Absolute URL: https://domain.com/img.jpg
Data URL: data:image/jpeg;base64,...
Root relative: /assets/logo.png
src="./images/avatar.jpg" - File local
src="https://picsum.photos/300" - URL external
alt Bắt buộc - Văn bản thay thế cho accessibility Descriptive text: Mô tả nội dung ảnh
Empty string: alt="" cho decorative images
Functional text: Mô tả chức năng nếu ảnh là button/link
alt="CEO John Smith đang thuyết trình"
alt="" - Ảnh trang trí
alt="Tìm kiếm" - Icon button
loading Chiến lược tải ảnh - tối ưu performance lazy: Tải khi ảnh sắp vào viewport (mặc định cho ảnh không critical)
eager: Tải ngay lập tức cùng với trang
auto: Browser tự quyết định
loading="lazy" - Ảnh ở cuối trang
loading="eager" - Hero image, logo
Không set = auto
decoding Cách decode/xử lý ảnh async: Decode không đồng bộ, không block render
sync: Decode đồng bộ, có thể block render
auto: Browser tự chọn (mặc định)
decoding="async" - Ảnh không quan trọng
decoding="sync" - Critical images
decoding="auto" - Thông thường
fetchpriority Độ ưu tiên tải ảnh so với resources khác high: Tải với priority cao (hero images, above fold)
low: Priority thấp (ảnh không quan trọng)
auto: Browser tự quyết định (mặc định)
fetchpriority="high" - Banner chính
fetchpriority="low" - Thumbnail
fetchpriority="auto" - Default
width Chiều rộng hiển thị (ưu tiên dùng CSS) Pixel value: Số nguyên dương (VD: 300, 150)
Không có đơn vị: Tự hiểu là pixel
Responsive: Nên dùng CSS thay vì HTML attribute
width="300" - Fixed width
CSS: width: 100%; max-width: 400px; - Responsive
height Chiều cao hiển thị (ưu tiên dùng CSS) Pixel value: Số nguyên dương
Auto aspect ratio: Không set height để giữ tỷ lệ
CSS preferred: Flexible hơn HTML attribute
height="200" - Fixed height
CSS: height: auto; - Giữ tỷ lệ
title Tooltip khi hover - thông tin bổ sung Descriptive text: Thông tin chi tiết về ảnh
Context info: Ngày chụp, tác giả, địa điểm
Caption alternative: Khi không có figcaption
title="Chụp tại Hà Nội, tháng 3/2024"
title="Logo được thiết kế năm 2020"
crossorigin CORS policy khi tải ảnh từ domain khác anonymous: Không gửi credentials (cookies, auth)
use-credentials: Gửi credentials
Không set: Không có CORS request
crossorigin="anonymous" - CDN images
crossorigin="use-credentials" - Private images
sizes Kích thước ảnh sẽ hiển thị (dùng với srcset) Media condition: (max-width: 768px) 100vw
Default size: 50vw
Multiple conditions: Danh sách cách nhau bởi dấu phẩy
sizes="(max-width: 768px) 100vw, 50vw"
Kết hợp với srcset
srcset Danh sách các nguồn ảnh cho responsive/high-DPI Width descriptor: image.jpg 300w
Density descriptor: image@2x.jpg 2x
Multiple sources: Cách nhau bởi dấu phẩy
srcset="small.jpg 300w, large.jpg 800w"
srcset="normal.jpg 1x, retina.jpg 2x"

💡 Các thuộc tính quan trọng nhất:

🎯 Khi nào dùng gì:
  • loading="lazy": Dùng cho ảnh không ở đầu trang (90% trường hợp)
  • loading="eager": Dùng cho hero images, logo
  • alt="": Dùng cho ảnh trang trí. Alt mô tả nội dung cho ảnh quan trọng
  • fetchpriority="high": Chỉ dùng cho 1-2 ảnh quan trọng nhất
  • decoding="async": Tốt cho ảnh không quan trọng
📋 Kết quả hiển thị:
Hình ảnh demo - Thiết bị công nghệ hiện đại

Hình ảnh demo với các thuộc tính: alt, title, loading, decoding

🎯 Ví dụ thực tế với đầy đủ thuộc tính:

<!-- Ảnh hero với priority cao -->
<img src="hero-banner.jpg" 
     alt="Khóa học lập trình web 2024 - Từ cơ bản đến nâng cao"
     width="1200" 
     height="600"
     title="Banner khóa học - Click để tìm hiểu thêm"
     fetchpriority="high"
     decoding="sync">

<!-- Ảnh trong content với lazy loading -->
<img src="tutorial-step1.png"
     alt="Bước 1: Tạo file HTML cơ bản với thẻ DOCTYPE"
     loading="lazy"
     decoding="async"
     title="Hướng dẫn chi tiết từng bước">

<!-- Ảnh trang trí (không cần alt) -->
<img src="decoration.svg" 
     alt=""
     role="presentation"
     loading="lazy">

Hình ảnh làm liên kết

<a href="https://www.example.com">
  <img src="https://images.unsplash.com/photo-1557804506-669a67965ba0?w=400&h=200&fit=crop&auto=format" alt="Banner quảng cáo">
</a>

🎥 3. Video

HTML5 cung cấp thẻ <video> để chèn video trực tiếp vào trang web.

Cú pháp cơ bản

<video width="400" height="300" controls>
  <source src="https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_1mb.mp4" type="video/mp4">
  <source src="https://sample-videos.com/zip/10/webm/SampleVideo_1280x720_1mb.webm" type="video/webm">
  Trình duyệt của bạn không hỗ trợ video.
</video>

📋 Các thuộc tính quan trọng của thẻ <video>

Thuộc tính Ý nghĩa & Vai trò Giá trị Khi nào sử dụng
controls Hiển thị nút điều khiển (play, pause, volume, fullscreen) Không cần giá trị (boolean) Hầu hết trường hợp để người dùng điều khiển
autoplay Tự động phát video khi trang load Không cần giá trị (boolean) ⚠️ Cẩn thận: làm phiền người dùng, cần kèm muted
loop Lặp lại video khi kết thúc Không cần giá trị (boolean) Video ngắn, demo, background video
muted Tắt âm thanh mặc định Không cần giá trị (boolean) Bắt buộc khi dùng autoplay
poster Ảnh hiển thị trước khi video phát Đường dẫn đến file ảnh Tạo ấn tượng đầu, thumbnail video
preload Cách tải video khi trang load none, metadata, auto Tối ưu hiệu suất trang
width/height Kích thước hiển thị video Số pixel Định dạng layout, ưu tiên dùng CSS
playsinline Phát inline trên mobile thay vì fullscreen Không cần giá trị (boolean) Video nhỏ, không muốn fullscreen

💡 Thuộc tính preload:

🎯 Ví dụ thực tế với đầy đủ thuộc tính:

<!-- Video giới thiệu sản phẩm -->
<video width="800" height="450" 
       controls 
       poster="https://images.unsplash.com/photo-1536240478700-b869070f9279?w=800&h=450&fit=crop&auto=format"
       preload="metadata"
       playsinline>
  <source src="https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_2mb.mp4" type="video/mp4">
  <source src="https://sample-videos.com/zip/10/webm/SampleVideo_1280x720_1mb.webm" type="video/webm">
  <p>Trình duyệt của bạn không hỗ trợ video HTML5. 
     <a href="https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_2mb.mp4">Tải video</a>
  </p>
</video>

<!-- Background video tự động phát -->
<video width="100%" height="400"
       autoplay 
       muted 
       loop 
       playsinline
       preload="auto">
  <source src="background-video.mp4" type="video/mp4">
  <source src="background-video.webm" type="video/webm">
  <!-- Fallback image cho trường hợp không hỗ trợ video -->
  <img src="fallback-image.jpg" alt="Background image">
</video>

<!-- Video bài giảng với track subtitle -->
<video controls preload="metadata">
  <source src="lesson-video.mp4" type="video/mp4">
  <track kind="subtitles" src="subtitles-vi.vtt" srclang="vi" label="Tiếng Việt">
  <track kind="subtitles" src="subtitles-en.vtt" srclang="en" label="English">
</video>
📋 Kết quả hiển thị:

🎬 Video cơ bản với controls:

🌊 Video với poster (ảnh trước khi phát):

⚠️ Lưu ý quan trọng về video:

💡 Best Practices:
  • Autoplay + Muted: Hầu hết trình duyệt chặn autoplay có âm thanh
  • Multiple sources: Cung cấp nhiều format để tương thích tốt hơn
  • Poster image: Luôn có ảnh đại diện chất lượng cao
  • Fallback content: Cung cấp nội dung thay thế khi không hỗ trợ
  • Preload strategy: Chọn phù hợp với mục đích sử dụng
  • File size: Tối ưu kích thước file để load nhanh

🎵 4. Audio

Thẻ <audio> được sử dụng để chèn file âm thanh. Có nhiều thuộc tính tương tự video nhưng tối ưu cho âm thanh.

📋 Các thuộc tính của thẻ <audio>

Thuộc tính Ý nghĩa & Vai trò Giá trị Khi nào sử dụng
controls Hiển thị player controls (play, pause, volume, timeline) Boolean attribute Khi muốn user có thể điều khiển audio
autoplay Tự động phát khi trang load Boolean attribute ⚠️ Tránh dùng - gây khó chịu cho user
loop Lặp lại audio liên tục Boolean attribute Nhạc nền, sound effect
muted Tắt tiếng mặc định Boolean attribute Khi dùng autoplay hoặc background audio
preload Chiến lược tải audio none, metadata, auto Tối ưu performance và UX
volume Mức âm lượng mặc định (0.0 đến 1.0) Số thập phân Đặt âm lượng phù hợp với context
<!-- Audio player cơ bản -->
<audio controls preload="metadata">
  <source src="https://file-examples.com/storage/fe68c8606b6515ad79b2a56/2017/11/file_example_MP3_700KB.mp3" type="audio/mpeg">
  <source src="https://file-examples.com/storage/fe68c8606b6515ad79b2a56/2017/11/file_example_OGG_700KB.ogg" type="audio/ogg">
  <p>Trình duyệt của bạn không hỗ trợ audio HTML5. 
     <a href="https://file-examples.com/storage/fe68c8606b6515ad79b2a56/2017/11/file_example_MP3_700KB.mp3">Tải file audio</a>
  </p>
</audio>

🎯 Ví dụ với các thuộc tính nâng cao

<!-- Playlist audio với controls đầy đủ -->
<audio controls loop preload="metadata" volume="0.8">
  <source src="https://file-examples.com/storage/fe68c8606b6515ad79b2a56/2017/11/file_example_MP3_1MG.mp3" type="audio/mpeg">
  <source src="https://file-examples.com/storage/fe68c8606b6515ad79b2a56/2017/11/file_example_WAV_1MG.wav" type="audio/wav">
  <p>Trình duyệt không hỗ trợ phát audio.</p>
</audio>

<!-- Background music (ít dùng) -->
<audio autoplay muted loop preload="auto" volume="0.3">
  <source src="background-music.mp3" type="audio/mpeg">
  <source src="background-music.ogg" type="audio/ogg">
</audio>

<!-- Audio với JavaScript control -->
<audio id="myAudio" preload="none">
  <source src="notification.mp3" type="audio/mpeg">
</audio>
<button onclick="document.getElementById('myAudio').play()">
  Phát âm thanh thông báo
</button>
📋 Kết quả hiển thị:

🎵 Audio player cơ bản:

🎶 Audio với nhiều format:

📚 Link resources cho audio (Copy để sử dụng):

🎵 Audio Files:
  • MP3 700KB: https://file-examples.com/storage/fe68c8606b6515ad79b2a56/2017/11/file_example_MP3_700KB.mp3
  • MP3 1MB: https://file-examples.com/storage/fe68c8606b6515ad79b2a56/2017/11/file_example_MP3_1MG.mp3
  • OGG 700KB: https://file-examples.com/storage/fe68c8606b6515ad79b2a56/2017/11/file_example_OGG_700KB.ogg
  • WAV 1MB: https://file-examples.com/storage/fe68c8606b6515ad79b2a56/2017/11/file_example_WAV_1MG.wav

💡 Các định dạng audio phổ biến:

🎵 So sánh format audio:
Format Ưu điểm Nhược điểm Khi nào dùng
MP3 Tương thích cao, file nhỏ Chất lượng hơi giảm khi nén Nhạc, podcast, âm thanh thông dụng
WAV Chất lượng cao, không nén File rất lớn Audio chuyên nghiệp, sound effect ngắn
OGG Mã nguồn mở, chất lượng tốt Hỗ trợ hạn chế trên Safari/IE Web app, game
AAC Chất lượng tốt hơn MP3 Ít tương thích hơn MP3 iOS, Apple devices

💡 Giá trị preload cho audio:

🖼️ 5. Iframe - Nhúng nội dung bên ngoài

Thẻ <iframe> cho phép nhúng một trang web khác vào trang hiện tại. Rất mạnh mẽ nhưng cần thận trọng về bảo mật.

📋 Các thuộc tính quan trọng của <iframe>

Thuộc tính Ý nghĩa & Vai trò Giá trị Lưu ý bảo mật
src Bắt buộc - URL của trang cần nhúng URL tuyệt đối Chỉ nhúng từ nguồn tin cậy
width/height Kích thước của iframe Pixel hoặc phần trăm Không ảnh hưởng bảo mật
sandbox Quan trọng - Hạn chế quyền của iframe allow-forms, allow-scripts, v.v. Luôn sử dụng để tăng bảo mật
loading Chiến lược tải iframe lazy, eager lazy loading giúp tối ưu performance
allow Chính sách tính năng (Feature Policy) camera, microphone, autoplay, v.v. Hạn chế quyền truy cập thiết bị
referrerpolicy Chính sách gửi referrer no-referrer, same-origin, v.v. Bảo vệ thông tin trang gốc
title Mô tả nội dung iframe cho accessibility Văn bản mô tả Quan trọng cho screen reader

🔒 Thuộc tính sandbox:

Cú pháp cơ bản

<!-- Iframe cơ bản với bảo mật tối thiểu -->
<iframe src="https://www.google.com/maps/embed?..."
        width="600" 
        height="400"
        style="border:0;"
        sandbox="allow-scripts allow-same-origin"
        loading="lazy"
        title="Bản đồ Google Maps">
</iframe>

🎬 Nhúng video YouTube với đầy đủ thuộc tính

<iframe width="560" 
        height="315"
        src="https://www.youtube.com/embed/VIDEO_ID"
        title="Tiêu đề video YouTube"
        frameborder="0"
        sandbox="allow-scripts allow-same-origin allow-presentation"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen
        loading="lazy"
        referrerpolicy="no-referrer-when-downgrade">
</iframe>

🗺️ Nhúng Google Maps an toàn

<iframe
  src="https://www.google.com/maps/embed?pb=!1m18!1m12..."
  width="100%"
  height="300"
  style="border:0;"
  sandbox="allow-scripts allow-same-origin"
  allowfullscreen=""
  loading="lazy"
  referrerpolicy="no-referrer-when-downgrade"
  title="Vị trí địa điểm trên Google Maps">
</iframe>

🔐 Ví dụ iframe siêu an toàn

<!-- Iframe với bảo mật cao nhất -->
<iframe src="https://trusted-site.com/content"
        width="800"
        height="600"
        sandbox=""
        loading="lazy"
        referrerpolicy="no-referrer"
        title="Nội dung được nhúng an toàn">
  <p>Trình duyệt của bạn không hỗ trợ iframe.</p>
</iframe>

<!-- Iframe cho phép form nhưng không có script -->
<iframe src="https://survey.com/form"
        sandbox="allow-forms"
        title="Form khảo sát">
</iframe>

⚠️ Lưu ý bảo mật:

📋 Kết quả hiển thị:

🗺️ Google Maps nhúng:

🎬 YouTube video nhúng:

🔒 Iframe siêu an toàn (sandbox rỗng):

📷 6. Figure và Figcaption

Các thẻ semantic để nhóm media với caption của chúng. Rất quan trọng cho SEO và accessibility.

📋 Thuộc tính và ý nghĩa của <figure> và <figcaption>

Thẻ Ý nghĩa Khi nào sử dụng SEO Benefits
<figure> Container semantic cho nội dung độc lập (ảnh, video, code, chart) Khi có nội dung kèm caption hoặc có thể di chuyển mà không ảnh hưởng flow Giúp search engine hiểu cấu trúc nội dung
<figcaption> Caption/mô tả cho figure - có thể ở đầu hoặc cuối figure Mô tả, giải thích, credit cho media content Cung cấp context cho search engine và screen reader

🎯 Ví dụ với hình ảnh:

<figure>
  <img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=600&h=400&fit=crop&auto=format" 
       alt="Phong cảnh núi non hùng vĩ với những đỉnh cao phủ đầy tuyết trắng"
       loading="lazy">
  <figcaption>
    <strong>Dãy núi Alps, Thụy Sĩ</strong> - 
    Chụp vào lúc hoàng hôn từ đỉnh Matterhorn. 
    <em>Ảnh: John Smith, 2023</em>
  </figcaption>
</figure>

<!-- Figure với video -->
<figure>
  <video controls width="500" loading="lazy">
    <source src="https://sample-videos.com/zip/10/mp4/SampleVideo_640x360_1mb.mp4" type="video/mp4">
    <p>Trình duyệt không hỗ trợ video.</p>
  </video>
  <figcaption>
    Video hướng dẫn: <cite>"Cách tạo website responsive"</cite> - 
    Phần 1: Thiết lập HTML cơ bản
  </figcaption>
</figure>

📊 Figure với nội dung khác (không chỉ media):

<!-- Figure với code snippet -->
<figure>
  <pre><code>
function calculateSum(a, b) {
  return a + b;
}
  </code></pre>
  <figcaption>
    <strong>Listing 1.1:</strong> Hàm tính tổng cơ bản trong JavaScript
  </figcaption>
</figure>

<!-- Figure với quote -->
<figure>
  <blockquote>
    "Học lập trình không chỉ là học syntax, mà là học cách tư duy logic."
  </blockquote>
  <figcaption>
    — <cite>Linus Torvalds</cite>, Tạo ra Linux kernel
  </figcaption>
</figure>

<!-- Figure với table/chart -->
<figure>
  <table>
    <thead>
      <tr><th>Năm</th><th>Doanh số</th></tr>
    </thead>
    <tbody>
      <tr><td>2022</td><td>100M</td></tr>
      <tr><td>2023</td><td>150M</td></tr>
    </tbody>
  </table>
  <figcaption>
    <strong>Bảng 2.1:</strong> Tăng trường doanh số công ty qua các năm
  </figcaption>
</figure>
📋 Kết quả hiển thị:
Phong cảnh núi non tuyệt đẹp với đỉnh phủ tuyết trắng
Dãy núi Alps, Thụy Sĩ - Phong cảnh hùng vĩ chụp vào lúc hoàng hôn từ đỉnh Matterhorn
Ảnh: John Smith, 2023
Video hướng dẫn: "Cách tạo website responsive" - Phần 1: Thiết lập HTML cơ bản
function calculateSum(a, b) {
  return a + b;
}

// Sử dụng hàm
console.log(calculateSum(5, 3)); // 8
Listing 1.1: Hàm tính tổng cơ bản trong JavaScript
Năm Doanh số
2022 100M VNĐ
2023 150M VNĐ
Bảng 2.1: Tăng trưởng doanh số công ty qua các năm
📋 Kết quả hiển thị:
Phong cảnh núi non tuyệt đẹp với đỉnh phủ tuyết trắng
Dãy núi Alps, Thụy Sĩ - Phong cảnh hùng vĩ chụp từ đỉnh cao
Ảnh: Nature Photography, 2023

💡 Best Practices cho Figure & Figcaption:

✨ Nguyên tắc sử dụng:
  • Semantic meaning: Chỉ dùng khi nội dung có thể đứng độc lập
  • Caption placement: figcaption có thể ở đầu hoặc cuối figure
  • Multiple elements: Figure có thể chứa nhiều media + 1 figcaption
  • Accessibility: figcaption được screen reader đọc kèm với media
  • SEO friendly: Search engine sử dụng figcaption để hiểu context
  • Styling: Dùng CSS để style thay vì inline styles

🎯 Bài tập thực hành

Bài tập 1: Tạo trang Portfolio cá nhân

Yêu cầu: Tạo một trang giới thiệu cá nhân đơn giản với navigation, avatar, video, audio và liên kết.

📋 Demo mẫu Portfolio đơn giản (chỉ HTML):

👋 Xin chào, tôi là Nguyễn Văn A

Avatar của Nguyễn Văn A
Web Developer - 3 năm kinh nghiệm

Tôi là một lập trình viên web đam mê tạo ra những sản phẩm hiện đại.

🎬 Video giới thiệu bản thân
🎵 Audio đọc CV

🚀 Dự án nổi bật

Dự án website thương mại điện tử
E-commerce Website
ReactJS + Node.js
Ứng dụng mobile quản lý task
Task Management App
React Native + Firebase

📞 Liên hệ với tôi

📍 Vị trí văn phòng:

📝 Nhiệm vụ của bạn:

  1. Tạo file HTML với cấu trúc tương tự demo trên
  2. Thay thế thông tin cá nhân của bạn
  3. Thêm ảnh avatar thật của bạn (hoặc dùng link từ phần resources)
  4. Sử dụng video demo từ phần resources
  5. Thêm Google Maps cho địa chỉ của bạn
  6. Đảm bảo tất cả links hoạt động đúng

Bài tập 2: Gallery ảnh du lịch

Yêu cầu: Tạo gallery ảnh với HTML cơ bản.

📋 Demo mẫu Gallery đơn giản (chỉ HTML):

📸 Gallery: Khám phá Việt Nam

Vịnh Hạ Long - Di sản thế giới
🏞️ Vịnh Hạ Long - Kỳ quan thiên nhiên thế giới

📷 Những địa điểm đẹp

Ruộng bậc thang Sapa
Ruộng bậc thang Sapa
Tây Bắc hùng vĩ
Phố cổ Hội An
Phố cổ Hội An
Di sản văn hóa thế giới
Sài Gòn về đêm
Sài Gòn về đêm
Thành phố không ngủ
Bún chả Hà Nội
Bún chả Hà Nội
Đặc sản thủ đô
Bãi biển Phú Quốc
Bãi biển Phú Quốc
Thiên đường biển đảo
Văn Miếu Hà Nội
Văn Miếu Hà Nội
Trường đại học đầu tiên

🎬 Video tổng hợp chuyến đi
Những khoảnh khắc đẹp nhất trong hành trình khám phá Việt Nam

📸 Gallery gồm 6 địa điểm | 🕒 7 ngày | 💫 Những kỷ niệm không thể quên

📝 Nhiệm vụ của bạn:

  1. Tạo gallery với chủ đề yêu thích (du lịch, sở thích, gia đình...)
  2. Sử dụng ít nhất 6 hình ảnh
  3. Thêm video tổng hợp ở cuối
  4. Viết caption mô tả cho từng ảnh
  5. Dùng table để sắp xếp ảnh thành lưới
  6. Copy link từ phần "Tổng hợp link resources" bên dưới

💡 Tips thực hành đơn giản: