Erstellen von benutzerdefinierten Emmet-Snippets in VS-Code

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ In diesem Artikel erklärt Manuel, warum Emmet eines seiner bevorzugten Produktivitätstools zum Schreiben von HTML und CSS ist und wie Sie benutzerdefinierte Emmet-Snippets in Visual Studio Code erstellen können, um Ihre Front-End-Workflows noch weiter zu verbessern.

Anfang dieses Jahres habe ich die HTML-Boilerplate, die ich gerne verwende, wenn ich neue Webprojekte beginne, mit zeilenweisen Erklärungen in meinem Blog geteilt. Es ist eine Sammlung von hauptsächlich <head> -Tags und Attributen, die ich normalerweise auf jeder Website verwende, die ich erstelle. Bis vor kurzem habe ich die Boilerplate einfach kopiert und eingefügt, wann immer ich sie brauchte, aber ich habe mich entschieden, meinen Workflow zu verbessern, indem ich sie als Snippet zu VS Code hinzugefügt habe – dem Editor meiner Wahl.

Hier ist eine kurze Demo der benutzerdefinierten Snippets, die ich erstellt habe.

Ausschnitte und Abkürzungen in Visual Studio-Code

VS Code ist mit benutzerdefinierten Benutzer-Snippets sowie HTML- und CSS-Snippets und Abkürzungen von Emmet integriert.

Wenn Sie beispielsweise p>a{Sign Up} in ein HTML-Dokument eingeben und die Eingabetaste oder die Tabulatortaste drücken, wandelt Emmet es in das folgende Markup um:

 <p><a href="">Sign Up</a></p>

Hinweis : Besuchen Sie die Emmet-Dokumentation, um zu erfahren, wie Sie die Abkürzungssyntax verwenden.

Wenn wir diese spezifische Abkürzung regelmäßig benötigen, können wir sie als Snippet speichern, um unseren Workflow noch weiter zu verbessern.

 { "html": { "snippets": { "signup": "p>a{Sign Up}" } } }

Jetzt können wir signup und die Eingabetaste oder die Tabulatortaste drücken, und wir erhalten dasselbe Ergebnis. Wie man Snippets erstellt, erkläre ich im nächsten Abschnitt.

Emmet wird standardmäßig mit einer Reihe von HTML-Snippets geliefert. Zum Beispiel ! erstellt die Grundstruktur eines HTML-Dokuments.

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> </body> </html>

Das ist großartig, aber wenn wir dieses Snippet anpassen wollen, indem wir Elemente und Attribute entfernen oder hinzufügen, müssen wir es überschreiben und ein eigenes Snippet erstellen.

Snippets erstellen und überschreiben

Wenn wir eigene Emmet-Snippets erstellen oder bestehende in VS Code überschreiben wollen, sind folgende Schritte notwendig:

  1. Erstellen Sie eine snippets.json -Datei, fügen Sie diese grundlegende JSON-Struktur hinzu und speichern Sie sie irgendwo auf Ihrer Festplatte.
     { "html": { "snippets": { } }, "css": { "snippets": { } } }
  2. Öffnen Sie die VS Code-Einstellungen (Code → Einstellungen → Einstellungen) und suchen Sie nach „Emmet Extensions Path“.
  3. Klicken Sie auf „Element hinzufügen“, geben Sie den Pfad zu dem Ordner ein, in dem Sie die zuvor erstellte Datei „ snippets.json “ gespeichert haben, und klicken Sie auf „OK“.

Das ist es. Jetzt können wir Snippets erstellen, indem wir Eigenschaften zu den html und css -Objekten hinzufügen, wobei der key der Name des Snippets und der value eine Abkürzung oder eine Zeichenfolge ist.

Einige meiner benutzerdefinierten HTML-Snippets

Bevor wir tief in die Snippet-Erstellung eintauchen und ich Ihnen zeige, wie ich ein Snippet für meine HTML-Boilerplate erstellt habe, wollen wir uns zuerst mit einigen kleinen, aber nützlichen Snippets aufwärmen, die ich ebenfalls erstellt habe.

Faules Laden

Standardmäßig gibt es eine img -Abkürzung, aber keine für faul geladene Bilder. Wir können die Standardabkürzung verwenden und einfach die zusätzlichen Attribute und Attributwerte hinzufügen, die wir in eckigen Klammern benötigen.

 { "html": { "snippets": { "img:l": "img[width height loading='lazy']" } } }

img:l + Enter / Tab erzeugt nun folgendes Markup:

 <img src="" alt="" width="" height="" loading="lazy">

Buchseite

Die meisten Seiten, die ich erstelle, bestehen aus <header> , <main> und <footer> Landmarks und einem <h1> . Mit der benutzerdefinierten page kann ich diese Struktur schnell erstellen.

 "snippets": { "page": "header>h1^main+footer{${0:©}}" }

page + Enter / Tab erstellt das folgende Markup:

 <header> <h1></h1> </header> <main></main> <footer>©</footer>

Diese Abkürzung ist ziemlich lang, also teilen wir sie in kleinere Teile auf.

Nervenzusammenbruch

Erstellen Sie ein <header> -Element und ein untergeordnetes <h1> .

 header>h1

Gehen Sie nach oben, zurück zur Ebene von <header> und erstellen Sie eine <footer> , die auf <main> folgt.

 ^main+footer

Setzen Sie den letzten Tabstopp innerhalb der <footer> und setzen Sie den Standardtext auf &copy .

 {${0:©}}

Navigation

Die Abkürzung nav erstellt standardmäßig nur ein <nav> Start- und End-Tag, aber was ich normalerweise brauche, ist ein <nav> mit verschachtelten <ul> , <li> Elementen und Links ( <a> ). Wenn es auf einer Seite mehrere <nav> -Elemente gibt, sollten diese auch beschriftet werden, zum Beispiel mit aria-label .

 "nav": "nav[aria-label='${1:Main}']>ul>(li>a[aria-current='page']{${2:Current Page}})+(li*3>a{${0:Another Page}})"

Das sieht wild aus, also lass es uns nochmal aufschlüsseln.

Nervenzusammenbruch

Wir beginnen mit einem <nav> -Element mit einem aria-label Attribut und einem verschachtelten <ul> . ${1:Main} füllt das Attribut mit dem Text „Main“ und erstellt einen Tabstopp am Attributwert, indem der Cursor darauf bewegt und bei der Erstellung hervorgehoben wird.

 nav[aria-label='${1:Main}']>ul

Dann erstellen wir vier Listenelemente mit verschachtelten Links. Das erste Element ist etwas Besonderes, da es die aktive Seite mit aria-current="page" markiert. Wir erstellen einen weiteren Tabstopp und füllen den Link mit dem Text „Aktuelle Seite“.

 (li>a[aria-current='page']>{${2:Current Page}})

Abschließend fügen wir drei weitere Listeneinträge mit Links und dem Linktext „Weitere Seite“ hinzu.

 (li*3>a>{${0:Another Page}})

Vor unseren Anpassungen haben wir Folgendes erhalten:

 <-- Before: nav + TAB/Enter --> <nav></nav>

Jetzt bekommen wir das:

 <-- After: nav + TAB/Enter --> <nav aria-label="Main"> <ul> <li><a href="" aria-current="page">Current Page</a></li> <li><a href="">Another Page</a></li> <li><a href="">Another Page</a></li> <li><a href="">Another Page</a></li> </ul> </nav>
Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Stil

Die Abkürzung für den Standardstil erstellt nur das <style> style und End-Tag, aber normalerweise mache ich es, wenn ich das <style> -Element verwende, weil ich schnell etwas testen oder debuggen möchte.

Fügen wir dem Tag <style> einige Standardregeln hinzu:

 "style": "style>{\\* { box-sizing: border-box; \\}}+{\n${1:*}:focus \\{${2: outline: 2px solid red; }\\} }+{\n${0}}"

Nervenzusammenbruch

Einige Zeichen (zB $ , * , { oder } ) müssen mit \\ werden.

 style>{\\* { box-sizing: border-box; \\}}

\n erstellt einen Zeilenumbruch und ${1:*} platziert den ersten Tabstopp am Selektor * .

 {\n${1:*}:focus \\{${2: outline: 2px solid red; }\\}}
  • Vorher : <style><style>
  • Nach :
     <style> * { box-sizing: border-box; }
    *:focus { outline: 2px solid red; } </style>

So, genug Aufwärmen. Lassen Sie uns komplexe Snippets erstellen. Zuerst wollte ich ein einzelnes Snippet für meine Boilerplate erstellen, aber ich habe drei Abkürzungen erstellt, die unterschiedliche Anforderungen erfüllen.

  1. Klein
  2. Mittel
  3. Voll

Boilerplate klein

Dies ist ein Boilerplate für schnelle Demos, es erstellt Folgendes:

  • Grundstruktur der Website,
  • viewport -Meta-Tag,
  • Seitentitel,
  • <style> -Element,
  • Ein <h1> .
 { "!": "{<!DOCTYPE html>}+html[lang=${1}${lang}]>(head>meta:utf+meta:vp+{}+title{${2:New document}}+{}+style)+body>(h1>{${3: New Document}})+{${0}}" }

Nervenzusammenbruch

Ein String mit dem Doctype:

 {<!DOCTYPE html>}

Das <html> -Element mit einem lang Attribut. Der Wert des lang -Attributs ist eine Variable, die Sie in den VS-Code-Einstellungen ändern können (Code → Einstellungen → Einstellungen).

 html[lang=${1}${lang}]

Sie können die standardmäßige natürliche Sprache der Seite ändern, indem Sie in den VS-Code-Einstellungen nach „emmet-Variablen“ suchen und die Variable „ lang “ ändern. Sie können hier auch Ihre benutzerdefinierten Variablen hinzufügen.

Es gibt 2 Standardvariablen in VS Code, lang ist auf en und charset auf UTF-8 gesetzt.

Der <head> enthält das charset -Meta-Tag, das viewport -Meta-Tag, den <title> - und den <style> -Tag. {} erstellt eine neue Zeile.

 (head>meta:utf+meta:vp+{}+title{${2:New document}}+{}+style)

Werfen wir einen ersten kurzen Blick darauf, was uns das bringt.

 <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>New document</title> </head> </html>

Sieht gut aus, aber die Abkürzung meta:utf erstellt die alte Art und Weise in HTML, den charset zu definieren, und meta:vp erstellt zwei Tabstopps, die ich nicht brauche, weil ich nie eine andere Einstellung für den viewport verwende.

Lassen Sie uns diese Snippets überschreiben, bevor wir fortfahren.

 { "meta:vp": "meta[name=viewport content='width=device-width, initial-scale=1']", "meta:utf": "meta[charset=${charset}]" }

Last but not least das Element <body> , ein <h1> mit Standardtext, gefolgt vom abschließenden Tabstopp.

 body>(h1>{${3: New Document}})+{${0}}

Der letzte Boilerplate:

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>New document</title> <style> * { box-sizing: border-box; } *:focus { outline: 2px solid red; } </style> </head> <body> <h1> New Document</h1> </body> </html>

Für mich ist das das perfekte minimale Debugging-Setup.

Boilerplate-Medium

Während ich den ersten Boilerplate nur für schnelle Demos verwende, kann der zweite Boilerplate für komplexe Seiten verwendet werden. Das Snippet erstellt Folgendes:

  • Grundstruktur der Website,
  • viewport -Meta-Tag,
  • Seitentitel,
  • .no-js / .js -Klassen,
  • Externe Bildschirm- und Druck-Stylesheets,
  • description und theme-color Meta-Tag,
  • Seitenstruktur.
 { "!!": "{<!DOCTYPE html>}+html[lang=${1}${lang}].no-js>{<!-- TODO: Check lang attribute --> }+(head>meta:utf+meta:vp+{}+title{${1: Change me}}+{}+(script[type=\"module\"]>{document.documentElement.classList.replace('no-js', 'js');})+{}+link:css+link:print+{}+meta[name=\"description\"][content=\"${2: Change me (up to ~155 characters)}\"]+{<!-- TODO: Change page description --> }+meta[name=\"theme-color\"][content=\"${2:#FF00FF}\"])+body>page" }

Ja, ich weiß, das sieht nach Kauderwelsch aus. Lass es uns sezieren.

Nervenzusammenbruch

Der doctype und das Root-Element sind wie im ersten Beispiel, aber mit einer zusätzlichen no-js Klasse und einem Kommentar, der mich daran erinnert, das lang -Attribut gegebenenfalls zu ändern.

 {<!DOCTYPE html>}+html[lang=${1}${lang}].no-js>{ }

Die TODO Highlight-Erweiterung lässt den Kommentar wirklich auffallen.

Die Erweiterung hebt bestimmte Schlüsselwörter wie TODO visuell hervor.

Der <head> enthält das charset -Meta-Tag, das viewport -Meta-Tag, <title> . {} erstellt eine neue Zeile.

 (head>meta:utf+meta:vp+{}+title{${1: Change me}}+{}

Ein Skript mit einer Zeile JavaScript. Ich schneide den Senf bei der JS-Modulunterstützung ab. Wenn ein Browser JavaScript-Module unterstützt, bedeutet dies, dass es sich um einen Browser handelt, der modernes JavaScript unterstützt (z. B. Module, ES 6-Syntax, Abrufen usw.). Ich versende die meisten JS nur an diese Browser und verwende die js -Klasse in CSS, wenn das Styling einer Komponente anders ist, wenn JavaScript aktiv ist.

 (script[type=\"module\"]>{document.documentElement.classList.replace('no-js', 'js');})+{}

Zwei <link> -Elemente; das erste verlinkt auf das Haupt-Stylesheet und das zweite auf ein Druck-Stylesheet.

 link:css+link:print+{}

Die Seitenbeschreibung:

 meta[name=\"description\"\][content=\"${2: Change me (up to ~155 characters)}\"]+{ }

Das theme-color Meta-Tag:

 meta[name=\"theme-color\"\][content=\"${2:#FF00FF}\"])

Das Body-Element und die grundlegende Seitenstruktur:

 body>page

Der endgültige Boilerplate sieht so aus:

 <!DOCTYPE html> <html lang="en" class="no-js"> <!-- TODO: Check lang attribute --> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> Change me</title> <script type="module"> document.documentElement.classList.replace('no-js', 'js'); </script> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="print.css" media="print"> <meta name="description" content=" Change me (up to ~155 characters)"> <!-- TODO: Change page description --> <meta name="theme-color" content="#FF00FF"> </head> <body> <header> <h1></h1> </header> <main></main> <footer>©</footer> </body> </html>

Volle Boilerplate

Die vollständige Boilerplate ähnelt der zweiten Boilerplate; Die Unterschiede sind zusätzliche meta -Tags und ein script -Tag.

Das Snippet erstellt Folgendes:

  • Grundstruktur der Website,
  • viewport -Meta-Tag,
  • Seitentitel,
  • js / no-js Klassen,
  • Externe Bildschirm- und Druck-Stylesheets,
  • description und offene Graph-Meta-Tags,
  • theme-color Meta-Tag,
  • kanonisches <link> -Tag,
  • Favicon-Tags,
  • Seitenstruktur,
  • < script> -Tag.
 { "!!!": "{<!DOCTYPE html>}+html[lang=${1}${lang}].no-js>{<!-- TODO: Check lang attribute --> }+(head>meta:utf+meta:vp+{}+title{${1: Change me}}+{}+(script[type=\"module\"]>{document.documentElement.classList.replace('no-js', 'js');})+{}+link:css+link:print+{}+meta[property=\"og:title\"][content=\"${1: Change me}\"]+meta[name=\"description\"][content=\"${2: Change me (up to ~155 characters)}\"]+meta[property=\"og:description\"][content=\"${2: Change me (up to ~155 characters)}\"]+meta[property=\"og:image\"][content=\"${1:https://}\"]+meta[property=\"og:locale\"][content=\"${1:en_GB}\"]+meta[property=\"og:type\"][content=\"${1:website}\"]+meta[name=\"twitter:card\"][content=\"${1:summary_large_image}\"]+meta[property=\"og:url\"][content=\"${1:https://}\"]+{<!-- TODO: Change social media stuff --> }+{}+link[rel=\"canonical\"][href=\"${1:https://}\"]+{<!-- TODO: Change canonical link --> }+{}+link[rel=\"icon\"][href=\"${1:/favicon.ico}\"]+link[rel=\"icon\"][href=\"${1:/favicon.svg}\"][type=\"image/svg+xml\"]+link[rel=\"apple-touch-icon\"][href=\"${1:/apple-touch-icon.png}\"]+link[rel=\"manifest\"][href=\"${1:/my.webmanifest}\"]+{}+meta[name=\"theme-color\"][content=\"${2:#FF00FF}\"])+body>page+{}+script:src[type=\"module\"]" }

Dieses unglaublich lange Snippet erzeugt Folgendes:

 <!DOCTYPE html> <html lang="en" class="no-js"> <!-- TODO: Check lang attribute --> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> Change me</title> <script type="module"> document.documentElement.classList.replace('no-js', 'js'); </script> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="print.css" media="print"> <meta property="og:title" content=" Change me"> <meta name="description" content=" Change me (up to ~155 characters)"> <meta property="og:description" content=" Change me (up to ~155 characters)"> <meta property="og:image" content="https://"> <meta property="og:locale" content="en_GB"> <meta property="og:type" content="website"> <meta name="twitter:card" content="summary_large_image"> <meta property="og:url" content="https://"> <!-- TODO: Change social media stuff --> <link rel="canonical" href="https://"> <!-- TODO: Change canonical link --> <link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.svg" type="image/svg+xml"> <link rel="apple-touch-icon" href="/apple-touch-icon.png"> <link rel="manifest" href="/my.webmanifest"> <meta name="theme-color" content="#FF00FF"> </head> <body> <header> <h1></h1> </header> <main></main> <footer>©</footer> <script src="" type="module"></script> </body> </html>

Benutzerdefinierte CSS-Snippets

Der Vollständigkeit halber sind hier einige der CSS-Snippets, die ich verwende.

Debuggen

Dieses Snippet erstellt eine rote 5-Pixel-Umrandung mit einem benutzerdefinierten Versatz.

 "debug": "outline: 5px solid red;\noutline-offset: -5px;"

Zentrierung

Ein Ausschnitt, der die display auf Flex setzt und seine untergeordneten Elemente zentriert.

 "center": "display: flex;\njustify-content: center;\nalign-items: center;"

Klebrig

Legt die position -Eigenschaft auf sticky , mit zwei Tabstopps an der top und left Eigenschaft.

 "sticky": "position: sticky;\ntop: ${1:0};\nleft: ${2:0};" 
Eine Demonstration aller 3 CSS-Snippets, die auf ein div Element angewendet werden.

Benutzer-Snippets

Am Anfang dieses Artikels habe ich erwähnt, dass VS Code auch benutzerdefinierte Snippets bereitstellt. Der Unterschied zu Emmet-Snippets besteht darin, dass Sie keine Abkürzungen verwenden können, aber Sie können auch Tabstopps definieren und interne Variablen verwenden.

Wie man das Beste aus Benutzer-Snippets herausholt, könnte ein Thema für einen anderen Artikel sein, aber hier ist ein Beispiel für ein benutzerdefiniertes CSS-Snippet, das ich definiert habe:

 "Visually hidden": { "prefix": "vh", "body": [ ".u-vh {", " position: absolute;\n white-space: nowrap;\n width: 1px;\n height: 1px;\n overflow: hidden;\n border: 0;\n padding: 0;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n margin: -1px;", "}" ], "description": "A utility class for screen reader accessible hiding." }

Dieses Snippet erstellt nicht nur CSS-Regeln, sondern einen ganzen Deklarationsblock, wenn wir vh und Enter oder Tab drücken.

 .u-vh { position: absolute; white-space: nowrap; width: 1px; height: 1px; overflow: hidden; border: 0; padding: 0; clip: rect(0 0 0 0); clip-path: inset(50%); margin: -1px; }

Letzte Worte

Das Erstellen dieser Snippets nimmt einige Zeit in Anspruch, aber die Mühe lohnt sich, da Sie Emmet an Ihre persönlichen Vorlieben anpassen, sich wiederholende Aufgaben automatisieren und langfristig Zeit sparen können.

Ich würde gerne sehen, welche Snippets Sie verwenden, also teilen Sie sie uns bitte in den Kommentaren mit. Wenn Sie meine Einstellungen verwenden möchten, finden Sie meine endgültige snippets.json auf GitHub.

Ressourcen

  • Standard-CSS-Emmet-Snippets
  • Standard-HTML-Emmet-Snippets
  • Emmet Spickzettel
  • Emmet in VS Code-Dokumentation