Tworzenie niestandardowych fragmentów kodu Emmet w kodzie VS

Opublikowany: 2022-03-10
Krótkie podsumowanie ↬ W tym artykule Manuel wyjaśnia, dlaczego Emmet jest jednym z jego ulubionych narzędzi zwiększających produktywność do pisania HTML i CSS oraz jak można tworzyć niestandardowe fragmenty kodu Emmet w Visual Studio Code, aby jeszcze bardziej ulepszyć przepływy pracy w interfejsie.

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.

Oto krótkie demo niestandardowych fragmentów, które utworzyłem.

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:

  1. Utwórz plik snippets.json , dodaj tę podstawową strukturę JSON i zapisz ją gdzieś na dysku twardym.
     { "html": { "snippets": { } }, "css": { "snippets": { } } }
  2. Otwórz ustawienia VS Code (Kod → Preferencje → Ustawienia) i wyszukaj „Ścieżka rozszerzeń Emmet”.
  3. 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 &copy .

 {${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>
Więcej po skoku! Kontynuuj czytanie poniżej ↓

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.

  1. Mały
  2. Średni
  3. 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.

W VS Code są 2 domyślne zmienne, język jest ustawiony na en, a zestaw znaków na UTF-8.

<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 metatag theme-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.

Rozszerzenie wyróżnia wizualnie niektóre słowa kluczowe, takie jak TODO.

<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};" 
Demonstracja wszystkich 3 fragmentów kodu CSS zastosowanych do elementu div .

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