🧱 Phase 1 · HTML 🟢 Beginner MODULE 03

Links, Images & Media

⏱️ 35 min
📖 Theory + Code
🧩 5 Questions
🏗️ 1 Challenge
Phase 1 progress50%
🎯 What you'll learn: The anchor tag and all its link types (external, internal, email, phone), relative vs absolute paths, the image element with all key attributes, responsive images with srcset, the <figure> pattern, embedding video and audio, and iframes for YouTube embeds.

Anchor Tags — The Link Element

The <a> (anchor) tag creates hyperlinks. The href attribute specifies the destination. Links can go to: external websites, other pages on your site, sections within the same page, email addresses, or phone numbers.

links.html
HTML
<!-- External link — opens site in same tab -->
<a href="https://bitwithbite.com">Visit BitWithBite</a>

<!-- target="_blank" opens in new tab -->
<a href="https://google.com" target="_blank" rel="noopener noreferrer">
  Google (opens in new tab)
</a>

<!-- Internal link — another page on your site -->
<a href="about.html">About Us</a>
<a href="courses/python.html">Python Course</a>

<!-- Anchor link — jump to section on same page -->
<a href="#contact">Jump to Contact</a>

<!-- The target section (has matching id) -->
<section id="contact">
  <h2>Contact Us</h2>
</section>

<!-- Email link — opens mail app -->
<a href="mailto:hello@bwb.com">Email Us</a>

<!-- Phone link — works on mobile -->
<a href="tel:+923001234567">Call: 0300-1234567</a>

<!-- Download link -->
<a href="files/guide.pdf" download>Download PDF</a>

<!-- Image as a link -->
<a href="https://bwb.com">
  <img src="logo.png" alt="BitWithBite">
</a>
⚠️
Always add rel="noopener noreferrer" with target="_blank"
Without rel="noopener noreferrer", the new tab can access your page's window.opener object — a security vulnerability called "tab-napping." Always pair target="_blank" with rel="noopener noreferrer" on external links.

Relative vs Absolute Paths

Understanding file paths is essential for linking pages and embedding images correctly. Absolute paths are full URLs. Relative paths are relative to the current file's location.

PathTypeMeaning
https://bwb.com/coursesAbsoluteFull URL — works from anywhere
about.htmlRelativeSame folder as current file
courses/python.htmlRelativeInside "courses" subfolder
../index.htmlRelativeOne folder up, then index.html
../../style.cssRelativeTwo folders up
/images/logo.pngRoot-relativeFrom site root (not local files)
File structure example
STRUCTURE
my-website/
├── index.html
├── about.html
├── style.css
├── images/
│   ├── logo.png
│   └── hero.jpg
└── courses/
    ├── python.html
    └── html-css.html

From index.html:
  <img src="images/logo.png">     ← correct
  <a href="courses/python.html">  ← correct
  <link rel="stylesheet" href="style.css">

From courses/python.html:
  <img src="../images/logo.png">  ← go up one level first
  <a href="../about.html">        ← go up one level
  <link rel="stylesheet" href="../style.css">

Images

The <img> element embeds images. It's a void element — no closing tag. The src (source) and alt (alternative text) attributes are both essential — alt is required for accessibility and appears if the image fails to load.

AttributeRequired?Description
srcYesPath or URL to the image file
altYesDescriptive text for screen readers and broken images. Empty string alt="" for decorative images.
widthRecommendedDisplay width in pixels — prevents layout shift while loading
heightRecommendedDisplay height — browser reserves space before image loads
loadingOptional"lazy" delays loading until near the viewport — improves performance
srcsetOptionalMultiple image sources for different screen sizes
images.html
HTML
<!-- Basic image -->
<img src="images/hero.jpg" alt="Students studying at BitWithBite">

<!-- With dimensions (prevents layout shift) -->
<img src="logo.png" alt="BitWithBite logo"
     width="200" height="60">

<!-- Lazy loading — loads only when near viewport -->
<img src="gallery/photo1.jpg"
     alt="Campus photo"
     loading="lazy"
     width="800" height="500">

<!-- Decorative image — empty alt (screen reader skips it) -->
<img src="divider.svg" alt="">

<!-- External image (from URL) -->
<img src="https://picsum.photos/800/400"
     alt="Random photo from Picsum"
     width="800" height="400">

<!-- figure + figcaption — semantic image with caption -->
<figure>
  <img src="python-popularity.png"
       alt="Bar chart showing Python is #1 language in 2025"
       width="600" height="400">
  <figcaption>Python tops the TIOBE Index, Jan 2025.</figcaption>
</figure>

<!-- Responsive images with srcset -->
<img
  src="hero-800.jpg"
  srcset="hero-400.jpg 400w,
          hero-800.jpg 800w,
          hero-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw, 800px"
  alt="Hero banner">
Write descriptive, meaningful alt text
Good alt text describes the image's content and purpose, not "image of..." or "photo of...". Instead of alt="image of a graph" write alt="Bar chart showing Python overtook JavaScript as the most used language in 2024". Screen reader users should get the same information sighted users get from seeing the image.

Video, Audio & iframes

HTML5 introduced native <video> and <audio> elements — no plugins required. For YouTube/Vimeo embeds, use an <iframe> with the platform's embed URL.

media.html
HTML
<!-- Video element -->
<video
  src="lesson.mp4"
  controls             <!-- shows play/pause/volume controls -->
  width="720"
  height="405"
  poster="thumbnail.jpg"   <!-- image shown before play -->
  preload="metadata"       <!-- only load metadata, not full video -->
>
  <!-- Fallback for old browsers -->
  Your browser doesn't support HTML5 video.
</video>

<!-- Multiple sources (different formats) -->
<video controls width="720">
  <source src="lesson.webm" type="video/webm">
  <source src="lesson.mp4"  type="video/mp4">
</video>

<!-- Audio element -->
<audio src="podcast.mp3" controls>
  Your browser doesn't support HTML5 audio.
</audio>

<!-- YouTube embed (iframe) -->
<iframe
  width="720"
  height="405"
  src="https://www.youtube.com/embed/VIDEO_ID"
  title="Introduction to HTML — BitWithBite"
  frameborder="0"
  allow="accelerometer; autoplay; clipboard-write; encrypted-media"
  allowfullscreen
></iframe>

<!-- Google Maps embed -->
<iframe
  src="https://maps.google.com/maps?q=Lahore&output=embed"
  width="600" height="400"
  title="Map of Lahore"
  loading="lazy"
></iframe>
💡
Always add title to iframes
Screen readers announce iframes by their title attribute. Without it, a screen reader user hears "unnamed embedded content" — which is useless. Always write a descriptive title attribute: title="Introduction to Python video lesson".
🧩 Knowledge Check
5 questions — Links, Images & Media
1. Which attribute makes a link open in a new browser tab?
2. What does the alt attribute on an <img> do?
3. If you're in courses/python.html and want to link to images/logo.png at the root, what path do you use?
4. Which element semantically wraps an image with a caption?
5. What attribute on <img> delays loading until the image is near the viewport?
🏗️
Challenge — Media-Rich Profile Page
Links, images, figure, and YouTube embed all in one page
Task: Build profile.html — a personal profile page that includes:

1. A <header> with a site name and <nav> with links to Home, Portfolio, and Contact (use # for href)
2. A profile <figure> with an image from https://picsum.photos/200/200 and a <figcaption>
3. An <h1> name and an "About Me" paragraph with <strong> and <em> formatting
4. A "My Socials" section with 3 links: one to GitHub, one to LinkedIn, one email link — the first two opening in new tabs with rel="noopener noreferrer"
5. A "Favourite YouTube Tutorial" section with an embedded YouTube iframe
6. Use loading="lazy" on the image
💡 Show hints
  • Picsum photo: <img src="https://picsum.photos/200/200" alt="Profile photo" loading="lazy" width="200" height="200">
  • GitHub link: <a href="https://github.com/yourusername" target="_blank" rel="noopener noreferrer">
  • YouTube embed URL: go to any video, click Share → Embed, copy the iframe src
  • Email link: <a href="mailto:you@email.com">
profile.html — Sample Solution
HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Ali Hassan | Profile</title>
</head>
<body>

  <header>
    <h1>Ali Hassan</h1>
    <nav>
      <a href="#">Home</a> |
      <a href="#portfolio">Portfolio</a> |
      <a href="#contact">Contact</a>
    </nav>
  </header>

  <main>
    <figure>
      <img src="https://picsum.photos/200/200"
           alt="Ali Hassan profile photo"
           loading="lazy"
           width="200" height="200">
      <figcaption>That's me! 📸</figcaption>
    </figure>

    <section>
      <h2>About Me</h2>
      <p>I'm <strong>Ali Hassan</strong>, a developer from
      <em>Lahore, Pakistan</em>. I love building for the web.</p>
    </section>

    <section id="contact">
      <h2>My Socials</h2>
      <ul>
        <li>
          <a href="https://github.com/ali"
             target="_blank"
             rel="noopener noreferrer">GitHub</a>
        </li>
        <li>
          <a href="https://linkedin.com/in/ali"
             target="_blank"
             rel="noopener noreferrer">LinkedIn</a>
        </li>
        <li>
          <a href="mailto:ali@example.com">Email Me</a>
        </li>
      </ul>
    </section>

    <section>
      <h2>Favourite Tutorial</h2>
      <iframe
        width="560" height="315"
        src="https://www.youtube.com/embed/dQw4w9WgXcQ"
        title="My favourite tutorial"
        frameborder="0"
        allowfullscreen
      ></iframe>
    </section>
  </main>

</body>
</html>
🎉
Lesson 3 Complete!
Links, images, and media mastered! One lesson left in Phase 1 — Forms, Tables & Lists!
← Course Home
Phase 1 · HTMLLesson 3 of 4