การสร้างตัวอย่าง Emmet ที่กำหนดเองใน VS Code
เผยแพร่แล้ว: 2022-03-10 เมื่อต้นปีนี้ ฉันได้แชร์เทมเพลต HTML ที่ฉันชอบใช้เมื่อเริ่มต้นโครงการเว็บใหม่พร้อมคำอธิบายทีละบรรทัดในบล็อกของฉัน เป็นชุดของแท็กและแอตทริบิวต์ <head>
ส่วนใหญ่ที่ฉันมักใช้ในทุกเว็บไซต์ที่ฉันสร้าง เมื่อไม่นานมานี้ ฉันจะคัดลอกและวางต้นแบบเมื่อใดก็ตามที่ฉันต้องการ แต่ฉันได้ตัดสินใจที่จะปรับปรุงเวิร์กโฟลว์ของฉันโดยเพิ่มเป็นส่วนย่อยใน VS Code ซึ่งเป็นเครื่องมือแก้ไขที่ฉันเลือก
ตัวอย่างและคำย่อใน Visual Studio Code
VS Code มาพร้อมกับข้อมูลโค้ดผู้ใช้ที่กำหนดเอง รวมถึงตัวอย่าง HTML และ CSS และตัวย่อที่ Emmet จัดเตรียมไว้ให้
ตัวอย่างเช่น หากคุณพิมพ์ p>a{Sign Up}
ในเอกสาร HTML แล้วกด Enter หรือ Tab Emmet จะเปลี่ยนให้เป็นมาร์กอัปต่อไปนี้:
<p><a href="">Sign Up</a></p>
หมายเหตุ : ไปที่เอกสาร Emmet เพื่อเรียนรู้วิธีใช้ไวยากรณ์ตัวย่อ
หากเราต้องการตัวย่อเฉพาะนี้เป็นประจำ เราสามารถบันทึกเป็นตัวย่อเพื่อปรับปรุงเวิร์กโฟลว์ของเราให้ดียิ่งขึ้นไปอีก
{ "html": { "snippets": { "signup": "p>a{Sign Up}" } } }
ตอนนี้เราสามารถพิมพ์ signup
แล้วกด Enter หรือ Tab แล้วเราจะได้ผลลัพธ์แบบเดียวกัน ฉันจะอธิบายวิธีสร้างตัวอย่างในหัวข้อถัดไป
Emmet มาพร้อมกับตัวอย่าง HTML จำนวนมากโดยค่าเริ่มต้น ตัวอย่างเช่น !
สร้างโครงสร้างพื้นฐานของเอกสาร 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>
เยี่ยมมาก แต่ถ้าเราต้องการปรับข้อมูลโค้ดนี้โดยการลบหรือเพิ่มองค์ประกอบและแอตทริบิวต์ เราต้องเขียนทับและสร้างข้อมูลโค้ดของเราเอง
การสร้างและเขียนทับตัวอย่างข้อมูล
หากเราต้องการสร้างข้อมูลโค้ด Emmet ของเราเองหรือเขียนทับข้อมูลโค้ดที่มีอยู่แล้วใน VS Code จำเป็นต้องมีขั้นตอนต่อไปนี้:
- สร้างไฟล์ snippets.json เพิ่มโครงสร้าง JSON พื้นฐานนี้ และบันทึกไว้ที่ใดที่หนึ่งบนฮาร์ดดิสก์ของคุณ
{ "html": { "snippets": { } }, "css": { "snippets": { } } }
- เปิดการตั้งค่า VS Code (Code → Preferences → Settings) และค้นหา "Emmet Extensions Path"
- คลิก "เพิ่มรายการ" ป้อนเส้นทางไปยังโฟลเดอร์ที่คุณได้บันทึกไฟล์ snippets.json ที่คุณสร้างไว้ก่อนหน้านี้แล้วกด "ตกลง"
แค่นั้นแหละ. ตอนนี้เราพร้อมที่จะสร้างตัวอย่างโดยการเพิ่มคุณสมบัติให้กับวัตถุ html
และ css
โดยที่ key
คือชื่อของตัวอย่างและ value
เป็นตัวย่อหรือสตริง
ตัวอย่าง HTML ที่กำหนดเองบางส่วนของฉัน
ก่อนที่เราจะเจาะลึกลงไปในการสร้างตัวอย่างและแสดงให้คุณเห็นว่าฉันสร้างตัวอย่างข้อมูลสำหรับต้นแบบ HTML ของฉันอย่างไร เรามาอุ่นเครื่องกันก่อนด้วยตัวอย่างเล็กๆ แต่มีประโยชน์ที่ฉันสร้างขึ้นด้วยเช่นกัน
ขี้เกียจโหลด
นอกกรอบ มีตัวย่อ img
แต่ไม่มีรูปภาพที่โหลดอย่างเกียจคร้าน เราสามารถใช้ตัวย่อเริ่มต้นและเพียงแค่เพิ่มแอตทริบิวต์เพิ่มเติมและค่าแอตทริบิวต์ที่เราต้องการในวงเล็บเหลี่ยม
{ "html": { "snippets": { "img:l": "img[width height loading='lazy']" } } }
img:l
+ Enter / Tab สร้างมาร์กอัปต่อไปนี้:
<img src="" alt="" width="" height="" loading="lazy">
หน้าหนังสือ
หน้าเว็บส่วนใหญ่ที่ฉันสร้างประกอบด้วยจุดสังเกต <header>
, <main>
และ <footer>
และ <h1>
ตัวย่อของ page
แบบกำหนดเองช่วยให้ฉันสร้างโครงสร้างนั้นได้อย่างรวดเร็ว
"snippets": { "page": "header>h1^main+footer{${0:©}}" }
page
+ Enter / Tab สร้างมาร์กอัปต่อไปนี้:
<header> <h1></h1> </header> <main></main> <footer>©</footer>
ตัวย่อนั้นค่อนข้างยาว เราเลยแยกมันเป็นส่วนย่อยๆ
ทำให้พังถล่ม
สร้าง <header>
องค์ประกอบและลูก <h1>
header>h1
เลื่อนขึ้น กลับไปที่ระดับของ <header>
และสร้าง <footer>
ที่ตามหลัง <main>
^main+footer
ตั้งค่าแท็บสุดท้ายหยุดภายใน <footer>
และตั้งค่าข้อความเริ่มต้นเป็น ©
{${0:©}}
การนำทาง
nav
ตัวย่อเพิ่งสร้างแท็กเริ่มต้นและสิ้นสุด <nav>
โดยค่าเริ่มต้น แต่สิ่งที่ฉันต้องการคือ <nav>
ที่มี <ul>
, <li>
องค์ประกอบและลิงก์ที่ซ้อนกัน ( <a>
) หากมีองค์ประกอบ <nav>
หลายรายการในหน้า ควรมีป้ายกำกับด้วย เช่น โดยใช้ aria-label
"nav": "nav[aria-label='${1:Main}']>ul>(li>a[aria-current='page']{${2:Current Page}})+(li*3>a{${0:Another Page}})"
มันดูป่าเถื่อน เลยมาทำลายมันอีกครั้ง
ทำให้พังถล่ม
เราเริ่มต้นด้วย <nav>
องค์ประกอบที่มีแอตทริบิวต์ aria-label
และ <ul>
ที่ซ้อนกัน ${1:Main}
เติมแอตทริบิวต์ด้วยข้อความ "หลัก" และสร้างแท็บหยุดที่ค่าแอตทริบิวต์โดยเลื่อนเคอร์เซอร์ไปที่แอตทริบิวต์นั้นและไฮไลต์เมื่อสร้าง
nav[aria-label='${1:Main}']>ul
จากนั้นเราสร้างรายการสี่รายการพร้อมลิงก์ที่ซ้อนกัน รายการแรกเป็นพิเศษเพราะทำเครื่องหมายหน้าที่ใช้งานอยู่โดยใช้ aria-current="page"
เราสร้างแท็บหยุดอื่นและเติมลิงก์ด้วยข้อความ "หน้าปัจจุบัน"
(li>a[aria-current='page']>{${2:Current Page}})
สุดท้าย เราเพิ่มรายการอีกสามรายการพร้อมลิงก์และข้อความลิงก์ "หน้าอื่น"
(li*3>a>{${0:Another Page}})
ก่อนการดัดแปลง เราได้สิ่งนี้:
<-- Before: nav + TAB/Enter --> <nav></nav>
ตอนนี้เราได้รับสิ่งนี้:
<-- 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>
สไตล์
ตัวย่อ style
เริ่มต้นจะสร้างเฉพาะแท็กเริ่มต้นและสิ้นสุด <style>
แต่โดยปกติเมื่อฉันใช้องค์ประกอบ <style>
ฉันทำเพราะว่าต้องการทดสอบหรือแก้ไขข้อบกพร่องบางอย่างอย่างรวดเร็ว
มาเพิ่มกฎเริ่มต้นให้กับแท็ก <style>
:
"style": "style>{\\* { box-sizing: border-box; \\}}+{\n${1:*}:focus \\{${2: outline: 2px solid red; }\\} }+{\n${0}}"
ทำให้พังถล่ม
อักขระบางตัว (เช่น $
, *
, {
หรือ }
) จะต้องหลีกเลี่ยงโดยใช้ \\
style>{\\* { box-sizing: border-box; \\}}
\n
สร้างตัวแบ่งบรรทัดและ ${1:*}
วางแท็บแรกที่หยุดที่ตัวเลือก *
{\n${1:*}:focus \\{${2: outline: 2px solid red; }\\}}
- ก่อนหน้า :
<style><style>
- หลัง :
<style> * { box-sizing: border-box; }
*:focus { outline: 2px solid red; } </style>
เอาล่ะ อุ่นเครื่องพอแล้ว มาสร้างตัวอย่างที่ซับซ้อนกันเถอะ ตอนแรก ฉันต้องการสร้างตัวอย่างข้อมูลเดียวสำหรับต้นแบบของฉัน แต่ฉันได้สร้างคำย่อสามคำที่ตอบสนองความต้องการที่แตกต่างกัน
- เล็ก
- ปานกลาง
- เต็ม
หม้อต้มขนาดเล็ก
นี่คือต้นแบบสำหรับการสาธิตอย่างรวดเร็ว โดยสร้างสิ่งต่อไปนี้:
- โครงสร้างไซต์พื้นฐาน
- เมตาแท็ก
viewport
, - ชื่อหน้า
-
<style>
องค์ประกอบ - อ
<h1>
.
{ "!": "{<!DOCTYPE html>}+html[lang=${1}${lang}]>(head>meta:utf+meta:vp+{}+title{${2:New document}}+{}+style)+body>(h1>{${3: New Document}})+{${0}}" }
ทำให้พังถล่ม
สตริงที่มี doctype:
{<!DOCTYPE html>}
<html>
องค์ประกอบที่มีแอตทริบิวต์ lang
ค่าของแอตทริบิวต์ lang
เป็นตัวแปรที่คุณสามารถเปลี่ยนได้ในการตั้งค่าโค้ด VS (รหัส → ค่ากำหนด → การตั้งค่า)
html[lang=${1}${lang}]
คุณสามารถเปลี่ยนภาษาธรรมชาติเริ่มต้นของหน้าได้โดยค้นหา "ตัวแปร emmet" ในการตั้งค่า VS Code และเปลี่ยนตัวแปร lang
คุณสามารถเพิ่มตัวแปรที่กำหนดเองได้ที่นี่เช่นกัน
<head>
ประกอบด้วยเมตาแท็ก charset
เมตาแท็ก viewport
<title>
และแท็ก <style>
{}
สร้างบรรทัดใหม่
(head>meta:utf+meta:vp+{}+title{${2:New document}}+{}+style)
มาดูกันก่อนว่าสิ่งนี้ให้อะไรกับเราบ้าง
<!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>
ดูดี แต่ตัวย่อ meta:utf
สร้างวิธีเก่าใน HTML เพื่อกำหนด charset
และ meta:vp
สร้างแท็บหยุดสองแท็บที่ฉันไม่ต้องการเพราะฉันไม่เคยใช้การตั้งค่าอื่นสำหรับ viewport
มาเขียนทับข้อมูลโค้ดเหล่านี้ก่อนที่เราจะไปต่อ
{ "meta:vp": "meta[name=viewport content='width=device-width, initial-scale=1']", "meta:utf": "meta[charset=${charset}]" }
สุดท้ายแต่ไม่ท้ายสุด องค์ประกอบ <body>
<h1>
ที่มีข้อความเริ่มต้น ตามด้วยแท็บหยุดสุดท้าย
body>(h1>{${3: New Document}})+{${0}}
ต้นแบบสุดท้าย:
<!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>
สำหรับฉัน นั่นเป็นการตั้งค่าการดีบักขั้นต่ำที่สมบูรณ์แบบ
หม้อต้มขนาดกลาง
ในขณะที่ฉันใช้เอกสารสำเร็จรูปชุดแรกสำหรับการสาธิตอย่างรวดเร็วเท่านั้น แต่เอกสารสำเร็จรูปชุดที่สองสามารถใช้สำหรับหน้าที่ซับซ้อนได้ ตัวอย่างสร้างสิ่งต่อไปนี้:
- โครงสร้างไซต์พื้นฐาน
- เมตาแท็ก
viewport
, - ชื่อหน้า
-
.no-js
/.js
คลาส - หน้าจอภายนอกและสไตล์ชีตการพิมพ์
-
description
และเมตาแท็กtheme-color
- โครงสร้างหน้า.
{ "!!": "{<!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" }
ใช่ ฉันรู้ มันดูเหมือนพูดพล่อยๆ มาวิเคราะห์กัน
ทำให้พังถล่ม
doctype
และองค์ประกอบ root เหมือนกับในตัวอย่างแรก แต่มีคลาส no-js
เพิ่มเติมและความคิดเห็นที่เตือนให้ฉันเปลี่ยนแอตทริบิวต์ lang
หากจำเป็น
{<!DOCTYPE html>}+html[lang=${1}${lang}].no-js>{ }
ส่วนขยาย TODO Highlight ทำให้ความคิดเห็นโดดเด่นมาก
<head>
ประกอบด้วยเมตาแท็ก charset
เมตาแท็ก viewport
<title>
{}
สร้างบรรทัดใหม่
(head>meta:utf+meta:vp+{}+title{${1: Change me}}+{}
สคริปต์ที่มีบรรทัดของ JavaScript ฉันกำลังตัดมัสตาร์ดที่รองรับโมดูล JS หากเบราว์เซอร์รองรับโมดูล JavaScript แสดงว่าเป็นเบราว์เซอร์ที่รองรับ JavaScript รุ่นใหม่ (เช่น โมดูล ไวยากรณ์ ES 6 การดึงข้อมูล และอื่นๆ) ฉันจัดส่ง JS ส่วนใหญ่ไปยังเบราว์เซอร์เหล่านี้เท่านั้น และฉันใช้คลาส js
ใน CSS หากการจัดรูปแบบขององค์ประกอบแตกต่างกัน เมื่อ JavaScript ทำงานอยู่
(script[type=\"module\"]>{document.documentElement.classList.replace('no-js', 'js');})+{}
สอง <link>
องค์ประกอบ; ลิงก์แรกไปยังสไตล์ชีตหลักและลิงก์ที่สองไปยังสไตล์ชีตการพิมพ์
link:css+link:print+{}
คำอธิบายหน้า:
meta[name=\"description\"\][content=\"${2: Change me (up to ~155 characters)}\"]+{ }
เมตาแท็ก theme-color
:
meta[name=\"theme-color\"\][content=\"${2:#FF00FF}\"])
องค์ประกอบเนื้อหาและโครงสร้างหน้าพื้นฐาน:
body>page
ต้นแบบสุดท้ายมีลักษณะดังนี้:
<!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 เต็ม
ต้นแบบเต็มรูปแบบจะคล้ายกับต้นแบบที่สอง ความแตกต่างคือ meta
แท็กเพิ่มเติมและแท็ก script
ตัวอย่างสร้างสิ่งต่อไปนี้:
- โครงสร้างไซต์พื้นฐาน
- เมตาแท็ก
viewport
, - ชื่อหน้า
- คลาส
js
/no-js
- หน้าจอภายนอกและสไตล์ชีตการพิมพ์
-
description
และเมตาแท็กเปิดกราฟ - เมตาแท็ก
theme-color
, - แท็ก
<link>
บัญญัติ - แท็ก Favicon,
- โครงสร้างหน้า
- <
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\"]" }
ตัวอย่างข้อมูลที่ยาวอย่างไม่น่าเชื่อนี้สร้างสิ่งนี้:
<!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>
ตัวอย่าง CSS ที่กำหนดเอง
เพื่อความสมบูรณ์ นี่คือข้อมูลโค้ด CSS บางส่วนที่ฉันใช้
แก้จุดบกพร่อง
ตัวอย่างนี้สร้างโครงร่างสีแดงขนาด 5px พร้อมออฟเซ็ตแบบกำหนดเอง
"debug": "outline: 5px solid red;\noutline-offset: -5px;"
ตั้งศูนย์
ตัวอย่างที่ตั้งค่าการ display
ให้โค้งงอ และจัดกึ่งกลางรายการย่อย
"center": "display: flex;\njustify-content: center;\nalign-items: center;"
เหนียว
ตั้งค่าคุณสมบัติ position
เป็น sticky
โดยมีสองแท็บหยุดที่คุณสมบัติ top
และ left
"sticky": "position: sticky;\ntop: ${1:0};\nleft: ${2:0};"
ตัวอย่างผู้ใช้
ในตอนต้นของบทความนี้ ฉันกล่าวว่า VS Code ยังมีตัวอย่างข้อมูลที่กำหนดเองอีกด้วย ความแตกต่างของข้อมูลโค้ด Emmet คือ คุณไม่สามารถใช้ตัวย่อได้ แต่คุณยังสามารถกำหนดแท็บหยุดและใช้ประโยชน์จากตัวแปรภายในได้
วิธีใช้ตัวอย่างข้อมูลผู้ใช้ให้เกิดประโยชน์สูงสุดอาจเป็นหัวข้อสำหรับบทความอื่น แต่นี่คือตัวอย่างข้อมูลโค้ด CSS ที่กำหนดเองซึ่งฉันได้กำหนดไว้:
"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." }
ข้อมูลโค้ดนี้ไม่เพียงแค่สร้างกฎ CSS เท่านั้น แต่ยังสร้างบล็อกการประกาศทั้งหมดเมื่อเราพิมพ์ vh
และกด Enter หรือ 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; }
คำพูดสุดท้าย
ต้องใช้เวลาพอสมควรในการสร้างตัวอย่างข้อมูลเหล่านี้ แต่ก็คุ้มค่ากับความพยายามเพราะคุณปรับแต่ง Emmet ให้เข้ากับความชอบส่วนตัวของคุณ ทำงานซ้ำๆ โดยอัตโนมัติ และประหยัดเวลาในระยะยาว
ฉันชอบที่จะดูว่าคุณใช้ตัวอย่างใด ดังนั้นโปรดแบ่งปันกับเราในความคิดเห็น หากคุณต้องการใช้การตั้งค่าของฉัน คุณสามารถค้นหา snippets.json สุดท้ายของฉันได้ที่ GitHub
ทรัพยากร
- ตัวอย่าง CSS Emmet เริ่มต้น
- ตัวอย่าง HTML Emmet เริ่มต้น
- แผ่นโกง Emmet
- Emmet ใน VS Code docs