Crearea de fragmente Emmet personalizate în VS Code

Publicat: 2022-03-10
Rezumat rapid ↬ În acest articol, Manuel explică de ce Emmet este unul dintre instrumentele sale preferate de productivitate pentru scrierea HTML și CSS și cum puteți crea fragmente Emmet personalizate în Visual Studio Code pentru a vă ajuta să vă îmbunătățiți și mai mult fluxurile de lucru front-end.

La începutul acestui an, am împărtășit pachetul HTML pe care îmi place să îl folosesc atunci când încep noi proiecte web, cu explicații rând cu rând pe blogul meu. Este o colecție de etichete și atribute <head> pe care le folosesc de obicei pe fiecare site web pe care îl construiesc. Până de curând, copiam și inseram boilerplate ori de câte ori aveam nevoie, dar am decis să-mi îmbunătățesc fluxul de lucru adăugându-l ca fragment în VS Code - editorul ales de mine.

Iată o demonstrație rapidă a fragmentelor personalizate pe care le-am creat.

Fragmente și abrevieri în codul Visual Studio

VS Code vine încorporat cu fragmente de utilizator personalizate și fragmente HTML și CSS și abrevieri furnizate de Emmet.

De exemplu, dacă tastați p>a{Sign Up} într-un document HTML și apăsați Enter sau Tab , Emmet îl va transforma în următorul marcaj:

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

Notă : Vizitați documentele Emmet pentru a afla cum să utilizați sintaxa abrevierilor.

Dacă avem nevoie de această abreviere în mod regulat, o putem salva ca fragment pentru a ne îmbunătăți și mai mult fluxul de lucru.

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

Acum putem scrie signup și apăsăm Enter sau Tab și vom obține același rezultat. Voi explica cum să creez fragmente în secțiunea următoare.

Emmet vine cu o grămadă de fragmente HTML în mod implicit. De exemplu, ! creează structura de bază a unui document 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>

Este grozav, dar dacă dorim să adaptăm acest fragment prin eliminarea sau adăugarea de elemente și atribute, trebuie să îl suprascriem și să ne creăm propriul fragment.

Crearea și suprascrierea fragmentelor

Dacă dorim să ne creăm propriile fragmente Emmet sau să le suprascriem pe cele existente în VS Code, sunt necesari următorii pași:

  1. Creați un fișier snippets.json , adăugați această structură JSON de bază și salvați-o undeva pe hard disk.
     { "html": { "snippets": { } }, "css": { "snippets": { } } }
  2. Deschideți setările VS Code (Cod → Preferințe → Setări) și căutați „Calea extensiilor Emmet”.
  3. Faceți clic pe „Adăugați element”, introduceți calea către folderul în care ați salvat fișierul snippets.json pe care l-ați creat mai devreme și apăsați pe „OK”.

Asta e. Acum suntem gata să creăm fragmente adăugând proprietăți la obiectele html și css , unde key este numele fragmentului și value o abreviere sau un șir.

Unele dintre fragmentele mele HTML personalizate

Înainte să ne aprofundăm în crearea de fragmente și să vă arăt cum am creat un fragment pentru placa mea HTML, să ne încălzim mai întâi cu câteva fragmente mici, dar utile, pe care le-am creat.

Încărcare leneșă

Din cutie, există o abreviere img , dar nu există nici una pentru imaginile încărcate leneș. Putem folosi abrevierea implicită și doar adăugăm atributele suplimentare și valorile atributelor de care avem nevoie între paranteze drepte.

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

img:l + Enter / Tab creează acum următorul marcaj:

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

Pagină

Cele mai multe pagini pe care le creez constau din repere <header> , <main> și <footer> și un <h1> . Abrevierea page personalizate îmi permite să creez rapid acea structură.

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

page + Enter / Tab creează următorul marcaj:

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

Această abreviere este destul de lungă, așa că haideți să o împărțim în bucăți mai mici.

Dărâma

Creați un element <header> și un copil <h1> .

 header>h1

Deplasați-vă în sus, înapoi la nivelul <header> și creați un <footer> care urmează <main> .

 ^main+footer

Setați tabulatorul final în <footer> și setați textul implicit la &copy .

 {${0:©}}

Navigare

Abrevierea nav creează doar o etichetă de început și de sfârșit <nav> în mod implicit, dar ceea ce am nevoie de obicei este un <nav> cu elemente imbricate <ul> , <li> și linkuri ( <a> ). Dacă există mai multe elemente <nav> pe o pagină, acestea ar trebui să fie, de asemenea, etichetate, de exemplu folosind aria-label .

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

Pare sălbatic, așa că hai să-l descompunem din nou.

Dărâma

Începem cu un element <nav> cu un atribut aria-label și un <ul> imbricat. ${1:Main} populează atributul cu textul „Principal” și creează o oprire de tabulare la valoarea atributului, deplasând cursorul la acesta și evidențiind-o la creare.

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

Apoi creăm patru elemente de listă cu legături imbricate. Primul articol este special pentru că marchează pagina activă folosind aria-current="page" . Creăm o altă tabulatură și populăm linkul cu textul „Pagina curentă”.

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

În cele din urmă, adăugăm încă trei elemente de listă cu linkuri și textul linkului „O altă pagină”.

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

Înainte de adaptările noastre, am primit asta:

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

Acum obținem asta:

 <-- 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>
Mai multe după săritură! Continuați să citiți mai jos ↓

Stil

Abrevierea implicită a style creează doar eticheta de început și de sfârșit <style> , dar, de obicei, când folosesc elementul <style> , o fac pentru că vreau rapid să testez sau să depanez ceva.

Să adăugăm câteva reguli implicite etichetei <style> :

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

Dărâma

Unele caractere (de exemplu $ , * , { sau } ) trebuie să fie eliminate folosind \\ .

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

\n creează o întrerupere de linie și ${1:*} plasează prima tabulatură la selector * .

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

Bine, suficientă încălzire. Să creăm fragmente complexe. La început, am vrut să creez un singur fragment pentru boilerplate, dar am creat trei abrevieri care servesc nevoi diferite.

  1. Mic
  2. Mediu
  3. Deplin

Boilerplate Mic

Acesta este un boilerplate pentru demonstrații rapide, creează următoarele:

  • Structura de bază a site-ului,
  • metaetichetă viewport ,
  • Titlul paginii,
  • element <style> ,
  • A <h1> .
 { "!": "{<!DOCTYPE html>}+html[lang=${1}${lang}]>(head>meta:utf+meta:vp+{}+title{${2:New document}}+{}+style)+body>(h1>{${3: New Document}})+{${0}}" }

Dărâma

Un șir cu doctype:

 {<!DOCTYPE html>}

Elementul <html> cu un atribut lang . Valoarea atributului lang este o variabilă pe care o puteți modifica în setările codului VS (Cod → Preferințe → Setări).

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

Puteți schimba limbajul natural implicit al paginii căutând „variabile emmet” în setările VS Code și schimbând variabila lang . Puteți adăuga și variabilele personalizate aici.

Există 2 variabile implicite în VS Code, lang este setat la en și charset la UTF-8.

<head> include metaeticheta set de charset , metaeticheta viewport , <title> și eticheta <style> . {} creează o linie nouă.

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

Să aruncăm o primă privire rapidă la ce ne oferă acest lucru.

 <!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>

Pare în regulă, dar abrevierea meta:utf creează vechiul mod în HTML de a defini setul de charset , iar meta:vp creează două puncte de tabulare de care nu am nevoie, deoarece nu folosesc niciodată o altă setare pentru fereastra de viewport .

Să suprascriem aceste fragmente înainte de a merge mai departe.

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

Nu în ultimul rând, elementul <body> , un <h1> cu text implicit, urmat de tabularea finală.

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

Placa finală:

 <!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>

Pentru mine, aceasta este configurația perfectă de depanare minimă.

Boilerplate Mediu

În timp ce folosesc primul boilerplate doar pentru demonstrații rapide, al doilea boilerplate poate fi folosit pentru pagini complexe. Fragmentul creează următoarele:

  • Structura de bază a site-ului,
  • metaetichetă viewport ,
  • Titlul paginii,
  • clase .no-js / .js ,
  • Ecran extern și foi de stil pentru imprimare,
  • metaetichetă description și theme-color ,
  • Structura paginii.
 { "!!": "{<!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" }

Da, știu, pare o farfurie. Să-l disecăm.

Dărâma

doctype și elementul rădăcină sunt ca în primul exemplu, dar cu o clasă suplimentară no-js și un comentariu care îmi amintește să schimb atributul lang , dacă este necesar.

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

Extensia TODO Highlight face comentariul cu adevărat pop.

Extensia evidențiază vizual anumite cuvinte cheie precum TODO.

<head> include metaeticheta set de charset , metaeticheta viewport , <title> . {} creează o linie nouă.

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

Un script cu o linie de JavaScript. Tai muștarul la suportul pentru modulul JS. Dacă un browser acceptă module JavaScript, înseamnă că este un browser care acceptă JavaScript modern (de ex. module, sintaxa ES 6, fetch și așa mai departe). Expediez majoritatea JS numai acestor browsere și folosesc clasa js în CSS, dacă stilul unei componente este diferit, când JavaScript este activ.

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

Două elemente <link> ; prima se leagă la foaia de stil principală și a doua la o foaie de stil de tipărire.

 link:css+link:print+{}

Descrierea paginii:

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

Metaeticheta theme-color :

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

Elementul body și structura de bază a paginii:

 body>page

Placa finală arată astfel:

 <!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>

Boilerplate plină

Boilerplate complet este similar cu al doilea boilerplate; diferențele sunt meta -etichete suplimentare și o etichetă de script .

Fragmentul creează următoarele:

  • Structura de bază a site-ului,
  • metaetichetă viewport ,
  • Titlul paginii,
  • clase js / no-js ,
  • Ecran extern și foi de stil pentru imprimare,
  • description și metaetichete pentru grafic deschis,
  • metaetichetă theme-color ,
  • etichetă canonică <link> ,
  • Etichete favicon,
  • Structura paginii,
  • eticheta < 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\"]" }

Acest fragment incredibil de lung creează acest lucru:

 <!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>

Fragmente CSS personalizate

Pentru a fi complet, iată câteva dintre fragmentele CSS pe care le folosesc.

Depanare

Acest fragment creează un contur roșu de 5 px cu un offset personalizat.

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

Centrarea

Un fragment care setează display să se flexibilizeze și își centrează elementele secundare.

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

Lipicios

Setează proprietatea de position la sticky , cu două tabulaturi în partea de top și left .

 "sticky": "position: sticky;\ntop: ${1:0};\nleft: ${2:0};" 
O demonstrație a tuturor celor 3 fragmente CSS aplicate unui element div .

Fragmente de utilizator

La începutul acestui articol, am menționat că VS Code oferă și fragmente personalizate. Diferența față de fragmentele Emmet este că nu puteți folosi abrevieri, dar puteți, de asemenea, să definiți tabulaturi și să utilizați variabile interne.

Cum să obțineți cele mai bune rezultate din fragmentele de utilizator ar putea fi un subiect pentru alt articol, dar iată un exemplu de fragment CSS personalizat pe care l-am definit:

 "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." }

Acest fragment nu creează doar reguli CSS, ci un întreg bloc de declarații atunci când introducem vh și apăsăm Enter sau 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; }

Cuvinte finale

Este nevoie de ceva timp pentru a crea aceste fragmente, dar merită efortul pentru că îl poți personaliza pe Emmet după preferințele tale personale, automatiza sarcinile repetitive și economisește timp pe termen lung.

Mi-ar plăcea să văd ce fragmente folosiți, așa că vă rugăm să ni le împărtășiți în comentarii. Dacă doriți să utilizați setările mele, puteți găsi finalul meu snippets.json pe GitHub.

Resurse

  • Fragmente CSS Emmet implicite
  • Fragmente HTML implicite Emmet
  • Emmet cheat sheet
  • Emmet în documentele VS Code