عرّف الرسم مرة واحدة داخل <symbol> في SVG، ثم أشر إلى معرّفه باستخدام <use> داخل كل عنصر SVG ظاهر. امنح كل نسخة حجمها الخاص، ودع CSS يرتب بقية الصفحة. بنية مستند SVG.
هذا الدليل موجّه إلى من يحرر صفحة HTML على جهاز Mac ويريد وضع الرسم الصغير نفسه بجوار عدة تسميات نصية. يستخدم المثال الكامل مربعات اصطناعية وHTML عاديًا وCSS. ولا يحتاج إلى إطار عمل أو JavaScript أو رسومات مُنزّلة أو خطوة بناء.
كيف ينتج رمز واحد عدة رسومات ظاهرة؟
<symbol> قالب رسومي. لا يظهر بمفرده؛ إذ ينشئ مرجع <use> نسخة ظاهرة منه. ضع التعريف مرة واحدة في المستند، ثم أضف غلاف SVG صغيرًا في كل موضع تريد ظهور الرسم فيه. توثّق MDN أن العنصرين متاحان على نطاق واسع. MDN: symbol.
من المهم التمييز بين تجنب تكرار المسارات في الشيفرة المصدرية المكتوبة وتجنب عمل التصيير في المتصفح. تحتوي HTML لديك على تعريف مسار واحد، لكن المتصفح يظل ينشئ نسخة مصيّرة لكل <use>. تصف MDN ذلك بأنه استنساخ في DOM غير مكشوف. تجعل إعادة الاستخدام الشيفرة المصدرية أسهل في الصيانة؛ لكنها لا تعني أن عدة رسومات ظاهرة تصبح كائنًا واحدًا مصيّرًا. MDN: use.
في صفحة تضم تسميات وأيقونات، أبقِ التسميات في HTML واجعل لكل أيقونة غلاف SVG خاصًا بها. يقرّ معيار WHATWG بأن SVG محتوى مضمّن ومن نمط العبارات والتدفق في HTML، ما يدعم وضع هذه الأغلفة بين محتويات الصفحة العادية. معيار HTML: SVG.
أنشئ صفحة كاملة بتعريف واحد وثلاث نسخ
في محرر نصوص عادي على جهاز Mac، أنشئ ملفًا باسم svg-reuse.html. الصق المستند الكامل أدناه، واحفظه، ثم افتحه في متصفح سطح المكتب. احتفظ بامتداد .html واحفظه كنص عادي، لا كمستند نص منسق.
يعرّف المثال مربعين قطريين باستخدام <path> واحد. وتعرض ثلاثة مراجع الشكل الهندسي نفسه بأحجام وألوان مختلفة. يستخدم كل مرجع href="#demo-tiles"؛ والصيغة href هي الصيغة الحالية، بينما xlink:href مهمل. MDN: سمات use.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Reusable tile symbol</title>
<style>
body {
margin: 2rem;
font-family: system-ui, sans-serif;
color: #263445;
}
.symbol-bank {
position: absolute;
width: 0;
height: 0;
overflow: hidden;
}
.samples {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.sample {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem;
border: 1px solid #cbd5df;
}
.icon {
display: block;
width: 24px;
height: 24px;
flex: none;
}
.icon-large { width: 48px; height: 48px; }
.icon-medium { width: 32px; height: 32px; }
.blue { color: #2457a7; }
.purple { color: #7140a0; }
</style>
</head>
<body>
<svg class="symbol-bank" width="0" height="0" aria-hidden="true">
<symbol id="demo-tiles" viewBox="0 0 24 24"
preserveAspectRatio="xMidYMid meet">
<path fill="currentColor"
d="M4 4H10V10H4Z M14 14H20V20H14Z"></path>
</symbol>
</svg>
<main>
<h1>Tile samples</h1>
<div class="samples">
<div class="sample">
<svg class="icon" width="24" height="24"
viewBox="0 0 24 24" aria-hidden="true">
<use href="#demo-tiles" width="24" height="24"></use>
</svg>
<span>Small tiles</span>
</div>
<div class="sample blue">
<svg class="icon icon-large" width="48" height="48"
viewBox="0 0 24 24" aria-hidden="true">
<use href="#demo-tiles" width="24" height="24"></use>
</svg>
<span>Large tiles</span>
</div>
<div class="sample purple">
<svg class="icon icon-medium" width="32" height="32"
viewBox="0 0 24 24" aria-hidden="true">
<use href="#demo-tiles" width="24" height="24"></use>
</svg>
<span>Medium tiles</span>
</div>
</div>
</main>
</body>
</html>
النتيجة المتوقعة هي ثلاث عينات ذات حدود، تحتوي كل منها على المربعات القطرية نفسها. تستخدم الأولى لون نص الصفحة، والثانية الأزرق، والثالثة الأرجواني. يبلغ مقاس مربعات SVG فيها 24 و48 و32 بكسل CSS. ضيّق نافذة المتصفح للتحقق من كيفية التفاف العينات.
الأشكال الظاهرة هنا للزينة لأن التسميات المجاورة توفّر المحتوى. لذلك تستخدم أغلفة SVG السمة aria-hidden="true". فهي تزيلها من شجرة إمكانية الوصول دون إخفائها بصريًا. استخدم هذه المعالجة للرسومات الزخرفية؛ ولا تطبقها على صورة تحمل معلومات غير موجودة في النص. MDN: aria-hidden.
ما الإعدادات التي تتحكم في تخطيط الصفحة وتخطيط SVG؟
هناك ثلاث مهام منفصلة: ترتيب عناصر HTML، وتحديد حجم كل مربع SVG، وملاءمة الرسم داخل ذلك المربع. وقد لا يؤدي تغيير إعداد خاص بإحدى هذه المهام إلى تغيير المهمتين الأخريين.
| المهمة | الإعداد في المثال | ما الذي ينبغي تغييره؟ |
|---|---|---|
| ترتيب العينات على الصفحة | يستخدم .samples تخطيط flexbox مع التفاف العناصر |
غيّر التباعد أو الالتفاف هنا |
| محاذاة كل رسم مع تسميته | يستخدم .sample تخطيط flexbox وalign-items: center |
غيّر محاذاة المكوّن هنا |
| تحديد حجم مربع SVG المعروض | .icon وفئات الأحجام الخاصة به |
غيّر عرض CSS وارتفاعه هنا |
| تعريف إحداثيات الرسم | viewBox="0 0 24 24" |
غيّره عندما تتغير حدود إحداثيات العمل الفني |
| تحديد الحجم الداخلي للرمز المُشار إليه | لـ<use> عرض وارتفاع بقيمة 24 |
أبقِهما متوافقين مع مساحة الإحداثيات الداخلية لهذا المثال |
| ملاءمة الرسم مع الحفاظ على نسبه | preserveAspectRatio="xMidYMid meet" |
غيّره فقط عندما يكون المقصود سلوك ملاءمة مختلفًا |
يرتب Flexbox العناصر الأبناء المباشرة لحاوية flex. لذلك ترتب الحاوية الخارجية العينات، وترتب كل حاوية داخلية عنصر SVG بجوار تسمية. يعمل Flexbox على بُعد واحد في كل مرة؛ وتتوزع المساحة في الأسطر الملتفة بصورة مستقلة. إذا كان التصميم يتطلب تنسيقًا مشتركًا للصفوف والأعمدة، فـCSS Grid هو البديل المناسب لتخطيط الصفحة. MDN: المفاهيم الأساسية لـFlexbox.
داخل SVG، لـ<use> نموذج تخطيط مختلف. تُزيح قيمتا x وy الرسومات في نظام إحداثيات SVG. ولا تحددان المسافة بين مكوّنات HTML. يمكن للعرض والارتفاع تحديد حجم إطار العرض لرمز مُشار إليه؛ لكنهما لا يوفّران أداة تحجيم عامة عند الإشارة مباشرةً إلى مسار أو مجموعة. W3C: تخطيط الرسومات المعاد استخدامها.
لماذا تظل أبعاد النسخة الكبيرة الداخلية 24؟
يصف viewBox في عنصر SVG الخارجي مساحة إحداثيات أبعادها 24 × 24. يمكن أن يكون مربع CSS الخاص به 48 × 48 بكسل، مع بقاء إحداثياته الداخلية كما هي. يملأ <use> مساحة الإحداثيات الداخلية ذات الأبعاد 24 × 24، ثم يكيّفها عنصر SVG الخارجي مع المربع الأكبر المعروض. تعرّف MDN viewBox على أنه أربعة أرقام: الحد الأدنى لقيمة x، والحد الأدنى لقيمة y، والعرض، والارتفاع. MDN: viewBox.
في حساب توضيحي يستخدم هذا العمل الفني بعينه، يكيّف مربع حجمه 48 بكسل 24 وحدة إحداثيات بمقياس 48 / 24 = 2. وتمتد هندسة المربعات من الإحداثي 4 إلى الإحداثي 20، لذا يصبح إجمالي نطاقها المرسوم (20 - 4) × 2 = 32 بكسل. وتأتي المساحة المتبقية من الهوامش المقصودة داخل الرسم.
يوضح هذا لماذا لا يؤدي زيادة عرض الأيقونة في CSS بالضرورة إلى جعل شكلها المرسوم يملأ العرض كله. تحقّق من حدود الأشكال الهندسية داخل viewBox قبل تعديل هوامش الصفحة للتعويض.
ماذا يحدث داخل مربع SVG مستطيل؟
مع xMidYMid meet، يُكبّر الرسم أو يُصغّر بالتساوي، ويبقى في المنتصف، ويلائم مساحة العرض المتاحة بالكامل. لذلك يترك الرسم المربع داخل مستطيل عريض مساحة على الجانبين. تسمح none بالتشويه؛ أما slice فتحافظ على النسب، لكنها تسمح بامتداد جزء من viewBox خارج مساحة العرض. استخدم meet عندما ينبغي أن يظل الرسم كاملًا ظاهرًا. MDN: preserveAspectRatio.
كيف يمكن منح كل نسخة لونًا خاصًا بها؟
يستخدم المسار fill="currentColor". تأخذ هذه الكلمة المفتاحية قيمة color للعنصر، ما يسمح للرسم نفسه باتباع لون النص المحيط. في المثال، يؤدي تغيير قاعدة .blue أو .purple إلى تغيير لون التسمية والمربعات معًا. MDN: الكلمة المفتاحية currentColor.
يعمل ذلك عن طريق التوارث داخل كل نسخة. يمنح نموذج إعادة الاستخدام في SVG المحتوى المُنشأ الأنماط الموروثة من عنصر <use> المضيف. وسيكون للون ثابت مُعرّف مباشرةً على مسار المصدر أولوية على تعبئة موروثة يوفّرها عنصر أب. أبقِ الهندسة المشتركة خالية من الألوان الثابتة عندما تحتاج إلى تلوين كل نسخة على حدة. W3C: نطاق الأنماط والتوارث.
تجنّب الاعتماد على محدد مثل .blue path للوصول إلى مسار مُنشأ عبر الغلاف الظاهر. ينتمي المحتوى المُنشأ إلى شجرة الظل لإعادة الاستخدام، لذا تختلف علاقات العناصر السلف عن HTML المتداخل العادي. عيّن color على الغلاف أو الحاوية، وأبقِ currentColor في هندسة المصدر. W3C: نطاق الأنماط والتوارث.
ما الذي ينبغي التحقق منه عندما يبدو الرمز المعاد استخدامه غير صحيح؟
ابدأ من المرجع وتحقق باتجاه الخارج. يفصل هذا التسلسل بين غياب الرسم وبين وجود خطأ في حجمه أو موضعه، بحيث يعالج كل تعديل آلية محددة.
- تحقق من الهدف. تأكد من أن
href="#demo-tiles"يطابقid="demo-tiles"في التعريف. اجعل هذا المعرّف فريدًا في شجرة المستند. W3C: سمة id. - تحقق من أبعاد الغلاف الظاهر. أبقِ فئة
.symbol-bankذات الحجم الصفري على حاوية التعريف فقط. تحتاج كل نسخة ظاهرة إلى مربع غير صفري، كما يوضح.icon. - تحقق من حدود الإحداثيات. تأكد من أن العمل الفني يقع ضمن
viewBoxالمُعلن. قد ينتج الفراغ غير المتوقع من إحداثيات رسم غير مستخدمة. MDN: viewBox. - تحقق من نوع العنصر المشار إليه. إذا استبدلت الرمز بمرجع مباشر إلى مسار، فلن يؤدي تغيير عرض
<use>وارتفاعه إلى تحجيمه بالطريقة نفسها. أعد الرمز وviewBoxلهذا النمط. MDN: use. - تحقق من تعريفات الألوان. ابحث عن ألوان ثابتة في المصدر قبل إضافة مزيد من محددات النسخ.
- تحقق من حاوية الصفحة. إذا كان الرسم يظهر صحيحًا لكنه بعيد جدًا عن تسميته، فعدّل الفجوة أو المحاذاة في CSS الخاص بالمكوّن. MDN: المفاهيم الأساسية لـFlexbox.
عند دمج المثال في صفحة موجودة، أدرج بنك الرموز مرة واحدة، وادمج CSS، وانسخ غلاف SVG الظاهر فقط إلى المكوّنات الإضافية. خضع المستند الصغير لفحوص بنيوية للتحقق من توازن العناصر وفرادة المعرّفات ووجود ثلاثة مراجع تشير إلى تعريف مسار واحد؛ لكن هذه الفحوص لا تثبت صحة التصيير في المتصفح. افتح الصفحة في متصفحات Mac التي تنوي دعمها، وافحص الحجم والتباعد واللون الناتج.
لتغيير الرسم المشترك، عدّل تعريف المسار الوحيد. ولتغيير نسخة واحدة، عدّل حجم غلافها أو لونها الموروث. يمنحك الفصل بين هذه المسؤوليات عملًا فنيًا قابلًا لإعادة الاستخدام وتحكمًا متوقعًا في موضع كل نسخة.
المصادر
- بنية المستند — SVG 2 — W3C.
- معيار HTML، إصدار مطوري الويب: SVG — WHATWG.
<symbol>— MDN Web Docs.<use>— MDN Web Docs.- المفاهيم الأساسية لـFlexbox — MDN Web Docs.
- viewBox — MDN Web Docs.
- preserveAspectRatio — MDN Web Docs.
- نوع CSS
<color>— MDN Web Docs. - ARIA: سمة aria-hidden — MDN Web Docs.