HTML Images and Media Elements
1. Image Elements (<img src alt>) and Responsive Images
| Attribute | Purpose | Values/Syntax | Required |
|---|---|---|---|
| src | Image source URL | URL or path to image file | Yes |
| alt | Alternative text for accessibility | Descriptive text (empty for decorative) | Yes |
| width | Image width in pixels | Number (without unit) | Recommended |
| height | Image height in pixels | Number (without unit) | Recommended |
| srcset | Responsive image sources | url 1x, url 2x or url 400w |
Optional |
| sizes | Image display sizes (with srcset) | Media conditions + size | With srcset (w) |
| loading | Lazy loading behavior | lazy, eager |
Optional |
| decoding | Image decode timing | async, sync, auto |
Optional |
| crossorigin | CORS settings | anonymous, use-credentials |
For cross-origin images |
| ismap | Server-side image map | Boolean | Rare use |
| usemap | Client-side image map | #mapname |
With <map> |
Example: Responsive images with srcset and sizes
<!-- Basic image with alt text -->
<img src="photo.jpg" alt="Description of photo" width="800" height="600">
<!-- Responsive with pixel density (Retina) -->
<img src="image.jpg"
srcset="image.jpg 1x, image-2x.jpg 2x, image-3x.jpg 3x"
alt="Responsive image">
<!-- Responsive with width descriptors -->
<img src="photo-800.jpg"
srcset="photo-400.jpg 400w,
photo-800.jpg 800w,
photo-1200.jpg 1200w,
photo-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
800px"
alt="Adaptive image">
<!-- Lazy loading -->
<img src="image.jpg" alt="Lazy loaded" loading="lazy">
<!-- Async decoding for performance -->
<img src="large.jpg" alt="Large image" decoding="async">
<!-- Decorative image (empty alt) -->
<img src="decoration.png" alt="" role="presentation">
<!-- Image map -->
<img src="map.jpg" alt="Interactive map" usemap="#regions">
<map name="regions">
<area shape="rect" coords="0,0,100,100" href="region1.html" alt="Region 1">
<area shape="circle" coords="200,200,50" href="region2.html" alt="Region 2">
</map>
Note: Always specify
width and height to prevent layout shifts (CLS).
Use loading="lazy" for below-fold images. Alt text is required for
accessibility.
2. Picture Element (<picture>) and Source Sets (srcset)
| Element | Purpose | Attributes | Use Case |
|---|---|---|---|
| <picture> | Container for multiple sources | None | Art direction, format selection |
| <source> | Define image source options | srcset, media, type, sizes | Conditional image loading |
| <img> | Fallback image (required) | src, alt | Default/fallback display |
Source Attributes
| Attribute | Purpose |
|---|---|
| srcset | Image URL(s) with descriptors |
| media | Media query condition |
| type | MIME type (format detection) |
| sizes | Display size hints |
| width/height | Intrinsic dimensions |
Use Cases:
- Art Direction: Different crops for mobile/desktop
- Format Selection: WebP/AVIF with JPEG fallback
- Resolution Switching: Different sizes per viewport
- Dark mode variations
- Print vs screen images
- Locale-specific images
Example: Picture element for art direction and formats
<!-- Art direction: different images for different viewports -->
<picture>
<source media="(min-width: 1200px)" srcset="hero-wide.jpg">
<source media="(min-width: 768px)" srcset="hero-medium.jpg">
<img src="hero-mobile.jpg" alt="Hero image">
</picture>
<!-- Format selection: modern formats with fallbacks -->
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Optimized image">
</picture>
<!-- Combined: format + resolution -->
<picture>
<source srcset="photo-800.webp 800w, photo-1200.webp 1200w"
type="image/webp">
<source srcset="photo-800.jpg 800w, photo-1200.jpg 1200w"
type="image/jpeg">
<img src="photo-800.jpg" alt="Photo" loading="lazy">
</picture>
<!-- Dark mode variation -->
<picture>
<source srcset="logo-dark.png" media="(prefers-color-scheme: dark)">
<img src="logo-light.png" alt="Company logo">
</picture>
<!-- Print-specific image -->
<picture>
<source srcset="chart-print.png" media="print">
<img src="chart-screen.png" alt="Sales chart">
</picture>
Warning: Browser selects first matching source. Order matters!
Put most specific media queries first. Always include <img> as fallback.
3. SVG Integration (<svg>) and Inline Graphics
| Method | Syntax | Pros | Cons |
|---|---|---|---|
| Inline SVG | <svg>...</svg> |
CSS/JS control, no HTTP request | Increases HTML size, not cached |
| IMG tag | <img src="image.svg"> |
Simple, cached, responsive | No CSS/JS manipulation |
| Object | <object data="image.svg"> |
Interactive, scriptable | Complex, slower |
| CSS Background | background: url(image.svg) |
Decorative, cached | Not in HTML, no alt text |
| Data URL | <img src="data:image/svg+xml,..."> |
No HTTP request | Not cached, size limit |
SVG Viewport Attributes
| Attribute | Purpose |
|---|---|
| width | SVG width (with unit or viewBox) |
| height | SVG height (with unit or viewBox) |
| viewBox | Coordinate system: min-x min-y width height |
| preserveAspectRatio | Scaling behavior |
Common SVG Elements:
<circle>- Circle shapes<rect>- Rectangles<path>- Complex paths<line>,<polyline>- Lines<polygon>- Closed shapes<text>- Text content<g>- Group elements
Example: SVG integration methods
<!-- 1. Inline SVG (full control) -->
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" fill="#007acc" />
<text x="50" y="55" text-anchor="middle" fill="white" font-size="20">SVG</text>
</svg>
<!-- 2. IMG tag (simple, cached) -->
<img src="icon.svg" alt="Icon" width="32" height="32">
<!-- 3. Object element (interactive) -->
<object data="diagram.svg" type="image/svg+xml" width="400" height="300">
<img src="diagram-fallback.png" alt="Diagram">
</object>
<!-- 4. Responsive inline SVG -->
<svg viewBox="0 0 200 100" preserveAspectRatio="xMidYMid meet">
<rect x="10" y="10" width="180" height="80" fill="none" stroke="#333" stroke-width="2"/>
<circle cx="100" cy="50" r="30" fill="#ff6b6b"/>
</svg>
<!-- 5. SVG with ARIA -->
<svg role="img" aria-labelledby="icon-title">
<title id="icon-title">Settings Icon</title>
<path d="M10 10 H 90 V 90 H 10 Z" fill="#666"/>
</svg>
<!-- 6. SVG sprite (reusable icons) -->
<svg style="display:none">
<symbol id="icon-home" viewBox="0 0 24 24">
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
</symbol>
</svg>
<svg width="24" height="24">
<use href="#icon-home"/>
</svg>
Note: Use inline SVG for icons you want to style with CSS. Use <img> for simple, static
SVGs. Add
role="img" and <title> for accessibility.
4. Audio Elements (<audio>) and Media Controls
| Attribute | Purpose | Values | Default |
|---|---|---|---|
| src | Audio file URL | URL to audio file | None |
| controls | Show playback controls | Boolean | false |
| autoplay | Auto-start playback | Boolean | false (blocked by browsers) |
| loop | Repeat playback | Boolean | false |
| muted | Start muted | Boolean | false |
| preload | Preload strategy | none, metadata, auto |
auto |
| crossorigin | CORS mode | anonymous, use-credentials |
None |
Example: Audio elements with multiple sources
<!-- Simple audio with controls -->
<audio src="audio.mp3" controls>
Your browser does not support the audio element.
</audio>
<!-- Multiple formats for compatibility -->
<audio controls>
<source src="audio.mp3" type="audio/mpeg">
<source src="audio.ogg" type="audio/ogg">
<source src="audio.wav" type="audio/wav">
<p>Your browser doesn't support HTML5 audio.
<a href="audio.mp3">Download the audio</a>.</p>
</audio>
<!-- Looping background music (muted by default) -->
<audio loop muted autoplay>
<source src="background.mp3" type="audio/mpeg">
</audio>
<!-- Preload metadata only -->
<audio controls preload="metadata">
<source src="podcast.mp3" type="audio/mpeg">
</audio>
<!-- With custom controls via JavaScript -->
<audio id="myAudio" src="audio.mp3"></audio>
<button onclick="document.getElementById('myAudio').play()">Play</button>
<button onclick="document.getElementById('myAudio').pause()">Pause</button>
<button onclick="document.getElementById('myAudio').volume += 0.1">Volume Up</button>
Warning: Autoplay is blocked by most browsers unless video is
muted or user has interacted with the page. Use
autoplay muted together if autoplay is essential.
5. Video Elements (<video>) and Streaming Support
| Attribute | Purpose | Values | Notes |
|---|---|---|---|
| src | Video file URL | URL to video file | Use <source> for multiple formats |
| poster | Thumbnail before playback | Image URL | Shows until play clicked |
| controls | Show playback controls | Boolean | Recommended for usability |
| width/height | Video dimensions | Pixels (number only) | Maintains aspect ratio |
| autoplay | Auto-start playback | Boolean | Requires muted in most browsers |
| loop | Repeat playback | Boolean | Useful for background videos |
| muted | Start muted | Boolean | Required for autoplay |
| preload | Preload strategy | none, metadata, auto |
Affects bandwidth usage |
| playsinline | Inline playback (mobile) | Boolean | iOS: prevents fullscreen |
| disablepictureinpicture | Disable PiP mode | Boolean | Optional |
Example: Video elements with advanced features
<!-- Basic video with controls -->
<video src="video.mp4" controls width="640" height="360">
Your browser doesn't support HTML5 video.
</video>
<!-- Multiple formats + poster -->
<video controls width="800" height="450" poster="thumbnail.jpg">
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
<p>Your browser doesn't support HTML5 video.
<a href="video.mp4">Download the video</a>.</p>
</video>
<!-- With subtitles/captions -->
<video controls>
<source src="movie.mp4" type="video/mp4">
<track kind="subtitles" src="subs-en.vtt" srclang="en" label="English" default>
<track kind="subtitles" src="subs-es.vtt" srclang="es" label="Español">
<track kind="captions" src="captions-en.vtt" srclang="en" label="English Captions">
</video>
<!-- Autoplay background video (muted) -->
<video autoplay muted loop playsinline>
<source src="background.mp4" type="video/mp4">
<source src="background.webm" type="video/webm">
</video>
<!-- Responsive video (CSS controlled) -->
<video controls style="max-width: 100%; height: auto;">
<source src="responsive.mp4" type="video/mp4">
</video>
<!-- Preload metadata only -->
<video controls preload="metadata" poster="poster.jpg">
<source src="large-video.mp4" type="video/mp4">
</video>
Note: For autoplay to work, video must be
muted. Use playsinline on
iOS to prevent fullscreen. Always provide poster image for better UX.
6. Canvas (<canvas>) and Graphics API Integration
| Attribute | Purpose | Values | Required |
|---|---|---|---|
| width | Canvas width in pixels | Number (default: 300) | Recommended |
| height | Canvas height in pixels | Number (default: 150) | Recommended |
Canvas Context Types
| Context | Purpose |
|---|---|
| 2d | 2D drawing (shapes, text, images) |
| webgl | 3D graphics (OpenGL ES) |
| webgl2 | Enhanced 3D (OpenGL ES 3.0) |
| bitmaprenderer | ImageBitmap rendering |
Common 2D Methods:
fillRect()- Draw filled rectanglestrokeRect()- Draw rectangle outlinefillText()- Draw filled textdrawImage()- Draw imagebeginPath()- Start patharc()- Draw circle/arclineTo()- Draw line
Example: Canvas element with 2D drawing
<!-- Basic canvas element -->
<canvas id="myCanvas" width="400" height="300">
Your browser doesn't support canvas.
</canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Draw rectangle
ctx.fillStyle = '#007acc';
ctx.fillRect(50, 50, 100, 80);
// Draw circle
ctx.beginPath();
ctx.arc(250, 90, 40, 0, 2 * Math.PI);
ctx.fillStyle = '#ff6b6b';
ctx.fill();
// Draw text
ctx.font = '20px Arial';
ctx.fillStyle = '#333';
ctx.fillText('Canvas Drawing', 100, 200);
// Draw line
ctx.beginPath();
ctx.moveTo(50, 250);
ctx.lineTo(350, 250);
ctx.strokeStyle = '#000';
ctx.lineWidth = 3;
ctx.stroke();
</script>
<!-- Responsive canvas -->
<canvas id="responsive" style="width: 100%; height: auto;"></canvas>
<script>
const canvas = document.getElementById('responsive');
// Set actual size in pixels
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
</script>
<!-- Export canvas as image -->
<canvas id="exportable" width="200" height="200"></canvas>
<button onclick="exportCanvas()">Download as PNG</button>
<script>
function exportCanvas() {
const canvas = document.getElementById('exportable');
const dataURL = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.download = 'canvas-image.png';
link.href = dataURL;
link.click();
}
</script>
Warning: Set canvas dimensions via
width/height attributes, not CSS.
CSS scales the canvas bitmap, causing blur. Canvas content is not accessible to
screen readers.
7. Object and Embed Elements (<object>, <embed>)
| Element | Purpose | Use Cases | Support |
|---|---|---|---|
| <object> | Embed external resources | PDFs, SVGs, Flash (legacy), plugins | Universal |
| <embed> | Embed plugins/external content | PDFs, multimedia (legacy) | Universal |
| <iframe> | Embed another HTML page | External sites, widgets, ads | Universal |
Example: Object, embed, and iframe usage
<!-- Object: PDF embed -->
<object data="document.pdf" type="application/pdf" width="100%" height="600">
<p>PDF cannot be displayed. <a href="document.pdf">Download PDF</a></p>
</object>
<!-- Object: SVG with fallback -->
<object data="diagram.svg" type="image/svg+xml" width="400" height="300">
<img src="diagram-fallback.png" alt="Diagram">
</object>
<!-- Embed: PDF (legacy) -->
<embed src="document.pdf" type="application/pdf" width="100%" height="600">
<!-- Iframe: External website -->
<iframe src="https://example.com" width="800" height="600"
title="External content">
</iframe>
<!-- Iframe: YouTube embed -->
<iframe width="560" height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
<!-- Iframe: Sandboxed for security -->
<iframe src="untrusted.html"
sandbox="allow-scripts allow-same-origin"
width="600" height="400">
</iframe>
<!-- Iframe: Lazy loading -->
<iframe src="content.html" loading="lazy" width="100%" height="400">
</iframe>
<!-- Responsive iframe (16:9 aspect ratio) -->
<div style="position: relative; padding-bottom: 56.25%; height: 0;">
<iframe src="video.html"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
frameborder="0">
</iframe>
</div>
Warning: Iframes can pose security risks. Use
sandbox attribute to restrict capabilities. For untrusted content, use sandbox=""
(maximum restrictions) and selectively enable features.
Section 6 Key Takeaways
- Always include
alttext for images; specifywidthandheightto prevent CLS - Use
srcsetandsizesfor responsive images based on viewport/density - <picture> for art direction (different crops) and format selection (WebP/AVIF fallback)
- Inline SVG for CSS/JS control; <img> for simple static SVGs
- Autoplay requires
mutedattribute; most browsers block unmuted autoplay - Use <track> for video subtitles/captions; WebVTT format
- Canvas dimensions set via attributes, not CSS; content not accessible
- Use iframe
sandboxfor security;loading="lazy"for performance