Start · Sprachen · JavaScript · Referenz · HTMLSourceElement.srcset

HTMLSourceElement.srcset

Eigenschaft

Liest oder setzt die kommagetrennte Liste von Bildkandidaten eines <code>&lt;source&gt;</code>-Elements innerhalb von <code>&lt;picture&gt;</code> und spiegelt das HTML-Attribut <code>srcset</code>.

seit JavaScript Baseline: alle modernen Browser Kategorie: webapi

Signatur

HTMLSourceElement.srcset

Beschreibung

Die Eigenschaft srcset des HTMLSourceElement-Interfaces spiegelt das gleichnamige HTML-Attribut wider. Sie enthält einen String mit einer kommagetrennten Liste von Bildkandidaten. Jeder Kandidat besteht aus einer URL und optional einem Deskriptor: entweder einer Breitenangabe (480w) oder einer Pixeldichte (2x). Ohne Deskriptor gilt 1x.

Relevant ist srcset nur, wenn das <source>-Element in einem <picture>-Element steht. Dort wählt der Browser anhand von media, type und sizes die erste passende Quelle aus und sucht sich aus deren srcset den geeignetsten Kandidaten aus. Bei <source> innerhalb von <audio> oder <video> wird stattdessen src verwendet, srcset hat dort keine Wirkung.

Nutzen Sie die Eigenschaft, um responsive Bilder dynamisch per JavaScript aufzubauen oder zu ändern, etwa beim Nachladen hochauflösender Varianten, beim Umschalten zwischen Bildformaten (AVIF, WebP) oder beim eigenen Lazy Loading. Welcher Kandidat tatsächlich geladen wurde, verrät nicht srcset, sondern HTMLImageElement.currentSrc des zugehörigen <img>.

Parameter

Name Typ Default Beschreibung
$value string "" Beim Setzen: kommagetrennte Liste von Kandidaten im Format URL [Deskriptor], z. B. "bild-480.webp 480w, bild-960.webp 960w". Wird unverändert ins Attribut geschrieben.

Rückgabewert

Typ
string
Beschreibung
Der aktuelle Wert des Attributs srcset genau so, wie er im HTML steht (URLs werden nicht zu absoluten URLs aufgelöst). Leerer String, wenn das Attribut fehlt.

Beispiele

srcset auslesen

// HTML:
// <picture>
//   <source id="webp" type="image/webp" srcset="foto-480.webp 480w, foto-960.webp 960w" sizes="(max-width: 600px) 100vw, 50vw">
//   <img src="foto-960.jpg" alt="Foto">
// </picture>
const source = document.querySelector('#webp');
console.log(source.srcset);

// Kandidaten zerlegen
const kandidaten = source.srcset.split(',').map((eintrag) => {
  const [url, deskriptor = '1x'] = eintrag.trim().split(/\s+/);
  return { url, deskriptor };
});
console.log(kandidaten);
foto-480.webp 480w, foto-960.webp 960w [{ url: 'foto-480.webp', deskriptor: '480w' }, { url: 'foto-960.webp', deskriptor: '960w' }]

<picture> mit AVIF/WebP-Quellen dynamisch erzeugen

const erstelleBild = (basis, alt) => {
  const picture = document.createElement('picture');
  const breiten = [480, 960, 1440];

  for (const format of ['avif', 'webp']) {
    const source = document.createElement('source');
    source.type = `image/${format}`;
    source.srcset = breiten.map((w) => `${basis}-${w}.${format} ${w}w`).join(', ');
    source.sizes = '(max-width: 800px) 100vw, 800px';
    picture.append(source);
  }

  const img = document.createElement('img');
  img.src = `${basis}-960.jpg`;
  img.alt = alt;
  picture.append(img);
  return picture;
};

const bild = erstelleBild('/img/berge', 'Bergpanorama');
document.body.append(bild);
console.log(bild.querySelector('source').srcset);
/img/berge-480.avif 480w, /img/berge-960.avif 960w, /img/berge-1440.avif 1440w

Lazy Loading mit data-srcset und IntersectionObserver

// <source data-srcset="karte.webp 1x, karte@2x.webp 2x" type="image/webp">
const observer = new IntersectionObserver((eintraege, obs) => {
  for (const { isIntersecting, target } of eintraege) {
    if (!isIntersecting) continue;
    target.querySelectorAll('source[data-srcset]').forEach((source) => {
      source.srcset = source.dataset.srcset;
      source.removeAttribute('data-srcset');
    });
    const img = target.querySelector('img');
    img.addEventListener('load', () => console.log('Geladen:', img.currentSrc), { once: true });
    if (img.dataset.src) img.src = img.dataset.src;
    obs.unobserve(target);
  }
});

document.querySelectorAll('picture.lazy').forEach((p) => observer.observe(p));
Geladen: https://example.com/karte@2x.webp

// Wichtig · Fallstricke

  • Nur in <picture> wirksam: In <video>/<audio> wird srcset ignoriert – dort src verwenden.
  • Keine Mischung von Deskriptoren: Innerhalb einer Liste entweder nur w- oder nur x-Deskriptoren verwenden. Bei w-Deskriptoren sollte immer sizes gesetzt sein, sonst nimmt der Browser 100vw an.
  • Kommas in URLs: URLs mit Kommas (z. B. bei manchen CDN-Parametern) können das Parsen stören; solche Zeichen URL-kodieren (%2C). Ein einfaches split(',') ist dann ebenfalls unzuverlässig.
  • Reihenfolge beim Setzen: Ändert man srcset an einer <source>, wird die Bildauswahl des zugehörigen <img> neu ausgewertet. Beim Aufbau per Skript srcset, sizes und type möglichst setzen, bevor das Element eingefügt wird, um doppelte Downloads zu vermeiden.
  • Welche Datei geladen wurde: Der Browser entscheidet selbst (Viewport, Pixeldichte, Datensparmodus, Cache). Das tatsächliche Ergebnis liefert img.currentSrc, nicht source.srcset.
  • Sicherheit: Werte aus Benutzereingaben vor dem Setzen validieren; externe Bild-URLs können Tracking ermöglichen und unterliegen der CSP-Direktive img-src.
  • Kompatibilität: In allen modernen Browsern unterstützt; der Internet Explorer kennt <picture> nicht und fällt auf das <img> zurück.