Emmet: الصعود `^` والضرب `*`: هياكل شجرية معقدة وعناصر متكررة

غطى الدرس السابق "النزول" بـ > و"الجعل مسطحًا" بـ +. عندما يصبح هيكلك معقدًا بما يكفي بحيث "يحتاج أخ إلى العودة للأعلى مستوى"، يواجه هذان العاملان وحدهما حائطًا — هنا تحتاج ^ للصعود مستوى واحدًا. لإنشاء 5 أو 10 أو أكثر من العناصر المتطابقة دفعة واحدة، استخدم * للتكرار.

1. ما ستتعلمه


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

(1) نقطة الألم: التداخل متعدد المستويات والوقوع "عالقًا عميقًا"

تعيد أليس هيكلة صفحة رئيسية لمتجر إلكتروني، محولة تخطيطًا مسطحًا إلى هيكل HTML5 ثلاثي الأقسام دلالي (header + main + footer). تستخدم body>header+main+footer من الدرس السابق للطبقة الخارجية، ثم تنزل داخل header بـ >nav>ul>li*5>a. لكن بعد إنهاء قسم header، تظهر مشكلة: يجب أن يتبع footer main كأخ، لكنها تجد footer ينتهي داخل header — لأن > يستمر في دفع السياق أعمق وأعمق، و + فقط يلحق في أحدث مستوى.

الأسوأ، تحتاج إلى بناء جدول منتجات بـ 6 صفوف × 5 أعمدة. 6 صفوف بـ *6 لا مشكلة، لكن كل صف يحتاج إلى 5 خلايا td مكررة — كتابة 30 عنصر td يدويًا تعني إما إعادة الكتابة أو كتابة tr>td*5*6 طويلة وصعبة القراءة. تتساءل أليس: ليت * يمكنه التداخل داخل * بشكل صحيح.

(2) كيف يحلها ^ و *

يوفر Emmet عاملين متكاملين لحل كلتا المشكلتين:

الصعود ^: عندما تنتهي من الكتابة عميقًا داخل header وتريد القفز مرة أخرى إلى مستوى body لإلحاق footer، ^ "يصعد للخارج" مستوى واحدًا، عائدًا إلى موضع أخ الأصل. تحتاج أليس فقط إلى إضافة ^ في نهاية شجرة header الفرعية، ثم إلحاق main+footer:

TEXT 📖 للعرض فقط
body>header>nav>ul>li*5>a^^main+footer

^^ يصعد مستويين لأعلى من داخل ul (أولاً خارج ul، ثم خارج nav، عائدًا إلى مستوى header)، لذا +main+footer يصبحان أخوة لـ header.

ا��ضرب *: يمكن وضع * في Emmet بعد أي عنصر لتكراره N مرة — و * يمكنه تداخل > داخله لتشكيل هياكل فرعية. جدول كامل هو سطر واحد:

TEXT 📖 للعرض فقط
table>(tr>td*5)*6

tr>td*5 هو "نمط صف"، مغلف بـ *6 لتكرار النمط 6 مرات. من 30 عنصر td إلى سطر اختصار واحد — من 5 دقائق إلى 8 ثوانٍ.

(3) الفوائد

^ و * هما التركيبة الأساسية لمعالجة "الهياكل المعقدة" في Emmet. الصعود يتيح لك التحكم بدقة في المستوى الذي ينتمي إليه كل عنصر؛ الضرب يتيح لك توليد هياكل متكررة دفعة واحدة في سطر واحد. بعد هذا الدرس، تجمع أليس body>header+main+footer مع ^^^ للتحكم المثالي في المستوى وتكتب جدول 6×5 بـ * في سطر واحد — من 12 دقيقة إلى 25 ثانية. التجميع () في الدرس التالي سيجعل هذه العوامل أقوى عند دمجها.


3. عامل الصعود ^: العودة إلى مستوى الأصل

^ تعني اصعد لأعلى — حرك موضع العناصر اللاحقة للخلف من المستوى الحالي إلى مستوى الأصل. يعالج سيناريو شائعًا: أنهيت شجرة فرعية عميقًا داخل هيكل متداخل وتريد أن يكون العنصر التالي أخًا لـ "جد" بدلاً من البقاء محاصرًا في المستوى الحالي.

الصيغة المعنى
^ اصعد مستوى واحدًا (للخلف مستوى سياق واحد)
^^^ اصعد 3 مستويات
^bq مكافئ لـ +bq في مستوى الأصل اصعد وألحق عنصرًا فورًا

(1) توضيح الصعود الفردي

جزء الاختصار الشكل الفرق الرئيسي
div+div>p>span+em^bq bq هو أخ لـ p (داخل div الثاني) ^ يشغل الصعود
div+div>p>span+em+bq bq هو أخ لـ span و em (داخل p) بدون ^، لا يزال في مستوى p

نقطة أساسية: الصعود هو أحد أكثر عوامل Emmet إرباكًا للمبتدئين. "السياق السابق" يشير إلى العقدة الأصلية في شجرة الصياغة، وليس "آخر عنصر كتبته." بعبارة أخرى، في div>ul>li^p، ^ يجعل p أخًا لـ ul (كلاهما داخل div)، وليس أخًا لـ li (داخل li).


4. عامل الضرب *: تكرار العناصر دفعة واحدة

*N تعني كرر — ضاعف العنصر السابق N مرة. هذا هو العامل الأساسي لـ Emmet لمعالجة الهياكل المتكررة مثل "N عنصر قائمة،" "N صف جدول،" و "N بطاقة."

الصيغة المعنى
li*5 5 عناصر li
div.card*3 3 عناصر div.card (div ضمني، الدرس 3)
tr>td*6 tr واحد يحتوي على 6 td
(tr>td*6)*5 5 tr، كل منها يحتوي على 6 td (تجميع، الدرس 6)

نصيحة: N في *N يجب أن يكون عددًا صحيحًا موجبًا. *1 صالح (مكافئ لعدم التكرار) لكن عادة يُبسط إلى الصيغة المفردة. *0 في Emmet يتوسع إلى لا شيء (لا يولد عناصر).

(1) نطاق الضرب

* ينطبق فقط على العنصر السابق مباشرة، متبعًا قاعدة "السياق المحلي". لتكرار شجرة فرعية متداخلة كاملة كوحدة، يجب استخدام الأقواس () للتجميع (الدرس 6):

الاختصار نطاق التكرار استخدام خاطئ (محاولة التكرار ككل بدون أقواس)
ul>li*3 3 li
ul>li*3>a 3 li، كل منها يحتوي على a واحد
tr>td*5*6 فقط 5 td؛ *6 يكرر tr ككل (Emmet يحلل كـ 5 td إجمالاً، tr مكرر 6 مرات) "لـ 6 صفوف × 5 أعمدة" استخدم (tr>td*5)*6

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

تغطي الأمثلة الخمسة التالية جميع السيناريوهات الأساسية لـ ^ و * — من الصعود الفردي إلى الصعود متعدد المستويات، من التكرار البسيط إلى التكرار المجمع المتداخل.

▶ مثال: صعود فردي div+div>p>span+em^bq (الصعوبة: ★★)

المشكلة المتبقية من الدرس السابق: كيفية جعل bq أخًا لـ p. الإجابة هي إضافة ^.

الاختصار:

HTML
div+div>p>span+em^bq

يتوسع إلى:

HTML
<div></div>
<div>
  <p><span></span><em></em></p>
  <blockquote></blockquote>
</div>

الناتج:

TEXT 📖 للعرض فقط
التحليل: div+div ينشئ divين أخوين، >p ينزل داخل div الثاني لوضع p، >span+em يضع أخوين داخل p. أخيرًا، ^ يشغل صعودًا: من مستوى p لأعلى إلى مستوى div (أصل p)، لذا bq يصبح أخًا لـ p — كلاهما أبناء لـ div الثاني. بدون ^، سينتهي bq داخل p، أخًا لـ span و em.

▶ مثال: صعود متعدد المستويات div+div>p>span+em^^^bq (الصعوبة: ★★)

ثلاث ^ متتالية تصعد طوال الطريق إلى مستوى الجذر.

الاختصار:

HTML
div+div>p>span+em^^^bq

يتوسع إلى:

HTML
<div></div>
<div>
  <p><span></span><em></em></p>
</div>
<blockquote></blockquote>

الناتج:

TEXT 📖 للعرض فقط
`^^^` يصعد ثلاث مرات: الأولى من p إلى div الثاني، الثانية من div الثاني إلى الجذر، الثالثة تحاول مجددًا من الجذر لكن لا يوجد "مستوى أعلى" (تبقى في مكانها). لذا bq ينتهي كأخ لـ div الثاني، ابنًا مباشرًا للجذر. ملاحظة: مستوى الجذر ليس له حاوية صريحة (لا يوجد div أبعد)، لذا bq يظهر بجانب div. هذا "الاختصار بدون جذر" يُغلف تلقائيًا بـ `<body>` في المتصفحات، لكن كن واعيًا لكيفية تأثير تغييرات المستوى على محددات CSS اللاحقة.

▶ مثال: الضرب ul>li*5 (الصعوبة: ★)

أبسط "توليد دفعة لـ 5 عناصر li."

الاختصار:

HTML
ul>li*5

يتوسع إلى:

HTML
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

الناتج:

TEXT 📖 للعرض فقط
5 عناصر li فارغة، جميعها أبناء مباشرون لـ ul. `*5` يعمل مباشرة على li — لا حاجة لهيكل معقد. هذا هو نمط Emmet الأعلى ترددًا لـ "قائمة تنقل بـ 5 عناصر،" "قائمة مهام بـ 5 عناصر،" "5 بطاقات ميزات،" وسيناريوهات مماثلة. اقرن مع ملء المحتوى (الدرس 9) لإعطاء كل عنصر نصًا مختلفًا.

▶ مثال: تكرار + تداخل ul>li*3>a (الصعوبة: ★)

التركيبة الكلاسيكية > + *a كالابن الوحيد لكل li.

الاختصار:

HTML
ul>li*3>a

يتوسع إلى:

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

الناتج:

TEXT 📖 للعرض فقط
`*3` يكرر li فقط، وكل li يحتوي على a واحد عبر >. لتكرار a أيضًا (3 a لكل li)، استخدم الأقواس: ul>li*>a*3 أو غلف a في مجموعة. لتكرار "(li و a)" كوحدة، استخدم (li>a)*3 (الدرس 6، التجميع). هذا فخ "نطاق" كلاسيكي في Emmet.

المثال المدمج لهذا الدرس: ضرب متداخل + تجميع (() من الدرس 6 — معاينة هنا).

الاختصار:

HTML
(div>dl>(dt+dd)*3)+footer>p

يتوسع إلى:

HTML
<div>
  <dl>
    <dt></dt>
    <dd></dd>
    <dt></dt>
    <dd></dd>
    <dt></dt>
    <dd></dd>
  </dl>
</div>
<footer>
  <p></p>
</footer>

الناتج:

TEXT 📖 للعرض فقط
التحليل: الأبعد (div>dl>...) يعمل كمجموعة، ويعمل "كجذر افتراضي." داخل المجموعة، div يحتوي على dl، و (dt+dd)*3 داخل dl يكرر زوج الأخوة dt+dd 3 مرات. ثم + يجعل footer أخًا لـ div (footer هو شجرة فرعية منفصلة ومستقلة)، و >p داخل footer يضع p. سطر الاختصار الكامل يتوسع إلى 13 سطرًا من HTML: 1 dl، 6 dt/dd، 1 footer، 1 p. هذا هو نمط Emmet النموذجي لكتابة كتلة قائمة تعريفات في سطر واحد.

6. مثال كامل: جد��ل منتجات 6×5

استخدم * المتداخل والتجميع لبناء جدول منتجات بـ 6 صفوف و 5 أعمدة بسطر اختصار واحد.

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

الاختصار:

HTML
table>(tr>td*5)*6

يتوسع إلى:

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

الناتج:

TEXT 📖 للعرض فقط
التحليل: tr>td*5 هو قالب "صف واحد من الخلايا،" و *6 الخارجي يكرر هذا القالب 6 مرات. الأقواس (tr>td*5) تضمن أن td*5 ينطبق فقط داخل tr (5 td كلها في نفس tr)، بدلاً من أن يتكرر مباشرة بواسطة *6 الخارجي. عاملا * متداخلان يشكلان شبكة ثنائية الأبعاد. بدون أقواس، tr>td*5*6 سيظل ينتج نتيجة 6×5 (Emmet يحلله كـ 5 td لكل tr، tr مكرر 6 مرات)، لكن الدلالات غير واضحة — لا يُنصح به.

❓ أسئلة شائعة

س قبل وجود عامل ^، كيف كان الناس يتعاملون مع احتياجات الصعود؟
ج الإصدارات المبكرة من Emmet فعلًا لم يكن لها عامل صعود. كان عليك استخدام "تجميع + إعادة نزول" لمحاكاة الصعود. على سبيل المثال، div>header>p+span^(main+footer) لم يكن موجودًا؛ كنت ستكتب (header>p+span)+(main+footer) باستخدام التجميع كحل بديل. لكن التجميع أقل قابلية للقراءة ويتطلب إعادة النزول. أضيف ^ في 2013 كـ "فتحة هروب" خصيصًا لحل نقطة الألم هذه.
س هل يمكن لـ ^ الصعود طوال الطريق إلى الجذر؟ ماذا يحدث إذا صعدت بعيدًا جدًا؟
ج نعم، يمكنك الاستمرار في الصعود، لكن فقط حتى الجذر (الجذر الافتراضي). الصعود متجاوزًا الجذر (مثل ^^^^^bq في مستوى الجذر) يبقى فقط في الجذر — لا خطأ. يعامل Emmet الجذر كـ "الطابق الأرضي،" ويتم تجاهل رموز ^ الزائدة بصمت.
س إلى ماذا يتوسع li*0؟
ج *0 في Emmet الرسمي يولد 0 عناصر (متخطى تمامًا)، لكن بعض تطبيقات المحررات قد تترك عنصر li فارغًا واحدًا. تجنب كتابة *0 — فقط اكتب li بشكل صريح. إذا توقعت "0 عناصر" وأعطاك محررك عنصرًا فارغًا واحدًا، فهذا اختلاف في تنفيذ المحرر.
س في div>span*3>p، أين ينتهي p؟
ج يتوسع إلى <div><span><p></p></span><span><p></p></span><span><p></p></span></div> — p هو ابن لكل span (لأن أقرب سياق هو span). *3 يكرر span فقط، و p يتبع كل span. هذا أحد أكثر الأنماط إرباكًا للمبتدئين: التمييز بين نطاق * (فقط العنصر السابق مباشرة) ونطاق > اللاحق (أقرب سياق).

📖 ملخص


📝 تمارين

  1. أساسي (الصعوبة: ★): اكتب 3 اختصارات Emmet باستخدام * تتوسع إلى: (أ) 5 li؛ (ب) 1 ul يحتوي على 3 li، كل li يحتوي على 1 a؛ (ج) 1 ul يحتوي على 1 li، الـ li يحتوي على 3 a.
  2. متوسط (الصعوبة: ★★): حلل كيف يجب أن يتوسع (nav>ul>li*3>a)+main+footer (ارسمه على الورق أولاً، ثم تحقق بالتوسيع). ثم أعد كتابته كنسخة مكافئة باستخدام ^ (بدون أقواس).
  3. متقدم (الصعوبة: ★★★): اكتب اختصار Emmet واحدًا لجدول شطرنج 8×8 (الخلية الأولى هي <th> عنوان، والباقي <td>). اشرح لماذا يتطلب هذا الهيكل الأقواس للتجميع. اكتب أيضًا "النسخة الخاطئة" بدون أقواس وقارن نتائج التوسيع الفعلية.
Web-Tutorial.com

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

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

100%