content
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.
- Syntax
- content: normal | none | <string> | attr() | url() | counter() | open-quote | close-quote
- Initialwert
- normal
- Vererbt
- Nein
- Animierbar
- Nein
- Kategorie
- Display & Sichtbarkeit
- Werte
- 7
- Beispiele
- 5
- Browser
- 5 von 5
- 2 von 5
- Stand
- 15.02.2026
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
7 WerteMehrere Werte lassen sich kombinieren: content: "Kapitel " counter(chapter) ": " erzeugt z.B. “Kapitel 3: ”.
Beispiele
5 BeispieleEin 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> 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> 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> 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> 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
5 Fehler 01 content vergessen bei ::before/::after
content wird das Pseudo-Element nicht gerendert. Selbst für rein dekorative Elemente brauchst du mindestens content: "". 02 Wichtigen Inhalt mit content erzeugen
03 content auf normalen Elementen setzen
content funktioniert nur auf ::before und ::after. Auf einem <div> oder <span> hat es keine Wirkung (außer bei Elementen mit display: contents, wo es den Inhalt ersetzt). 04 Anführungszeichen vergessen bei Strings
content: Hallo ist ungültig. Strings müssen in Anführungszeichen stehen: content: "Hallo". 05 Pseudo-Elemente auf void-Elemente
<img>, <input> und <br> können keine ::before/::after Pseudo-Elemente haben, weil sie keinen Inhalt enthalten können. Browser-Kompatibilität
5 von 5content wird von allen modernen Browsern vollständig unterstützt, inklusive attr(), counter() und url().
-
Chrome
Komplett
-
Firefox
Komplett
-
Safari
Komplett
-
Edge
Komplett
-
Opera
Komplett
Email-Kompatibilität
2 von 5content und Pseudo-Elemente werden in HTML-Emails kaum unterstützt. Verwende stattdessen echte HTML-Elemente.
-
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
Newsletter
einmal die Woche, kostenlosNeue Artikel und Videos, was sich auf der Lernplattform tut, und ab und zu ein Sonderpreis zum Kursstart. Kurz genug, dass du es auch liest.
Zuletzt verschickt · KW 40
Einmal alles neu, und die Lernplattform ist da