Tworzenie niestandardowych fragmentów kodu Emmet w kodzie VS
Opublikowany: 2022-03-10 Na początku tego roku udostępniłem na swoim blogu szablon HTML, którego lubię używać przy rozpoczynaniu nowych projektów internetowych z objaśnieniami linijka po linijce. Jest to zbiór głównie tagów i atrybutów <head>
, których zwykle używam na każdej tworzonej przeze mnie stronie internetowej. Do niedawna po prostu kopiowałem i wklejałem szablon, kiedy tylko potrzebowałem, ale postanowiłem poprawić swój przepływ pracy, dodając go jako fragment do VS Code — wybranego przeze mnie edytora.
Fragmenty i skróty w kodzie programu Visual Studio
VS Code ma wbudowane niestandardowe fragmenty kodu użytkownika oraz fragmenty kodu HTML i CSS oraz skróty dostarczane przez firmę Emmet.
Na przykład, jeśli wpiszesz p>a{Sign Up}
w dokumencie HTML i naciśniesz Enter lub Tab , Emmet zmieni to w następujący znacznik:
<p><a href="">Sign Up</a></p>
Uwaga : odwiedź dokumentację Emmeta, aby dowiedzieć się, jak używać składni skrótów.
Jeśli regularnie potrzebujemy tego konkretnego skrótu, możemy zapisać go jako fragment, aby jeszcze bardziej usprawnić nasz przepływ pracy.
{ "html": { "snippets": { "signup": "p>a{Sign Up}" } } }
Teraz możemy wpisać signup
i nacisnąć Enter lub Tab i otrzymamy ten sam wynik. W następnej sekcji wyjaśnię, jak tworzyć fragmenty.
Emmet domyślnie zawiera kilka fragmentów kodu HTML. Na przykład !
tworzy podstawową strukturę dokumentu HTML.
<!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>
To świetnie, ale jeśli chcemy dostosować ten fragment kodu, usuwając lub dodając elementy i atrybuty, musimy go zastąpić i utworzyć własny fragment.
Tworzenie i nadpisywanie fragmentów
Jeśli chcemy tworzyć własne fragmenty kodu Emmet lub nadpisywać istniejące w VS Code, konieczne są następujące kroki:
- Utwórz plik snippets.json , dodaj tę podstawową strukturę JSON i zapisz ją gdzieś na dysku twardym.
{ "html": { "snippets": { } }, "css": { "snippets": { } } }
- Otwórz ustawienia VS Code (Kod → Preferencje → Ustawienia) i wyszukaj „Ścieżka rozszerzeń Emmet”.
- Kliknij „Dodaj element”, wprowadź ścieżkę do folderu, w którym zapisałeś wcześniej utworzony plik snippets.json i naciśnij „OK”.
Otóż to. Teraz jesteśmy gotowi do tworzenia fragmentów, dodając właściwości do obiektów html
i css
, gdzie key
jest nazwa fragmentu, a value
skrótem lub ciągiem znaków.
Niektóre z moich niestandardowych fragmentów HTML
Zanim zagłębimy się w tworzenie snippetów i pokażę, jak stworzyłem snippet dla mojego szablonu HTML, rozgrzejmy się najpierw z kilkoma małymi, ale użytecznymi urywkami, które również stworzyłem.
Powolne ładowanie
Po wyjęciu z pudełka jest skrót img
, ale nie ma go dla leniwie ładowanych obrazów. Możemy użyć domyślnego skrótu i po prostu dodać dodatkowe atrybuty i wartości atrybutów, których potrzebujemy, w nawiasach kwadratowych.
{ "html": { "snippets": { "img:l": "img[width height loading='lazy']" } } }
img:l
+ Enter / Tab tworzy teraz następujący znacznik:
<img src="" alt="" width="" height="" loading="lazy">
Strona
Większość stron, które tworzę, składa się z punktów orientacyjnych <header>
, <main>
i <footer>
oraz <h1>
. Skrót page
niestandardowej pozwala mi szybko stworzyć taką strukturę.
"snippets": { "page": "header>h1^main+footer{${0:©}}" }
page
+ Enter / Tab tworzy następujący znacznik:
<header> <h1></h1> </header> <main></main> <footer>©</footer>
Ten skrót jest dość długi, więc podzielmy go na mniejsze części.
Awaria
Utwórz element <header>
i dziecko <h1>
.
header>h1
Przejdź w górę, z powrotem na poziom <header>
i utwórz <footer>
, który następuje po <main>
.
^main+footer
Ustaw ostatni punkt tabulacji w <footer>
i ustaw domyślny tekst na ©
.
{${0:©}}
Nawigacja
Skrót nav
po prostu domyślnie tworzy tag początkowy i końcowy <nav>
, ale to, czego zwykle potrzebuję, to <nav>
z zagnieżdżonymi elementami <ul>
, <li>
i linkami ( <a>
). Jeśli na stronie znajduje się wiele elementów <nav>
, należy je również oznaczyć, na przykład za pomocą aria-label
.
"nav": "nav[aria-label='${1:Main}']>ul>(li>a[aria-current='page']{${2:Current Page}})+(li*3>a{${0:Another Page}})"
To wygląda dziko, więc zróbmy to ponownie.
Awaria
Zaczynamy od elementu <nav>
z atrybutem aria-label
i zagnieżdżonym <ul>
. ${1:Main}
wypełnia atrybut tekstem „Main” i tworzy tabulator na wartości atrybutu, przesuwając do niego kursor i podświetlając go podczas tworzenia.
nav[aria-label='${1:Main}']>ul
Następnie tworzymy cztery elementy listy z zagnieżdżonymi łączami. Pierwsza pozycja jest wyjątkowa, ponieważ oznacza aktywną stronę za pomocą aria-current="page"
. Tworzymy kolejny tabulator i wypełniamy link tekstem „Bieżąca strona”.
(li>a[aria-current='page']>{${2:Current Page}})
Na koniec dodajemy jeszcze trzy elementy listy z linkami i tekstem linku „Inna strona”.
(li*3>a>{${0:Another Page}})
Przed naszymi adaptacjami otrzymaliśmy to:
<-- Before: nav + TAB/Enter --> <nav></nav>
Teraz otrzymujemy to:
<-- 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>
Styl
Domyślny skrót style
tworzy tylko tag start i end <style>
, ale zwykle, gdy używam elementu <style>
, robię to, ponieważ chcę szybko coś przetestować lub debugować.
Dodajmy kilka domyślnych reguł do tagu <style>
:
"style": "style>{\\* { box-sizing: border-box; \\}}+{\n${1:*}:focus \\{${2: outline: 2px solid red; }\\} }+{\n${0}}"
Awaria
Niektóre znaki (np. $
, *
, {
lub }
) muszą zostać zmienione za pomocą \\
.
style>{\\* { box-sizing: border-box; \\}}
\n
tworzy łamanie linii, a ${1:*}
umieszcza pierwszy tabulator na selektorze *
.
{\n${1:*}:focus \\{${2: outline: 2px solid red; }\\}}
- Przed :
<style><style>
- Po :
<style> * { box-sizing: border-box; }
*:focus { outline: 2px solid red; } </style>
Dobra, dość rozgrzewki. Utwórzmy złożone fragmenty. Na początku chciałem stworzyć jeden fragment kodu dla mojego boilerplate’u, ale stworzyłem trzy skróty, które odpowiadają różnym potrzebom.
- Mały
- Średni
- Pełny
Płyta kotła mała
Jest to szablon do szybkich demonstracji, tworzy następujące elementy:
- Podstawowa struktura strony,
- metatag
viewport
, - Tytuł strony,
- element
<style>
, -
<h1>
.
{ "!": "{<!DOCTYPE html>}+html[lang=${1}${lang}]>(head>meta:utf+meta:vp+{}+title{${2:New document}}+{}+style)+body>(h1>{${3: New Document}})+{${0}}" }
Awaria
Ciąg z doctypem:
{<!DOCTYPE html>}
Element <html>
z atrybutem lang
. Wartość atrybutu lang
to zmienna, którą możesz zmienić w ustawieniach kodu VS (Kod → Preferencje → Ustawienia).
html[lang=${1}${lang}]
Możesz zmienić domyślny język naturalny strony, wyszukując „zmienne emmet” w ustawieniach VS Code i zmieniając zmienną lang
. Tutaj również możesz dodać swoje zmienne niestandardowe.
<head>
zawiera metatag charset
, metatag viewport
, <title>
i <style>
tag. {}
tworzy nową linię.
(head>meta:utf+meta:vp+{}+title{${2:New document}}+{}+style)
Przyjrzyjmy się najpierw, co nam to daje.
<!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>
Wygląda dobrze, ale skrót meta:utf
tworzy stary sposób w HTML na zdefiniowanie charset
, a meta:vp
tworzy dwa tabulatory, których nie potrzebuję, ponieważ nigdy nie używam innych ustawień dla viewport
.
Zastąpmy te fragmenty, zanim przejdziemy dalej.
{ "meta:vp": "meta[name=viewport content='width=device-width, initial-scale=1']", "meta:utf": "meta[charset=${charset}]" }
Na koniec element <body>
, <h1>
z domyślnym tekstem, po którym następuje ostatni tabulator.
body>(h1>{${3: New Document}})+{${0}}
Ostateczny schemat:
<!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>
Dla mnie jest to idealna minimalna konfiguracja debugowania.
Średnia płyta kotłowa
Podczas gdy pierwszego boilerplate’u używam tylko do szybkich demonstracji, drugiego boilerplate’u można używać do złożonych stron. Fragment kodu tworzy:
- Podstawowa struktura strony,
- metatag
viewport
, - Tytuł strony,
-
.no-js
/.js
, - Zewnętrzne arkusze stylów ekranu i druku,
-
description
i metatagtheme-color
, - Struktura strony.
{ "!!": "{<!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" }
Tak, wiem, to wygląda jak bełkot. Przeanalizujmy to.
Awaria
doctype
i element root są takie jak w pierwszym przykładzie, ale z dodatkową klasą no-js
i komentarzem, który przypomina mi o zmianie atrybutu lang
, jeśli to konieczne.
{<!DOCTYPE html>}+html[lang=${1}${lang}].no-js>{ }
Rozszerzenie TODO Highlight sprawia, że komentarz jest naprawdę atrakcyjny.
<head>
zawiera metatag charset
, metatag viewport
, <title>
. {}
tworzy nową linię.
(head>meta:utf+meta:vp+{}+title{${1: Change me}}+{}
Skrypt z linią JavaScript. Musztardę kroję na wsporniku modułu JS. Jeśli przeglądarka obsługuje moduły JavaScript, oznacza to, że jest to przeglądarka obsługująca nowoczesny JavaScript (np. moduły, składnia ES 6, pobieranie itd.). Większość JS wysyłam tylko do tych przeglądarek i używam klasy js
w CSS, jeśli stylizacja komponentu jest inna, gdy JavaScript jest aktywny.
(script[type=\"module\"]>{document.documentElement.classList.replace('no-js', 'js');})+{}
Dwa elementy <link>
; pierwszy łączy się z głównym arkuszem stylów, a drugi z arkuszem stylów drukowania.
link:css+link:print+{}
Opis strony:
meta[name=\"description\"\][content=\"${2: Change me (up to ~155 characters)}\"]+{ }
Metatag theme-color
:
meta[name=\"theme-color\"\][content=\"${2:#FF00FF}\"])
Element body i podstawowa struktura strony:
body>page
Finalny schemat wygląda tak:
<!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>
Pełna płyta grzewcza
Pełny boilerplate jest podobny do drugiego boilerplate’u; różnice to dodatkowe meta
i tag script
.
Fragment kodu tworzy:
- Podstawowa struktura strony,
- metatag
viewport
, - Tytuł strony,
- klasy
js
/no-js
, - Zewnętrzne arkusze stylów ekranu i druku,
-
description
i metatagi open graph, - metatag
theme-color
, - kanoniczny tag
<link>
, - Tagi favicon,
- Struktura strony,
- znacznik <
script>
.
{ "!!!": "{<!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\"]" }
Ten niesamowicie długi fragment kodu tworzy to:
<!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>
Niestandardowe fragmenty CSS
Ze względu na kompletność, oto kilka fragmentów kodu CSS, których używam.
Debugowanie
Ten fragment kodu tworzy czerwony kontur o wielkości 5 pikseli z niestandardowym przesunięciem.
"debug": "outline: 5px solid red;\noutline-offset: -5px;"
Krążyna
Fragment kodu, który ustawia display
na flex i centruje jego elementy podrzędne.
"center": "display: flex;\njustify-content: center;\nalign-items: center;"
Lepki
Ustawia właściwość position
na sticky
, z dwoma tabulatorami na top
i left
właściwości.
"sticky": "position: sticky;\ntop: ${1:0};\nleft: ${2:0};"
Fragmenty użytkownika
Na początku tego artykułu wspomniałem, że VS Code udostępnia również niestandardowe fragmenty. Różnica w stosunku do fragmentów kodu Emmeta polega na tym, że nie można używać skrótów, ale można również definiować tabulatory i korzystać ze zmiennych wewnętrznych.
Jak najlepiej wykorzystać fragmenty kodu użytkownika, może być tematem innego artykułu, ale oto przykład niestandardowego fragmentu kodu CSS, który zdefiniowałem:
"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." }
Ten fragment kodu nie tylko tworzy reguły CSS, ale cały blok deklaracji, gdy vh
i naciśniemy Enter lub Tab .
.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; }
Ostatnie słowa
Tworzenie tych fragmentów zajmuje trochę czasu, ale jest warte wysiłku, ponieważ możesz dostosować Emmeta do swoich osobistych preferencji, zautomatyzować powtarzające się zadania i zaoszczędzić czas na dłuższą metę.
Bardzo chciałbym zobaczyć, jakich fragmentów używasz, więc podziel się nimi z nami w komentarzach. Jeśli chcesz użyć moich ustawień, możesz znaleźć mój ostateczny snippets.json na GitHub.
Zasoby
- Domyślne fragmenty kodu CSS Emmet
- Domyślne fragmenty kodu HTML Emmet
- Ściągawka Emmeta
- Emmet w dokumentacji VS Code