Das Ändern spezifischer Zeichen kann eine Herausforderung in CSS sein. Oft sind wir gezwungen, unsere gewünschten Änderungen einzeln in HTML zu implementieren, vielleicht mit dem span-Element. Aber in einigen spezifischen Fällen kann eine CSS-zentrierte Lösung immer noch möglich sein. In diesem Artikel werden wir zunächst einige CSS-first-Ansätze zur Änderung von Zeichen betrachten, bevor wir ein Szenario betrachten, in dem wir zu JavaScript greifen müssen.
CSS
Derzeit glänzt CSS nicht darin, spezifische Zeichen anzusprechen, ohne Änderungen am HTML vorzunehmen. Es gibt jedoch einige Szenarien, in denen CSS die bevorzugte Wahl sein könnte.
@font-face
Die Regel @font-face wird regelmäßig verwendet, um benutzerdefinierte Schriftarten zu erstellen, aber ihre Eigenschaft unicode-range kann uns auch erlauben, spezifische Zeichen anzusprechen.
Stellen Sie sich zum Beispiel vor, unsere Website enthält häufig kaufmännische Und-Zeichen in ihren Überschriften. Anstatt die Überschriften-Schriftart zu verwenden, wünschen wir uns etwas Flamboyanteres. Wir können den Unicode-Wert eines kaufmännischen Und-Zeichens (U+0026) nachschlagen und unicode-range verwenden, um dieses spezifische Zeichen anzusprechen.
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300');
h1, h2, h3, h4, h5, h6 {
font-family: 'Ampersand', Montserrat, sans-serif;
}
@font-face {
font-family: 'Ampersand';
src: local('Times New Roman');
unicode-range: U+0026;
}
Probieren Sie dies mit dem folgenden HTML aus, um es in Aktion zu sehen
<h1>Jane Austen Novels</h1>
<h2>Pride & Prejudice</h2>
<h2>Sense & Sensibility</h2>
::first-letter
Das Pseudo-Element ::first-letter wurde hauptsächlich für den Einsatz von Initialen konzipiert und wird von allen gängigen Browsern unterstützt.
p::first-letter {
font-size: 125%;
font-weight: bold;
}
Dies ist natürlich nur in einer relativ begrenzten Anzahl von Szenarien nützlich. Es gab mehrere Forderungen nach einem ::nth-letter Pseudo-Element (einschließlich hier auf CSS-Tricks), aber im Moment ist das nur ein Hirngespinst!
::after
Mit dem Pseudo-Element ::after und der Eigenschaft content können wir einen ähnlichen Effekt für das letzte Zeichen erzielen – solange dieses Zeichen immer dasselbe ist. Zum Beispiel, so könnten wir ein schnittiges, kursiv geschriebenes Ausrufezeichen nach jedem h2-Element hinzufügen
h2::after {
content: '\0021';
color: red;
font-style: italic;
}
font-variant-alternates
Schließlich gibt es noch die Eigenschaft font-variant-alternates. Diese wird *nur von Firefox unterstützt*, daher wird sie für den Produktionseinsatz nicht empfohlen, aber sie kann für sehr spezifische Szenarien nützlich sein: Wenn eine Schriftart zufällig alternative Glyphen enthält, können wir diese Eigenschaft mit der Funktion character-variant() verwenden, um eine bevorzugte Glyphe für ein Zeichen unserer Wahl auszuwählen.
JavaScript
Der Übergang zu JavaScript muss nicht auf Kosten der Leistung gehen, insbesondere wenn wir HTML-verändernde Funktionen zur Build-Zeit ausführen. Der häufigste Anwendungsfall ist wahrscheinlich das Suchen und Ersetzen spezifischer Zeichen in unserem HTML durch ein span-Element. Der Einfachheit halber beginne ich mit einem Beispiel auf der Client-Seite, und danach werden wir uns ansehen, wie wir dies zur Build-Zeit mit webpack ausführen können.
Finden und Ersetzen zur Laufzeit
Stellen wir uns vor, dass wir jedes Mal, wenn wir den Text "LOGO" in einer Kopfzeile auf unserer Website haben, einen speziellen Stil auf das erste "O" Zeichen anwenden möchten, indem wir es in ein span-Element mit der Klasse .special-o einschließen.
const headings = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
for (const heading of headings) {
heading.innerHTML = heading.innerHTML
.replace(/\bLOGO\b/g, 'L<span class="special-o">O</span>GO');
}
Im obigen JavaScript führen wir ein Finden und Ersetzen in jedem Kopfzeilen-Tag durch.
Unser regulärer Ausdruck verwendet das Metazeichen \b, um sicherzustellen, dass LOGO immer ein Wort ist – und nicht Teil eines größeren Wortes. Zum Beispiel wollen wir nicht die Pluralform „LOGOS“ abgleichen. Derzeit wäre es mit CSS unmöglich, dies zu tun, nicht zuletzt, weil wir nur das erste "O" in der Sequenz ansprechen wollen.
Das gleiche Prinzip gilt, wenn wir das "O" – oder sogar das ganze Wort "LOGO" – durch ein Bild ersetzen wollen.
Finden und Ersetzen zur Build-Zeit
Es gibt viele Build-Tools, aber da webpack sehr beliebt ist, verwenden wir es für unser Beispiel – und glücklicherweise gibt es ein Plugin für das, was wir brauchen, namens string-replace-loader. Für diejenigen, die neu bei webpack sind, wird ein Loader zum Vorverarbeiten von Dateien verwendet. Hier können wir als Teil unseres Builds ein Suchen und Ersetzen in spezifischen Dateien durchführen.
Zuerst müssen wir das Plugin installieren
npm install --save-dev string-replace-loader
Dann fügen Sie in webpack.config.js hinzu
module.exports = {
// ...
module: {
rules: [
{
test: /\.html$/i,
loader: 'string-replace-loader',
options: {
search: '/\bLOGO\b/g',
replace: 'L<span class="special-o">O</span>GO',
}
}
]
}
}
Durch Ändern des Werts der Eigenschaft test könnten wir JSX, TSX, PUG, Handlebars oder jedes andere Template-Dateiformat ansprechen
/\.html$/i # HTML
/\.[jt]sx$/i # JSX or TSX
/\.pug$/i # PUG
/\.handlebars$/i # Handlebars
Der Vorteil dieses Ansatzes ist, dass kein unnötiger JavaScript im Browser unseres Clients ausgeführt wird.
Abschließender Hinweis
Wenn Sie schließlich mit der Erstellung und Bearbeitung von Schriftarten vertraut sind und CSS oder JavaScript vermeiden möchten, könnte eine benutzerdefinierte Schriftart eine Lösung für viele der oben genannten Szenarien sein. Es gibt viele kostenlose Schriftartenbearbeitungswerkzeuge wie Font Forge oder Birdfont für diejenigen, die diesen designorientierteren Ansatz ausprobieren möchten.
Ich hatte vorher nicht an font-face mit unicode-range gedacht, das gefällt mir!
Ein CodePen-Demo wäre aber ideal!
Hallo Alistair, danke für das Feedback! Hier ist eine CodePen-Demo mit dem Beispiel aus dem Artikel: https://codepen.io/BretCameron/pen/NWNpbrW.
Danke für die Aktualisierung.
Sehr erfinderisch
Danke für den Artikel! Aber nach meinen Erfahrungen funktioniert ::first-letter nicht bei Inline-Elementen. Manchmal funktioniert es nicht, wenn ich dynamische Änderungen auf der Seite vornehme. Es funktioniert erst wieder, wenn ich die Seite aktualisiere.
Hallo Yiding, wenn Sie auf druckformatierte Initialen abzielen, versuchen Sie,
::first-lettermitfloat: leftzu verwenden. Ich habe ein einfaches CodePen erstellt, um diesen Effekt zu demonstrieren: https://codepen.io/BretCameron/pen/mdPKQpy.Hallo Bret! Der Beitrag hat mir gefallen. Kannst du ihn modifizieren, ohne reguläre Ausdrücke zu verwenden?
Danke! Ja, die Funktion
replacekann einen einfachen String akzeptieren, und das gilt auch für die Optionsearchvonstring-replace-loader.