Emmet: التجميع `()` والوسوم الضمنية

(div>dl>(dt+dd)*3)+footer>p من الدرس السابق استعرض بالفعل قوة "تجميع الأقواس" — إنه يحصر > و + للعمل فقط داخل ()، بينما يعود الأخوة الخارجيون إلى مستوى المجموعة. يغطي هذا الدرس () بشكل منهجي، ثم يدمجها مع "أسماء الوسوم الضمنية" من الدرس 3 لتحقيق "توليد صفحة HTML كاملة من سطر اختصار واحد."

1. ما ستتعلمه


2. قصة حقيقية لمطور واجهة أمامية

(1) نقطة الألم: الهياكل المعقدة تؤدي إلى "فوضى التداخل"

تبني أليس صفحة قائمة لوحة تحكم إدارية تحتاج إلى جدول بـ 5 صفوف و 3 أعمدة مع رؤوس <th> و 5 صفوف بيانات أدناه. تستخدم * من الدرس 5 لكتابة (tr>td*3)*5، لكنها تواجه بسرعة مشكلتين جديدتين.

أولاً، (tr>td*3)*5 ينتج 5 صفوف × 3 أعمدة، لكن شريط الترقيم يجب أن يكون خارج </table> — تريد <table> ككتلة كاملة مع المرقم كأخ له. تحاول إلحاق +nav.pagination في النهاية:

TEXT 📖 للعرض فقط
table>(tr>td*3)*5+nav.pagination

بعد التوسيع، تجد nav ينتهي داخل table، لأن *5 يكرر tr 5 مرات والسياق بأكمله الآن داخل table — +nav في الواقع يلحق nav بعد tr الخامس، مدمرًا الهيكل.

ثانيًا، كل صف من صفوف البيانات الخمسة له الفئة .row. تكتب table>(tr.row>td*3)*5، لكنه مطول. إذا كانت كل الخلايا لها .cell، ستحتاج table>(tr.row>(td.cell)*3)*5 — أكثر تعقيدًا. تتساءل: هل يمكنها كتابة table>(.row>(.cell)*3)*5؟ هل .cell داخل سياق tr يصبح تلقائيًا td؟ هل .row داخل سياق table يصبح تلقائيًا tr؟

(2) كيف يحلها تجميع () والوسوم الضمنية

يوفر Emmet آليتين متكاملتين لحل مشكلات أليس:

الأقواس (): تجعل "الشجرة الفرعية المجمعة" وحدة أخوة مستقلة، بحيث لا يتسرب + الخارجي إلى داخل المجموعة. تتطلب مشكلة الترقيم لدى أليس معاملة (tr>td*3)*5 كـ "مجموعة افتراضية" واحدة، ثم إلحاق +nav خارجها — أو استخدام ^ من الدرس 5 للصعود للخارج.

أسماء الوسوم الضمنية: يقوم Emmet تلقائيًا بتبديل الوسوم الضمنية بناءً على "سياق العنصر الأصلي" — .row داخل table يصبح تلقائيًا <tr>، .cell داخل table يصبح تلقائيًا <td>، .item داخل ul يصبح تلقائيًا <li>، .opt داخل select يصبح تلقائيًا <option>. يصبح جدول أليس 5×3:

TEXT 📖 للعرض فقط
table>(.row>.cell*3)*5

.row يصبح ضمنيًا <tr>، .cell يصبح ضمنيًا <td> — كل شيء في سطر واحد.

(3) الفوائد

() والوسوم الضمنية هما التركيبة المتقدمة لـ Emmet. الأقواس تمنحك تحكمًا دقيقًا في "النطاق"؛ الوسوم الضمنية تتيح لك حذف أسماء الوسوم الأكثر شيوعًا. بعد هذا الدرس، تستخدم أليس تجميع () لكتابة اختصارات صفحات كاملة واضحة الهيكل وتستخدم الوسوم الضمنية لتخطي 30% من كتابة أسماء الوسوم. هيكل HTML الكامل لصفحة القائمة الإدارية ينتقل م�� 80 سطرًا مكتوبًا يدويًا إلى سطري اختصار — 5 دقائق من العمل تتقلص إلى 8 ثوانٍ.


3. التجميع (): عزل النطاق

() يعامل الاختصار الداخلي كـ شجرة فرعية مستقلة. > و + و * المستخدمة داخلها لا تتسرب للخارج؛ عندما تلحق عناصر + خارج المجموعة، يشير موضع الإلحاق إلى العنصر الأول داخل المجموعة، وليس المستوى الأعمق.

(1) مقارنة بصرية: مجمع مقابل غير مجمع

100%
graph TB
    subgraph "بدون تجميع: div>header>p"
        A1[div] --> B1[header]
        B1 --> C1[p]
    end
    subgraph "مع تجميع: div>(header>p)+footer"
        A2[div] --> B2[header]
        A2 --> D2[footer]
        B2 --> C2[p]
    end
الاختصار موضع p موضع footer
div>header>p+footer ابن header ابن header (أخ لـ p)
div>(header>p)+footer ابن header ابن div (أخ لـ header)

نقطة أساسية: الوظيفة الحرجة لـ () هي كسر سلسلة النزول. (header>p) يغلف النزول داخل الأقواس؛ +footer الخارجي يستأنف من مستوى السياق قبل الأقواس (هنا، داخل div)، وليس من مستوى p. هذا هو سبب أن التجميع يجعل header و footer أخوة.


4. أسماء الوسوم الضمنية: تبديل تلقائي واعٍ بالسياق

أسماء الوسوم الضمنية هي آلية إنتاجية رئيسية أخرى في Emmet. في سياق العنصر الأصلي، حذف اسم الوسم لا يكون افتراضيًا div — بدلاً من ذلك، يستنتج "العنصر الابن المنطقي" بناءً على الأصل.

العنصر الأصلي الاختصار الوسم الضمني التوسيع
ul .item li <li class="item"></li>
ol .item li <li class="item"></li>
table .row tr <tr class="row"></tr>
table .cell td <td class="cell"></td>
select .opt option <option class="opt"></option>
tbody .row tr <tr class="row"></tr>
thead .cell th <th class="cell"></th>
dl .term dt <dt class="term"></dt>
dl .def dd <dd class="def"></dd>
غير ذلك .class div <div class="class"></div> (قاعدة الدرس 3)

نصيحة: أسماء الوسوم الضمنية تؤثر فقط على الحالات التي لا يُحدد فيها اسم وسم. إذا كتبت اسم وسم بشكل صريح (مثل div.item)، يتم تجاوز القاعدة الضمنية — تبقى <div class="item">.

(1) مقارنات ضمني مقابل صريح شائعة

الصيغة التوسيع
.item (بدون أصل) <div class="item"></div>
ul>.item <ul><li class="item"></li></ul>
table>.row <table><tr class="row"></tr></table>
table>tbody>.row <table><tbody><tr class="row"></tr></tbody></table>

5. أمثلة عملية

تغطي الأمثلة الأربعة التالية الاستخدام المدمج الأساسي لـ () والوسوم الضمنية — من مثال العرض الرسمي للتوثيق إلى أنماط القوائم/الجداول عالية التردد في الممارسة.

هذا هو مثال العرض الرئيسي لتوثيق Emmet، يوضح كيف يجعل () footer أخًا لـ header.

الاختصار:

HTML
div>(header>ul>li*2>a)+footer>p

يتوسع إلى:

HTML
<div>
  <header>
    <ul>
      <li><a href=""></a></li>
      <li><a href=""></a></li>
    </ul>
  </header>
  <footer>
    <p></p>
  </footer>
</div>

الناتج:

TEXT 📖 للعرض فقط
حلل الأقواس: الخارجي (header>ul>li*2>a) يغلف شجرة header الفرعية كوحدة مستقلة. +footer خارج الأقواس لم يعد متأثرًا بـ *2 ويصبح أخًا لـ header — كلاهما أبناء لـ div. li*2 ينتج 2 li داخل header، كل منهما يحتوي ضمنيًا على 1 a. بدون أقواس، div>header>ul>li*2>a+footer>p سيجعل footer أخًا لـ a (داخل ul)، وليس أخًا لـ header.

▶ مثال: جدول بوسوم صريحة table>(tr>td*3)*2 (الصعوبة: ★★)

جدول 2×3 بـ tr/td صريحين — يوضح دور التجميع في الهياكل المتكررة.

الاختصار:

HTML
table>(tr>td*3)*2

يتوسع إلى:

HTML
<table>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>

الناتج:

TEXT 📖 للعرض فقط
tr>td*3 هو قالب "صف واحد من 3 خلايا،" و (tr>td*3)*2 يكرر هذا القالب مرتين. الأقواس تعزل *2 عن علاقة td — بدونها، tr>td*3*2 سيُحلل كـ "td مكرر 3 مرات" و "tr مكرر مرتين،" الذي يصادف أيضًا أنه ينتج 2×3، لكن الدلالات غير واضحة. الأقواس تجعل القصد الهيكلي واضحًا. ملاحظة: النسخة المختصرة لهذا المثال يمكنها استخدام الوسوم الضمنية — table>(.row>.cell*3)*2 يتوسع إلى نفس الهيكل بكتابة أقل.

▶ مثال: قائمة بوسوم ضمنية ul>.item*3>a (الصعوبة: ★)

.item داخل سياق ul يصبح ضمنيًا li، كل منها يحتوي على 1 a.

الاختصار:

HTML
ul>.item*3>a

يتوسع إلى:

HTML
<ul>
  <li class="item"><a href=""></a></li>
  <li class="item"><a href=""></a></li>
  <li class="item"><a href=""></a></li>
</ul>

الناتج:

TEXT 📖 للعرض فقط
داخل سياق ul، `.item` يُستنتج تلقائيًا كـ li بواسطة Emmet. `*3` يكرر 3 li، كل منها يحتوي على 1 a عبر >. هذا أحد أكثر اختصارات Emmet شيوعًا لـ "قائمة تنقل بـ 3 عناصر." لتكرار عنصر a أيضًا، إما اكتب ul>.item*3>a*3 (3 a لكل li) أو ul>(.item>a)*3 (كرر الوحدة الكاملة 3 مرات). بدون أقواس، a*3 يعمل على a الموجود في أقصى اليمين فقط (فقط 1 a لكل li، و a لا يتكرر).

هيكل صفحة كاملة في اختصار واحد: تنقل، منطقة رئيسية، وتذييل — كلها في نفس المستوى.

الاختصار:

HTML
(nav>ul>li*3)+main+footer

يتوسع إلى:

HTML
<nav>
  <ul>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</nav>
<main></main>
<footer></footer>

الناتج:

TEXT 📖 للعرض فقط
التحليل: الأبعد (nav>ul>li*3) يجعل شجرة nav الفرعية وحدة مستقلة. +main و +footer خارج الأقواس يرتكزان على nav (العنصر الأول في المجموعة) ويصبحان أخوة لـ nav. لكن بما أن nav ليس له أصل صريح، main و footer ينتهيان في مستوى الجذر — هذه بالضبط الحالة التي يغلف فيها المتصفح تلقائيًا بـ `<body>`. لفرض nav داخل body، يجب أن يكون الاختصار `body>(nav>ul>li*3)+main+footer`.

6. مثال كامل: جدول بيانات 5×3 مع نسخة ضمنية

ادمج الوسوم الضمنية + التجميع + الضرب لبناء جدول بـ 5 صفوف و 3 أعمدة في اختصار واحد — وقارن صيغة "صريح" مقابل "ضمني."

▶ مثال: جدول بيانات 5×3 (الصعوبة: ★★)

الاختصار (النسخة الضمنية):

HTML
table>(.row>.cell*3)*5

يتوسع إلى:

HTML
<table>
  <tr class="row">
    <td class="cell"></td>
    <td class="cell"></td>
    <td class="cell"></td>
  </tr>
  <tr class="row">
    <td class="cell"></td>
    <td class="cell"></td>
    <td class="cell"></td>
  </tr>
  <tr class="row">
    <td class="cell"></td>
    <td class="cell"></td>
    <td class="cell"></td>
  </tr>
  <tr class="row">
    <td class="cell"></td>
    <td class="cell"></td>
    <td class="cell"></td>
  </tr>
  <tr class="row">
    <td class="cell"></td>
    <td class="cell"></td>
    <td class="cell"></td>
  </tr>
</table>

الناتج:

TEXT 📖 للعرض فقط
قارن مع النسخة الصريحة table>(tr>td*3)*5: كلاهما يتوسع إلى نفس النتيجة. ميزة النسخة الضمنية: الاختصار أقصر (18 حرفًا م��ابل 21)، والدلالات أوضح (أسماء الفئات تنقل قصد "صف/خلية"). ومع ذلك، تنكسر النسخة الضمنية عندما يتغير العنصر الأصلي: table>(.row>td*3)*5 لا يزال يعمل لأن .row يصبح ضمنيًا tr و td صريح — نفس النتيجة. لكن section>(.row>.cell*3)*5، حيث section ليس جدولاً، يعني أن .row يتراجع إلى div وينهار الهيكل بالكامل. قاعدة عامة: "الوسوم الضمنية تعمل فقط في سياق العنصر الأصلي الصحيح؛ في السياقات الخاطئة تتراجع إلى div."

❓ أسئلة شائعة

س كيف تختلف الأقواس () عن الأقواس المربعة [attr]؟ أين تستخدم الأقواس المربعة؟
ج () هي للتجميع؛ [] هي للسمات. () دائمًا تفصل هيكل الاختصار؛ [] تتبع اسم وسم (مثل td[colspan=3]) لإضافة سمات مخصصة. الاثنتان لا تتعارضان نحويًا أبدًا. تركيبة شائعة هي (td[colspan=3])*5، وتعني 5 عناصر td لكل منها سمة colspan.
س هل التجميع المتداخل مثل (a>(b>c))+(d>e) صالح؟
ج نعم، وهو شائع. يمكن تداخل الأقواس بشكل عشوائي. الأقواس الداخلية تؤثر فقط ع��ى هيكل شجرتها الفرعية؛ الأقواس الخارجية تعامل "(نتيجة الأقواس الداخلية)" بالكامل كمجموعة واحدة. ترتيب التوسيع: أولاً وسّع الأقواس الداخلية للحصول على شجرة فرعية كاملة، ثم الأقواس الخارجية تعاملها ككل للإلحاق الخارجي. تحذير واحد: إذا كانت الأقواس الداخلية وعناصر + الخارجية في نفس المستوى، يشير الأخ الخارجي إلى العنصر الأول للمجموعة الخارجية.
س إلى جانب ul/table/select، أي العناصر الأخرى لها قواعد ضمنية؟
ج في HTML5، تتركز القواعد الضمنية حول ثلاث فئات — القوائم، الجداول، والنماذج. المتعلقة بالقوائم: li داخل ul/ol، dt/dd داخل dl، a داخل nav. المتعلقة بالجداول: thead/tbody/tfoot داخل table، tr داخل thead/tbody/tfoot، td/th داخل tr، الحذف داخل caption. المتعلقة بالنماذج: option داخل select، option داخل datalist، legend داخل fieldset. جميع سياقات العناصر الأصلية الأخرى تكون افتراضيًا div.

📖 ملخص


📝 تمارين

  1. أساسي (الصعوبة: ★): اكتب اختصارات Emmet مفردة تتوسع إلى: (أ) تنقل بـ 3 عناصر nav>ul>li*3؛ (ب) نفس التنقل باستخدام الوسوم الضمنية nav>ul>.item*3؛ (ج) جدول 2×3 بصيغتي الصريح table>(tr>td*3)*2 والضمني table>(.row>.cell*3)*2 — قارن النتائج.
  2. متوسط (الصعوبة: ★★): صمم هيكل "علامات تبويب": HTML يحتوي على ul (3 li تبويب) و main يحتوي على 3 sections (كل section هو لوحة محتوى واحدة). اكتب اختصار Emmet واحدًا (باستخدام الأقواس والقواعد الضمنية) واشرح لماذا الأقواس ضرورية.
  3. متقدم (الصعوبة: ★★★): باستخدام تجميع الأقواس + الوسوم الضمنية + الضرب مجتمعين، اكتب سطرًا واحدًا لإنتاج جدول منتجات "5 صفوف × 4 أعمدة" حيث يحتوي كل صف منتج على "صورة img، عنوان h3، سعر p.price، وزر إضافة إلى السلة button.btn." اكتب اختصارين متكافئين (أحدهما صريح، الآخر ضمني) وقارن أيهما أكثر قابلية للقراءة وأقل عرضة للخطأ.
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%