content
Zuletzt aktualisiert am 15. Februar 2026
content erzeugt Inhalte über die Pseudo-Elemente ::before und ::after, ohne das HTML zu verändern. Damit fügst du dekorative Elemente wie Icons, Sterne für Pflichtfelder oder automatische Nummerierungen ein. Wichtig: Generated Content gehört nicht zum DOM und wird von Screenreadern unterschiedlich behandelt. Verwende content nur für dekorative Zwecke und nie für inhaltlich relevante Informationen.
content: normal | none | <string> | attr() | url() | counter() | open-quote | close-quote normal Grundlagen
Pseudo-Elemente ::before und ::after erzeugen ein zusätzliches Element als erstes bzw. letztes Kind des Elements. Damit sie erscheinen, brauchen sie zwingend die content-Eigenschaft. Selbst wenn der Inhalt leer sein soll, muss content: "" gesetzt werden.
Der erzeugte Inhalt ist standardmäßig ein Inline-Element. Du kannst ihn mit display: block oder display: inline-block umformatieren und wie jedes andere Element mit Padding, Margin, Hintergrund und Rahmen stylen.
Ein zentraler Punkt: Generated Content existiert nicht im HTML-DOM. Du kannst ihn nicht mit JavaScript selektieren, er wird nicht von der Textauswahl erfasst, und Screenreader behandeln ihn inkonsistent. Manche lesen ihn vor, manche ignorieren ihn. Deswegen gilt: Nur dekorativen Inhalt mit content erzeugen.
Syntax & Werte
| Wert | Beschreibung | Beispiel |
|---|---|---|
normal | Für ::before und ::after: Kein Pseudo-Element wird erzeugt. (Standard) | content: normal |
none | Pseudo-Element wird nicht erzeugt oder ein bestehendes wird entfernt. | content: none |
"text" | Fügt den angegebenen Text ein. Mehrere Strings und Funktionen können kombiniert werden. | content: "→ " |
attr(name) | Fügt den Wert eines HTML-Attributs ein. | content: attr(data-label) |
url(pfad) | Fügt ein Bild oder eine Ressource ein. | content: url("icon.svg") |
counter(name) | Gibt den Wert eines CSS-Counters aus. Nützlich für automatische Nummerierungen. | content: counter(section) |
open-quote / close-quote | Fügt Anführungszeichen basierend auf der quotes-Eigenschaft ein. | content: open-quote |
Mehrere Werte lassen sich kombinieren: content: "Kapitel " counter(chapter) ": " erzeugt z.B. “Kapitel 3: ”.
Beispiele
Dekorativer Pfeil vor Links
Ein häufiges Muster: Ein kleines Symbol vor oder nach einem Element einfügen.
.arrow-link::before {
content: "→ ";
color: #059669;
}<div class="link-demo">
<a href="#" class="arrow-link">Zum nächsten Artikel</a>
<a href="#" class="arrow-link">Dokumentation lesen</a>
<a href="#" class="arrow-link">Beispiele ansehen</a>
</div>Pflichtfeld-Stern bei Formularen
Der rote Stern nach Pflichtfeld-Labels ist ein klassischer Anwendungsfall für ::after.
.required::after {
content: " *";
color: #dc2626;
}<div class="form-demo">
<div class="form-group">
<label class="form-label required">Name</label>
<input class="form-input" type="text" placeholder="Max Mustermann">
</div>
<div class="form-group">
<label class="form-label required">Email</label>
<input class="form-input" type="email" placeholder="max@beispiel.de">
</div>
<div class="form-group">
<label class="form-label">Nachricht (optional)</label>
<input class="form-input" type="text" placeholder="Deine Nachricht">
</div>
</div>Externe Links kennzeichnen
Zeige bei externen Links automatisch ein Hinweis-Symbol an. Der Attribut-Selektor erkennt Links, die mit http beginnen.
/* Links die mit http beginnen */
a[href^="http"]::after {
content: " ↗";
font-size: 0.85em;
color: #6b7280;
}<div class="ext-demo">
<p><a href="#">Interner Link</a> hat kein Symbol.</p>
<p><a href="https://example.com">Externer Link</a> bekommt ein Symbol.</p>
<p><a href="https://developer.mozilla.org">MDN Web Docs</a> bekommt auch eins.</p>
</div>Attribut-Werte mit attr() anzeigen
attr() liest den Wert eines HTML-Attributs und fügt ihn als Text ein. Praktisch für Tooltips oder Daten-Labels.
.tooltip::after {
content: attr(data-tooltip);
position: absolute;
top: calc(100% + 6px);
background: #1e293b;
color: white;
padding: 4px 10px;
border-radius: 4px;
opacity: 0;
transition: opacity 0.2s;
}
.tooltip:hover::after {
opacity: 1;
}<div class="attr-demo">
<span class="tooltip-trigger" data-tooltip="Hypertext Markup Language">HTML</span>
<span class="tooltip-trigger" data-tooltip="Cascading Style Sheets">CSS</span>
<span class="tooltip-trigger" data-tooltip="JavaScript">JS</span>
</div>Custom List Bullets
Ersetze die Standard-Aufzählungszeichen durch eigene Symbole mit ::before.
.custom-list {
list-style: none;
padding: 0;
}
.custom-list li {
padding-left: 24px;
position: relative;
}
.custom-list li::before {
content: "✓";
position: absolute;
left: 0;
color: #059669;
font-weight: bold;
}<ul class="custom-list">
<li>Responsive Design umsetzen</li>
<li>Accessibility prüfen</li>
<li>Performance optimieren</li>
<li>Cross-Browser testen</li>
</ul>Barrierefreiheit
Generated Content via content ist für Screenreader unzuverlässig. Das Verhalten variiert stark zwischen Screenreadern und Browsern: Manche lesen content: "text" vor, andere ignorieren es komplett. Du darfst dich nicht darauf verlassen, dass assistive Technologien den Inhalt erfassen.
Verwende content nur für dekorative Zwecke. Pfeile, Trennzeichen, Ornamente und visuelle Hinweise sind in Ordnung. Aber niemals wichtige Informationen wie Preise, Statusmeldungen oder Anleitungen in Pseudo-Elementen verstecken. Diese Inhalte müssen im echten HTML-DOM stehen.
Der Pflichtfeld-Stern ist ein Sonderfall: content: " *" für Pflichtfelder ist akzeptabel, aber nur in Kombination mit dem required-Attribut am Input-Element und optionalem aria-required="true". Der Stern ist dann rein visuell, die Pflicht-Information kommt aus dem HTML.
attr() für semantische Inhalte ist riskant. Während content: attr(data-tooltip) technisch funktioniert, sollten wichtige Tooltips stattdessen über aria-label, aria-describedby oder echte HTML-Elemente mit passenden ARIA-Rollen bereitgestellt werden. Die WCAG 1.3.1 (Info and Relationships) fordert, dass Informationen programmatisch verfügbar sind.
Alt-Texte in content: url() funktionieren nicht verlässlich. Die Syntax content: url(icon.svg) / "Beschreibung" hat nur sehr begrenzte Browser-Unterstützung. Verwende für Icons stattdessen SVG direkt im HTML mit <title> oder echte <img>-Elemente mit alt-Attribut.
Häufige Fehler
contentvergessen bei::before/::after: Ohnecontentwird das Pseudo-Element nicht gerendert. Selbst für rein dekorative Elemente brauchst du mindestenscontent: "".- Wichtigen Inhalt mit
contenterzeugen: Generated Content ist nicht Teil des DOM, wird von der Textauswahl ausgeschlossen und von Screenreadern inkonsistent behandelt. Verwende ihn nur für Dekoration, nie für inhaltlich relevante Informationen. contentauf normalen Elementen setzen:contentfunktioniert nur auf::beforeund::after. Auf einem<div>oder<span>hat es keine Wirkung (außer bei Elementen mitdisplay: contents, wo es den Inhalt ersetzt).- Anführungszeichen vergessen bei Strings:
content: Halloist ungültig. Strings müssen in Anführungszeichen stehen:content: "Hallo". - Pseudo-Elemente auf void-Elemente:
<img>,<input>und<br>können keine::before/::afterPseudo-Elemente haben, weil sie keinen Inhalt enthalten können.
Browser-Kompatibilität
content wird von allen modernen Browsern vollständig unterstützt, inklusive attr(), counter() und url().
| Client | Unterstützung | Hinweise |
|---|---|---|
| Chrome | Komplett | — |
| Firefox | Komplett | — |
| Safari | Komplett | — |
| Edge | Komplett | — |
| Opera | Komplett | — |
Email-Kompatibilität
content und Pseudo-Elemente werden in HTML-Emails kaum unterstützt. Verwende stattdessen echte HTML-Elemente.
| Client | Unterstützung | Hinweise |
|---|---|---|
| Apple Mail | Komplett | — |
| Gmail | Keine | Gmail entfernt ::before und ::after Pseudo-Elemente komplett |
| Outlook | Keine | Outlook unterstützt keine Pseudo-Elemente |
| Thunderbird | Komplett | — |
| Yahoo Mail | Keine | Pseudo-Elemente werden nicht unterstützt |
Verwandte Eigenschaften
Bleib auf dem Laufenden
Erhalte neue Inhalte direkt in dein Postfach
Was erwartet dich?
Neue Artikel & Videos
Wenn ich was Neues veröffentliche, erfährst du's hier zuerst.
Plattform & Kurs-Updates
Neue Kurse, Referenz-Updates und gelegentlich Sonderpreise zum Launch.
Einmal die Woche in deinem Postfach
Kurz, auf den Punkt, kein Spam.