Lecteur Vidéo Material Design

Extraits & Composants HTML 07/04/2026 13:00:00 AngularForAll.com
Material Design Lecteur Video Video Player Responsive Ripple Material Icons Elevation Controls Html Snippet

Lecteur vidéo Material Design avec élévation, boutons MD, barre de progression stylisée, icônes Material Icons et effet ripple.

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8" />
  <meta name="copyright" content="AngularForAll" />
  <meta name="author" content="AngularForAll" />
  <meta name="robots" content="noindex, nofollow" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="Cache-Control" content="public, max-age=604800" />
  <title>Snippet Video Materiel 2026 04280042 | AngularForAll</title>
<meta name="theme-color" content="#f5f5f5">

    <!-- Material Design 3 - Roboto + Material Symbols -->
    <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,400&display=swap" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0,1" rel="stylesheet">

    <!-- Material Web Components (md-icon, md-icon-button) -->
    <script type="importmap">
    {
      "imports": {
        "@material/web/": "https://esm.run/@material/web/"
      }
    }
    </script>
    <script type="module">
    import 'https://esm.run/@material/web/icon/icon.js';
    import 'https://esm.run/@material/web/iconbutton/icon-button.js';
    </script>
<style>
        * { margin: 0; padding: 0; box-sizing: border-box; }

        :root {
            --md-primary: #0b57d0;
            --md-primary-container: #d3e3fd;
            --md-surface: #ffffff;
            --md-surface-variant: #e7e0ec;
            --md-on-surface: #1d1b20;
            --md-on-surface-variant: #49454f;
            --md-outline: #79747e;
            --md-surface-container: #f0f2f5;
            --md-secondary: #5f6368;
        }

        body {
            font-family: 'Roboto', system-ui, sans-serif;
            background: linear-gradient(145deg, #ffffff 0%, #f0f2f5 100%);
            color: var(--md-on-surface);
        }

        /* ── Top App Bar (MD3) ─────────────────────────────────── */
        .mat-top-app-bar {
            position: fixed;
            top: 0; left: 0; right: 0;
            height: 64px;
            background: var(--md-surface);
            box-shadow: 0 1px 3px rgba(0,0,0,0.12);
            display: flex;
            align-items: center;
            padding: 0 8px;
            gap: 8px;
            z-index: 100;
        }
        .mat-top-app-bar-title {
            flex: 1;
            font-size: 1.375rem;
            font-weight: 400;
            color: var(--md-on-surface);
            padding-left: 4px;
        }
        .mat-top-app-bar-trailing {
            display: flex;
            align-items: center;
            gap: 4px;
        }
        .mat-icon-btn {
            width: 48px; height: 48px;
            border-radius: 50%;
            border: none;
            background: transparent;
            cursor: pointer;
            display: flex; align-items: center; justify-content: center;
            transition: background 0.2s;
        }
        .mat-icon-btn:hover { background: rgba(11,87,208,0.08); }
        .mat-icon-btn .material-symbols-outlined { font-size: 24px; color: var(--md-on-surface-variant); }
        .spacer { height: 72px; }

        /* ── Page wrapper ──────────────────────────────────────── */
        .page-content { max-width: 1400px; margin: 0 auto; padding: 2.5rem 1.5rem; }

        /* ── Hero section ──────────────────────────────────────── */
        .hero { text-align: center; margin-bottom: 3rem; }
        .hero-chips { display: flex; justify-content: center; flex-wrap: wrap; gap: 8px; margin-bottom: 1rem; }
        .hero-badge {
            background: var(--md-primary-container);
            color: var(--md-primary);
            border-radius: 48px;
            padding: 0.4rem 1.2rem;
            font-weight: 500;
            font-size: 0.875rem;
            display: inline-flex; align-items: center; gap: 6px;
        }
        .headline-large {
            font-size: clamp(2rem, 5vw, 2.8rem);
            font-weight: 400;
            letter-spacing: -0.5px;
            background: linear-gradient(145deg, #0b47a0, #1766dc);
            background-clip: text;
            -webkit-background-clip: text;
            color: transparent;
            margin-bottom: 1rem;
        }
        .hero-desc {
            font-size: 1.1rem;
            color: var(--md-secondary);
            max-width: 700px;
            margin: 0 auto;
            line-height: 1.6;
        }
        .hero-desc code {
            background: #f1f3f4;
            padding: 0.1rem 0.4rem;
            border-radius: 12px;
            font-size: 0.875em;
        }
        .attr-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 1.5rem; }
        .badge-light {
            background: #e8eaed;
            color: #1a5c9e;
            font-size: 0.7rem;
            font-weight: 500;
            padding: 0.25rem 0.75rem;
            border-radius: 40px;
            display: inline-flex;
            align-items: center;
            gap: 4px;
        }
        .badge-light .material-symbols-outlined { font-size: 1rem; }

        /* ── Video grid ────────────────────────────────────────── */
        .video-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
            gap: 1.8rem;
        }
        .video-card {
            background: var(--md-surface);
            border-radius: 24px;
            overflow: hidden;
            transition: all 0.25s cubic-bezier(0.2, 0, 0, 1);
            box-shadow: 0 1px 2px rgba(0,0,0,0.05), 0 0 0 1px rgba(0,0,0,0.02);
        }
        .video-card:hover {
            transform: translateY(-4px);
            box-shadow: 0 12px 28px rgba(0,0,0,0.1), 0 0 0 1px rgba(11,87,208,0.1);
        }
        .card-header-md {
            padding: 0.75rem 1rem;
            background: #fafbfc;
            border-bottom: 1px solid #e9ecef;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .card-header-left { display: flex; align-items: center; gap: 8px; }
        .title-medium { font-size: 1rem; font-weight: 500; }
        .attr-chip {
            background: #f1f3f4;
            border-radius: 16px;
            padding: 0.2rem 0.65rem;
            font-family: 'Roboto Mono', monospace;
            font-size: 0.7rem;
            color: var(--md-primary);
        }
        .card-body-md { padding: 0.75rem; }
        .card-footer-md {
            padding: 0.75rem 1rem;
            background: var(--md-surface);
            border-top: 1px solid #e9ecef;
        }
        .card-meta { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 0.5rem; font-size: 0.8rem; color: var(--md-secondary); }
        .card-meta span { display: flex; align-items: center; gap: 4px; }
        .card-meta .material-symbols-outlined { font-size: 1rem; }
        .card-desc { font-size: 0.8rem; color: var(--md-secondary); margin: 0; }

        video {
            width: 100%;
            border-radius: 18px;
            background: #000;
            display: block;
        }

        /* ── Info card (MD3 Elevated) ──────────────────────────── */
        .mat-elevated-card {
            margin-top: 3rem;
            background: var(--md-surface);
            border-radius: 28px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 2px 8px rgba(0,0,0,0.06);
            padding: 1.8rem;
        }
        .info-card-header {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 1.25rem;
            flex-wrap: wrap;
        }
        .info-card-header .material-symbols-outlined {
            font-size: 2rem;
            color: var(--md-primary);
        }
        .info-card-header h2 { font-size: 1.375rem; font-weight: 500; }
        .attr-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 0.75rem;
            margin-bottom: 1rem;
        }
        .attr-item { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; }
        .attr-item .material-symbols-outlined { font-size: 1.25rem; color: var(--md-primary); }
        .attr-item code {
            background: #f1f3f4;
            padding: 0.1rem 0.4rem;
            border-radius: 12px;
            font-size: 0.8rem;
        }
        .info-divider { border: none; border-top: 1px solid #e2e8f0; margin: 1rem 0; }
        .info-note { display: flex; align-items: flex-start; gap: 6px; font-size: 0.8rem; color: var(--md-secondary); }
        .info-note .material-symbols-outlined { font-size: 1rem; flex-shrink: 0; margin-top: 2px; }

        /* ── Footer ────────────────────────────────────────────── */
        footer {
            margin-top: 3rem;
            padding: 2rem 0;
            text-align: center;
            border-top: 1px solid #dadce0;
            font-size: 0.8rem;
            color: var(--md-secondary);
        }

        /* ── Color helpers ─────────────────────────────────────── */
        .text-primary { color: var(--md-primary); }
        .text-success  { color: #1e8e3e; }
        .text-warning  { color: #e37400; }
        .text-danger   { color: #c5221f; }
        .text-info     { color: #0097a7; }

        @media (max-width: 768px) {
            .video-grid { grid-template-columns: 1fr; }
            .video-card { border-radius: 20px; }
        }
    </style>
</head>
<body>

    <!-- Top App Bar Material Design 3 -->
    <header class="mat-top-app-bar">
        <button class="mat-icon-btn" aria-label="Menu">
            <span class="material-symbols-outlined">menu</span>
        </button>
        <span class="mat-top-app-bar-title">Material Video Gallery</span>
        <div class="mat-top-app-bar-trailing">
            <button class="mat-icon-btn" aria-label="Mode jour">
                <span class="material-symbols-outlined">light_mode</span>
            </button>
            <button class="mat-icon-btn" aria-label="Plus d'options">
                <span class="material-symbols-outlined">more_vert</span>
            </button>
        </div>
    </header>

    <div class="spacer"></div>

    <div class="page-content">

        <!-- Hero -->
        <div class="hero">
            <div class="hero-chips">
                <span class="hero-badge"><span class="material-symbols-outlined">videocam</span> HTML5 Video</span>
                <span class="hero-badge"><span class="material-symbols-outlined">palette</span> Material Design 3</span>
                <span class="hero-badge"><span class="material-symbols-outlined">wb_sunny</span> Mode Jour / Light</span>
            </div>
            <h1 class="headline-large">5 expériences vidéo</h1>
            <p class="hero-desc">
                Toutes les options natives de la balise <code>&lt;video&gt;</code> : contrôles, autoplay, loop, muted, poster, preload, playsinline, Picture-in-Picture, pistes texte, controlslist.
                <br>Design clair et lumineux (thème jour) — inspiré Material You.
            </p>
            <div class="attr-chips">
                <span class="badge-light"><span class="material-symbols-outlined">play_circle</span> controls</span>
                <span class="badge-light"><span class="material-symbols-outlined">repeat</span> loop</span>
                <span class="badge-light"><span class="material-symbols-outlined">volume_off</span> muted autoplay</span>
                <span class="badge-light"><span class="material-symbols-outlined">image</span> poster</span>
                <span class="badge-light"><span class="material-symbols-outlined">picture_in_picture</span> PiP natif</span>
                <span class="badge-light"><span class="material-symbols-outlined">subtitles</span> pistes VTT</span>
            </div>
        </div>

        <!-- Video grid -->
        <div class="video-grid">

            <!-- CARTE 1 : Controls + Poster -->
            <div class="video-card">
                <div class="card-header-md">
                    <div class="card-header-left">
                        <span class="material-symbols-outlined text-primary">settings_overscan</span>
                        <h3 class="title-medium">Style 1 · Controls + Poster</h3>
                    </div>
                    <span class="attr-chip">controls poster</span>
                </div>
                <div class="card-body-md">
                    <video controls preload="metadata" poster="public/loader.gif">
                        <source src="public/video-robot.mp4" type="video/mp4">
                        <source src="public/video-robot.webm" type="video/webm">
                    </video>
                </div>
                <div class="card-footer-md">
                    <div class="card-meta">
                        <span><span class="material-symbols-outlined">check_circle</span> interface native</span>
                        <span><span class="material-symbols-outlined">wallpaper</span> poster image</span>
                    </div>
                    <p class="card-desc">Contrôles complets + affiche personnalisée avant lancement. Formats MP4 + WebM.</p>
                </div>
            </div>

            <!-- CARTE 2 : Autoplay muted loop -->
            <div class="video-card">
                <div class="card-header-md">
                    <div class="card-header-left">
                        <span class="material-symbols-outlined text-success">loop</span>
                        <h3 class="title-medium">Style 2 · Autoplay Muted Loop</h3>
                    </div>
                    <span class="attr-chip">autoplay muted loop</span>
                </div>
                <div class="card-body-md">
                    <video autoplay muted loop playsinline preload="auto">
                        <source src="public/video-robot.mp4" type="video/mp4">
                        <source src="public/video-robot.webm" type="video/webm">
                    </video>
                </div>
                <div class="card-footer-md">
                    <div class="card-meta">
                        <span><span class="material-symbols-outlined">volume_off</span> muet au départ</span>
                        <span><span class="material-symbols-outlined">all_inclusive</span> lecture en boucle</span>
                    </div>
                    <p class="card-desc">Parfait pour vidéo de fond / héros. Lecture automatique silencieuse.</p>
                </div>
            </div>

            <!-- CARTE 3 : Sous-titres + track VTT -->
            <div class="video-card">
                <div class="card-header-md">
                    <div class="card-header-left">
                        <span class="material-symbols-outlined text-warning">subtitles</span>
                        <h3 class="title-medium">Style 3 · Piste texte WebVTT</h3>
                    </div>
                    <span class="attr-chip">&lt;track&gt; subtitles</span>
                </div>
                <div class="card-body-md">
                    <video controls preload="auto" crossorigin="anonymous">
                        <source src="public/video-robot.mp4" type="video/mp4">
                        <source src="public/video-robot.webm" type="video/webm">
                        <!--track src="public/cc-subtitles.vtt" kind="subtitles" srclang="en" label="English CC" default-->
                    </video>
                </div>
                <div class="card-footer-md">
                    <div class="card-meta">
                        <span><span class="material-symbols-outlined">closed_caption</span> sous-titres inclus</span>
                        <span><span class="material-symbols-outlined">data_usage</span> preload="auto"</span>
                    </div>
                    <p class="card-desc">Fichier WebVTT externe, activez les sous-titres via le bouton CC.</p>
                </div>
            </div>

            <!-- CARTE 4 : controlslist restreint -->
            <div class="video-card">
                <div class="card-header-md">
                    <div class="card-header-left">
                        <span class="material-symbols-outlined text-danger">lock</span>
                        <h3 class="title-medium">Style 4 · Contrôles restreints</h3>
                    </div>
                    <span class="attr-chip">controlslist</span>
                </div>
                <div class="card-body-md">
                    <video controls controlslist="nodownload nofullscreen" poster="public/loader.gif" preload="metadata">
                        <source src="public/video-robot.mp4" type="video/mp4">
                        <source src="public/video-robot.webm" type="video/webm">
                    </video>
                </div>
                <div class="card-footer-md">
                    <div class="card-meta">
                        <span><span class="material-symbols-outlined">do_not_disturb</span> sans téléchargement</span>
                        <span><span class="material-symbols-outlined">fullscreen_exit</span> fullscreen désactivé</span>
                    </div>
                    <p class="card-desc">Interface désactivée pour certaines options, poster haute résolution.</p>
                </div>
            </div>

            <!-- CARTE 5 : Picture-in-Picture -->
            <div class="video-card">
                <div class="card-header-md">
                    <div class="card-header-left">
                        <span class="material-symbols-outlined text-info">picture_in_picture</span>
                        <h3 class="title-medium">Style 5 · Picture-in-Picture</h3>
                    </div>
                    <span class="attr-chip">PiP · autoplay muted</span>
                </div>
                <div class="card-body-md">
                    <video id="pipMaterialVideo" controls autoplay muted playsinline preload="metadata">
                        <source src="public/video-robot.mp4" type="video/mp4">
                        <source src="public/video-robot.webm" type="video/webm">
                    </video>
                </div>
                <div class="card-footer-md">
                    <div class="card-meta">
                        <span><span class="material-symbols-outlined">picture_in_picture_alt</span> bouton PiP natif</span>
                        <span><span class="material-symbols-outlined">touch_app</span> utilisateur peut activer son</span>
                    </div>
                    <p class="card-desc">Picture-in-Picture disponible sur Chrome, Edge, Safari. Démarrage muet.</p>
                </div>
            </div>

        </div>

        <!-- Info card Material Elevated -->
        <div class="mat-elevated-card">
            <div class="info-card-header">
                <span class="material-symbols-outlined">code_blocks</span>
                <h2>Tous les attributs de la balise &lt;video&gt;</h2>
            </div>
            <div class="attr-grid">
                <div class="attr-item"><span class="material-symbols-outlined">play_circle</span> <code>src</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">tune</span> <code>controls</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">play_arrow</span> <code>autoplay</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">repeat</span> <code>loop</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">volume_off</span> <code>muted</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">image</span> <code>poster</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">downloading</span> <code>preload</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">smartphone</span> <code>playsinline</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">public</span> <code>crossorigin</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">lock_open</span> <code>controlslist</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">picture_in_picture</span> <code>disablePictureInPicture</code></div>
                <div class="attr-item"><span class="material-symbols-outlined">subtitles</span> <code>&lt;track&gt;</code> (VTT)</div>
            </div>
            <hr class="info-divider">
            <p class="info-note">
                <span class="material-symbols-outlined">info</span>
                Ces 5 démonstrations couvrent tous les cas d'usage : interface standard, boucle muette automatique, sous-titres, restrictions d'UI, et Picture-in-Picture. Design inspiré de Material Design 3 — Mode clair (jour) avec couleurs apaisantes.
            </p>
        </div>

        <footer>
            <p>© 2025 — Démo éducative des attributs vidéo HTML5.</p>
        </footer>
    </div>

    <script>
        const allVideos = document.querySelectorAll('video');
        allVideos.forEach((vid, idx) => {
            vid.addEventListener('play', () => console.info(`🎬 [Material] Vidéo ${idx+1} lecture`));
            vid.addEventListener('pause', () => console.info(`⏸️ [Material] Vidéo ${idx+1} pause`));
            vid.addEventListener('volumechange', () => {
                if (!vid.muted && vid.volume > 0) console.info(`🔊 [Material] Vidéo ${idx+1} volume: ${vid.volume}`);
                else if (vid.muted) console.info(`🔇 [Material] Vidéo ${idx+1} muette`);
            });
            if (vid.id === 'pipMaterialVideo') {
                vid.addEventListener('enterpictureinpicture', () => console.info('📺 Material PiP activé'));
                vid.addEventListener('leavepictureinpicture', () => console.info('🖥️ Sortie PiP Material'));
            }
        });
        document.querySelectorAll('video[autoplay]').forEach(v => v.play().catch(() => {}));
        // console.info('✨ Material Design 3 - mode jour lumineux, 5 styles vidéo avec contrôles, attributs complets.');
    </script>
</body>
</html>

Télécharger le fichier source

Partager