تعلّم كيف يعمل الإنترنت، تبني هيكل صفحة، تنسّقها بـ CSS، وتخرج بصفحة شخصية واحدة جاهزة للعرض على العملاء أو في ملفك كمستقل.
كيف تدرس هذا المسار؟
اقرأ ثم جرّب معاينة الكود داخل الصفحة.
انسخ القوالب وعدّل الأسماء والألوان لتناسبك.
ابنِ صفحتك الشخصية خطوة بخطوة.
سجّل تقدّمك بعد كل درس.
مناسب من سن 13 فما فوق، وفي آخر كل درس روابط لمراجعه الرسمية.
1. الإنترنت والمواقع — ببساطة
الهدف: تفهم ماذا يحدث عندما تكتب عنوان موقع في المتصفح، وتعرف أين تبحث حين لا تظهر الصفحة.
عندما تكتب عنواناً مثل example.com في شريط المتصفح وتضغط Enter، تبدو الصفحة كأنها ظهرت فوراً، لكن خلف ذلك سلسلة قصيرة من الخطوات تنتهي عادة في أقل من ثانية. فهم هذه السلسلة يوفر عليك ساعات لاحقاً، لأن كل عطل تقريباً في موقع جديد يقع في حلقة واحدة منها، ومعرفة الحلقة تعني معرفة مكان البحث.
الرحلة في أربع محطات:
1) ترجمة الاسم: الأجهزة على الشبكة تتخاطب بعناوين رقمية تسمى عناوين IP، فيسأل المتصفح نظام أسماء النطاقات (DNS) عن العنوان المرتبط بالاسم، بعد أن يتحقق من ذاكرته المؤقتة وذاكرة نظام التشغيل.
2) فتح الاتصال: يتصل المتصفح بالخادم (Server)، وإذا كان العنوان يبدأ بـ https يتفق الطرفان على مفاتيح تشفير عبر بروتوكول TLS قبل إرسال أي بيانات.
3) الطلب والرد: يرسل المتصفح طلب HTTP يحدد فيه المسار المطلوب، فيرد الخادم برمز حالة ومعه المحتوى، وأول ما يصل عادة ملف HTML.
4) البناء والرسم: يقرأ المتصفح HTML من أعلى إلى أسفل، وكلما صادف إشارة إلى ملف CSS أو صورة أو سكربت أرسل طلباً إضافياً لجلبه، ثم يحسب التخطيط ويرسم الصفحة.
هكذا يبدو الطلب في صيغته النصية المبسطة:
GET /index.html HTTP/1.1
Host: example.com
ويبدأ رد الخادم بسطرين مثل:
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
السطر الأول في الطلب يحوي الطريقة GET ومعناها «أعطني هذا المورد»، ثم المسار، ثم إصدار البروتوكول. ومعظم المواقع الكبيرة تستخدم اليوم HTTP/2 أو HTTP/3، وهما ينقلان المعلومات نفسها بصيغة ثنائية أكفأ، لكن أدوات المطوّر تعرضها لك بالحقول ذاتها: الطريقة والمسار ورمز الحالة والترويسات. وفي الرد يخبر السطر Content-Type المتصفح أن المحتوى صفحة HTML بترميز UTF-8، وهو الترميز الذي يعرض الحروف العربية صحيحة.
رموز الحالة لغة مختصرة تستحق الحفظ. المجموعة 2xx تعني النجاح وأشهرها 200، والمجموعة 3xx تعني إعادة التوجيه مثل 301 حين ينتقل الرابط إلى عنوان دائم جديد، والمجموعة 4xx تعني أن المشكلة في الطلب نفسه مثل 404 «غير موجود»، والمجموعة 5xx تعني أن الخادم تعطل أثناء التنفيذ مثل 500. عندما يشكو زائر من أن صفحة لا تعمل، فأول سؤال تطرحه: ما الرمز الذي ظهر؟
سجل استكشاف أعطال قصير من متجر ملابس صغير في أسيوط أطلق موقعه حديثاً:
• الشكوى الأولى: «المتصفح يقول تعذّر العثور على الخادم». لم يصل أي طلب HTTP أصلاً، فالمشكلة في DNS: النطاق جديد لم تنتشر سجلاته بعد، أو سجلاته غير مضبوطة.
• الشكوى الثانية: الصفحة تظهر بلا ألوان ولا تنسيق. في تبويب Network عاد طلب ملف style.css بالرمز 404، أي أن مسار الملف المكتوب في HTML لا يطابق مكانه على الخادم.
• الشكوى الثالثة: صفحة بيضاء ورمز 500. ملفات HTML وCSS الثابتة لا تسبب هذا الرمز وحدها؛ المشكلة في برنامج يعمل على الخادم، والحل عند مزود الاستضافة أو مطوّر الخلفية.
لكل لغة من لغات الواجهة دور محدد: HTML يصف معنى المحتوى (عنوان، فقرة، رابط، صورة)، وCSS يحدد مظهره (ألوان، خطوط، مسافات، تخطيط)، وJavaScript يضيف السلوك عند النقر أو الكتابة. يركز هذا المسار على الأوليين، لأن صفحة شخصية أو صفحة تعريف بمشروع صغير يمكن أن تُبنى بهما كاملة.
ملاحظة قبل أن تبدأ: حين تفتح ملفك بنقرة مزدوجة يبدأ شريط العنوان بـ file:///، أي أن المتصفح يقرأ الملف من قرصك مباشرة، فلا خادم ولا DNS في القصة. هذا مثالي للتعلم، لكنه يعني أن أحداً غيرك لا يرى الصفحة حتى ترفعها إلى استضافة، وهو موضوع الدرس التاسع.
للتطبيق: افتح أي موقع إخباري، واضغط F12، واختر تبويب Network، ثم أعد تحميل الصفحة. سجّل رمز حالة أول طلب ونوعه، ثم استخدم مرشّح النوع لعدّ ملفات CSS والصور. ستلاحظ أن صفحة واحدة قد تحتاج عشرات الطلبات، ولهذا يؤثر حجم الصور وعدد الملفات مباشرة في سرعة الموقع.
DNS يترجم اسم النطاق إلى عنوان IP قبل إرسال أي طلب HTTP.
رمز الحالة يحدد مكان العطل: 4xx مشكلة في الطلب، و5xx مشكلة في الخادم.
HTML للمعنى، وCSS للمظهر، وJavaScript للسلوك.
الملف المفتوح من file:/// لا يراه أحد غيرك حتى تنشره.
الهيكل
المستخدم
│
▼
[ المتصفح ] ──DNS──▶ عنوان IP
│
├──طلب HTTP──▶ [ الخادم ]
│◀── 200 + HTML ──┘
│◀── CSS + صور (طلبات إضافية)
▼
[ صفحة مرئية ]
مختبر — أول ملف HTML
انسخ الكود في ملف index.html وافتحه بالمتصفح (نقر مزدوج). لا تحتاج خادماً في البداية، ولاحظ أن العنوان يبدأ بـ file:///.
مهمة عملية
افتح موقعاً تستخدمه يومياً وسجّل من تبويب Network: رمز حالة ملف HTML، وعدد طلبات CSS، وعدد الصور، وحجم أكبر ملف. ثم غيّر العنوان والفقرة في ملف المختبر ليعكسا اسمك وهدفك.
اختبر فهمك (1/3)
أي لغة تتحكم في لون النص وحجمه داخل الصفحة؟
اختبر فهمك (2/3)
زائر يرى رسالة «تعذّر العثور على الخادم» ولا يظهر أي طلب HTTP في تبويب Network. أين المشكلة غالباً؟
اختبر فهمك (3/3)
الصفحة تظهر بلا تنسيق، وفي Network عاد طلب style.css بالرمز 404. ما المعنى؟
الهدف: تكتب هيكلاً صحيحاً لأي صفحة عربية، وتستبدل أغلفة div العشوائية بعناصر ذات معنى.
تتكون صفحة HTML من عناصر (Elements) يحتوي بعضها بعضاً كأغصان شجرة. العنصر في الغالب وسم افتتاح ووسم إغلاق وبينهما محتوى، وقد يحمل وسم الافتتاح سمات (Attributes) تضيف معلومات بصيغة اسم="قيمة":
<a href="about.html" title="صفحة التعريف">عني</a>
هنا a اسم العنصر، وhref وtitle سمتان، و«عني» هو المحتوى، و</a> يغلق العنصر. بعض العناصر فارغة لا محتوى لها فلا تُغلق، مثل img وmeta وbr وinput. والقاعدة الذهبية في التداخل: آخر عنصر فُتح هو أول عنصر يُغلق، فالصيغة <p><strong>تنبيه</strong></p> صحيحة، أما عكس ترتيب الإغلاق فخطأ يصلحه المتصفح بصمت، وقد يصلحه بغير ما أردت.
لنأخذ مثالاً تخيّلياً: طالب في كلية الحاسبات بالمنصورة كتب صفحة لمشروع تخرجه بهذا الشكل، وكل شيء فيها div:
الصفحة تبدو سليمة بعد التنسيق، لكنها خرساء لكل من لا يراها: قارئ الشاشة لا يجد عنواناً رئيسياً ولا منطقة تنقل، ومحرك البحث لا يعرف أي نص هو موضوع الصفحة. هذه النسخة نفسها بعد إعادة كتابتها بعناصر دلالية (Semantic HTML):
ماذا تغيّر؟ header يعلن الترويسة، وnav يعلن منطقة التنقل فيستطيع مستخدم قارئ الشاشة القفز إليها مباشرة، وmain يحدد المحتوى الأساسي ولا يظهر منه إلا عنصر واحد في الصفحة، وh1 صار العنوان الرئيسي فعلاً. والعناوين من h1 إلى h6 تبني فهرس الصفحة: h2 للأقسام، وh3 لما تحتها، والأفضل ألا تقفز من h2 إلى h4 مباشرة. اختر المستوى حسب موقع العنوان في الفهرس، أما الحجم فمسؤولية CSS. ولاحظ أن عدد الأسطر لم يزد تقريباً؛ الكتابة الدلالية لا تكلفك وقتاً إضافياً، بل توفر عليك أصنافاً مثل big وtitle2 لا يفهمها أحد غيرك.
الإطار الخارجي للصفحة ثابت تقريباً في كل مشروع، ويستحق أن تحفظه:
• السطر الأول <!DOCTYPE html> يطلب الوضع القياسي؛ بدونه يدخل المتصفح «وضع التوافق» (Quirks Mode) المخصص للصفحات القديمة، فتتصرف بعض قواعد CSS بطريقة غير متوقعة.
• العنصر html يحمل lang="ar" dir="rtl" في الصفحات العربية: الأولى ليختار قارئ الشاشة النطق العربي، والثانية لتنقلب الصفحة كلها من اليمين إلى اليسار.
• head يضم ما لا يظهر داخل الصفحة: meta charset="UTF-8" لعرض العربية صحيحة، وmeta viewport للجوال، وtitle الذي يظهر في التبويب ونتائج البحث، وmeta name="description" لوصف قصير قد تعرضه محركات البحث.
• body يضم كل ما يراه الزائر.
عطل يتكرر مع الصفحات العربية: تظهر الحروف رموزاً غريبة مثل ال بدل الكلمات. السبب غالباً أحد أمرين: الملف محفوظ في المحرر بترميز غير UTF-8، أو سطر meta charset غائب أو متأخر داخل head. احفظ الملف بترميز UTF-8 من قائمة المحرر، واجعل سطر الترميز أول عنصر داخل head. ولاكتشاف أخطاء التداخل والسمات المفقودة الصق الكود في مدقق W3C على validator.w3.org، أو افتح تبويب Elements في أدوات المطوّر وقارن الشجرة التي بناها المتصفح بما كتبت أنت.
وملاحظة عن الكتابة نفسها: HTML لا يهتم بالمسافات الزائدة ولا بالأسطر الجديدة داخل النص، فكل مجموعة مسافات متتالية تُعرض مسافة واحدة. لذلك استخدم المسافة البادئة (Indentation) بحرية لتوضيح التداخل لنفسك، فهي لا تغيّر شيئاً في العرض. واكتب ملاحظاتك داخل تعليق <!-- --> الذي لا يظهر في الصفحة، لكنه يظهر لكل من يعرض مصدرها، فلا تضع فيه كلمات مرور أو معلومات خاصة.
للتثبيت اكتب الإطار كاملاً من الذاكرة دون نسخ: DOCTYPE، وhead فيه ترميز وviewport وعنوان ووصف، وbody فيه header وmain وfooter، وعنوان h1 وقسمان لكل منهما h2. مرّره على المدقق وأصلح كل ملاحظة حتى تحصل على نتيجة خالية من الأخطاء.
ابدأ كل صفحة بـ <!DOCTYPE html> ثم <html lang="ar" dir="rtl">.
head للترميز والعنوان والوصف، وbody لكل ما يراه الزائر.
الهدف: تنسّق الفقرات والقوائم، وتربط صفحاتك بمسارات صحيحة لا تنكسر بعد النشر.
افترض مخبزاً عائلياً في الإسكندرية يريد موقعاً صغيراً: صفحة رئيسية، وصفحة لقائمة المنتجات، ومدونة لوصفات الموسم. هذا المشروع المتواضع يكفي لتعلم كل ما يخص النصوص والروابط، لأنه يحتاج فقرات وقوائم، وروابط بين الصفحات، وروابط اتصال تعمل من الجوال.
نبدأ بالنص. الفقرة p هي الوحدة الأساسية، وللتأكيد عنصران مختلفان في المعنى: strong يعني «هذا مهم» وقد ينطقه قارئ الشاشة بنبرة مختلفة، وem يشدد على كلمة داخل الجملة فيغيّر معناها. أما b وi فيغيّران الشكل دون أن يحملا معنى خاصاً. وفي صفحة المخبز تحتاج نوعي القوائم: ul لأصناف الخبز التي لا يهم ترتيبها، وol لخطوات وصفة متسلسلة، وكل بند داخلهما li، ويمكن وضع قائمة كاملة داخل li لصنع قائمة فرعية.
الرابط هو العنصر a مع السمة href، وقيمة href تحدد نوعه:
• مطلق يبدأ بـ https:// ويشير إلى موقع آخر، مثل موقع المخبز على خرائط Google.
• نسبي مثل menu.html يُحسب من مكان الملف الحالي.
• مقطع مثل #hours يقفز إلى العنصر الذي يحمل id="hours" في الصفحة نفسها.
• mailto: يفتح برنامج البريد، وtel: يبدأ مكالمة عند النقر من الجوال، وهو أهم رابط في موقع مخبز يستقبل الطلبات بالهاتف.
لنفترض أن ملفات الموقع مرتبة هكذا:
bakery/
index.html
menu.html
blog/
recipe.html
من index.html إلى صفحة القائمة يكفي href="menu.html". ومن index.html إلى الوصفة تكتب href="blog/recipe.html"، أي ادخل مجلد blog ثم افتح الملف. ومن blog/recipe.html إلى الرئيسية تكتب href="../index.html"، لأن النقطتين تعنيان «اصعد مجلداً واحداً». وإذا بدأ المسار بشرطة مثل /menu.html فإنه يُحسب من جذر الموقع؛ هذا مريح بعد النشر، لكنه لا يعمل كما تتوقع عند فتح الملفات من قرصك بـ file:///، لأن الجذر حينها هو جذر القرص نفسه.
للروابط الخارجية قد تضيف target="_blank" لفتحها في تبويب جديد. كانت الصفحة المفتوحة بهذه الطريقة قادرة على التحكم في صفحتك عبر window.opener، ولذلك اعتاد المطورون إضافة rel="noopener". المتصفحات الحديثة تطبق هذا السلوك تلقائياً مع _blank، وكتابته صراحة لا تضر. ومع ذلك لا تفتح كل الروابط في تبويبات جديدة؛ اترك القرار للزائر إلا حين يكون خروجه من الصفحة مكلفاً، كأن يكون في منتصف تعبئة نموذج طلب.
نص الرابط يحتاج عناية خاصة، لأن مستخدمي قارئات الشاشة يتنقلون أحياناً بقائمة روابط الصفحة وحدها بعيداً عن السياق. قارن بين صيغتين في صفحة المخبز:
قبل: «لمعرفة أسعار الكعك اضغط هنا»، والرابط على كلمة «هنا».
بعد: «اطّلع على قائمة أسعار الكعك»، والرابط على العبارة كلها.
في قائمة الروابط تظهر الأولى كلمة «هنا» بلا معنى، وتصف الثانية الوجهة بدقة، وهذا جوهر معيار WCAG الخاص بوضوح غرض الرابط.
أكثر خطأ يكسر المواقع بعد رفعها نسخ مسار الملف من مستكشف الملفات، مثل href="C:\Users\...\menu.html". يعمل الرابط على جهازك فقط ويتعطل عند أول زائر. لاكتشافه مرّر المؤشر فوق الرابط واقرأ العنوان الذي يظهر أسفل نافذة المتصفح؛ إن رأيت اسم قرصك فحوّله إلى مسار نسبي. وخطأ آخر أقل وضوحاً: id مكرر في الصفحة نفسها، فيقفز الرابط إلى أول عنصر يحمله فقط، والمعرّف يجب أن يكون فريداً.
للتطبيق أنشئ الملفات الثلاثة بالترتيب السابق، وضع في كل صفحة عنصر nav يربط الصفحات كلها بمسارات نسبية، وأضف رابط tel: ورابط mailto: في التذييل. ثم انقر كل رابط من كل صفحة، وتأكد في تبويب Network أنه لا يوجد طلب عاد بالرمز 404.
strong وem يحملان معنى، وb وi يغيّران الشكل فقط.
المسار النسبي يُحسب من مكان الملف الحالي، و../ يصعد مجلداً واحداً.
target="_blank" للروابط الخارجية عند الحاجة فقط، مع rel="noopener".
نص الرابط يصف الوجهة ولا يكتفي بـ «اضغط هنا».
الهيكل
bakery/
├── index.html ──▶ menu.html
│ └──────▶ blog/recipe.html
└── blog/recipe.html ──▶ ../index.html
#hours ──▶ قسم في الصفحة نفسها
مختبر — قائمة تنقل
أضف id لكل section وجرّب النقر على الروابط، ولاحظ القفز داخل الصفحة. رقم الهاتف في المثال وهمي؛ ضع رقمك عند التجربة.
مهمة عملية
أنشئ nav بأربعة روابط داخلية، وأضف section رابعاً بعنوان «أسعار» بفقرة قصيرة، ثم تحقق أن كل رابط يقفز إلى القسم الصحيح وأن كل id فريد.
اختبر فهمك (1/3)
كيف تكتب رابطاً يقفز إلى قسم يحمل id="services" في الصفحة نفسها؟
اختبر فهمك (2/3)
من الملف blog/recipe.html تريد ربط index.html الموجود في المجلد الأعلى. أي href صحيح؟
اختبر فهمك (3/3)
أي صياغة رابط هي الأوضح لمستخدم يتنقل بقائمة الروابط وحدها؟
العنصر img فارغ لا يُغلق، لكنه من أكثر العناصر تأثيراً في جودة الصفحة: يحدد سرعة تحميلها، وثباتها أثناء التحميل، ومدى فهم قارئ الشاشة ومحرك البحث لمحتواها. وكل ذلك يتوقف على أربع سمات:
• src: مسار ملف الصورة، بالقواعد نفسها للمسارات النسبية في الدرس السابق.
• alt: نص بديل يقرؤه قارئ الشاشة، ويظهر مكان الصورة إن فشل تحميلها.
• width وheight: الأبعاد الأصلية بالبكسل. يحسب منها المتصفح نسبة العرض إلى الارتفاع ويحجز المكان قبل وصول الصورة، فلا يقفز النص تحتها. هذا القفز يقيسه مؤشر تغيّر التخطيط التراكمي (CLS) ضمن مؤشرات أداء الويب الأساسية.
• loading="lazy": يؤجل تحميل الصور البعيدة عن الشاشة حتى يقترب منها الزائر. لا تضعها على الصورة الكبيرة أعلى الصفحة، لأنها أول ما يجب أن يظهر.
كتابة alt مهارة تحريرية أكثر منها تقنية، وتساعدك فيها ثلاثة أسئلة مستوحاة من شجرة القرار التي ينشرها فريق الوصولية في W3C:
1) هل الصورة زخرفة لا تضيف معلومة، مثل خط فاصل مزخرف؟ اكتب alt="" فارغة فيتجاوزها قارئ الشاشة. أما حذف السمة كلياً فيجعل بعض القارئات تنطق اسم الملف.
2) هل الصورة وحدها داخل رابط أو زر؟ صف الوظيفة التي يؤديها النقر، فشعار يعود إلى الرئيسية يكون نصه البديل «الصفحة الرئيسية لمخبز النخيل».
3) هل تنقل الصورة معلومة؟ صفها في سياقها بجملة قصيرة: «لقطة من صفحة مقهى تعرض قائمة المشروبات والأسعار» أنفع بكثير من «صورة1».
ولا تبدأ النص بعبارة «صورة لـ»، فقارئ الشاشة يعلن أنها صورة من تلقاء نفسه.
اختيار الصيغة قرار مقارنة بسيط. JPEG للصور الفوتوغرافية، وPNG لما يحتاج شفافية أو حوافاً حادة كلقطات الشاشة، وSVG للشعارات والأيقونات لأنها رسوم متجهية تبقى حادة بأي حجم وتُكتب نصاً يمكن تعديله. أما WebP وAVIF فصيغتان حديثتان تعطيان غالباً حجماً أصغر بالجودة نفسها، وتدعمهما المتصفحات الحديثة الرئيسية؛ وإن احتجت بديلاً لمتصفح قديم فالعنصر picture يتيح عرض صيغة احتياطية.
هكذا يبدو قسم أعمال في صفحة شخصية بعد تطبيق ما سبق:
<section id="work">
<h2>أعمالي</h2>
<figure>
<img src="images/cafe.webp" alt="صفحة مقهى تعرض قائمة المشروبات والأسعار" width="800" height="500" loading="lazy">
<figcaption>مشروع تدريبي: صفحة مقهى متجاوبة</figcaption>
</figure>
</section>
figure يجمع الصورة وتعليقها figcaption في وحدة واحدة، والتعليق يظهر للجميع بينما alt يحل محل الصورة لمن لا يراها، فلا تكرر النص نفسه في الاثنين. وsection قسم موضوعي يحمل عنواناً، بينما article محتوى مستقل يُفهم وحده كمقال أو بطاقة مشروع، وaside محتوى جانبي مرتبط بالصفحة. أما div فغلاف للتنسيق بلا معنى، تستخدمه حين لا يناسب أي عنصر آخر.
حالة عملية: صفحة معرض لمصوّر أفراح في طنطا تبدو ممتازة على شبكة البيت، وبطيئة جداً على باقة الجوال. في تبويب Network، عمود Size، تبيّن أن كل صورة رُفعت كما خرجت من الكاميرا بعرض 4000 بكسل وحجم عدة ميغابايت، بينما تُعرض في مربع عرضه 300 بكسل. الإصلاح من ثلاث خطوات: صغّر الأبعاد إلى ضعف عرض العرض تقريباً، أي 600 بكسل، لتبقى حادة على الشاشات عالية الكثافة؛ ثم اضغطها بأداة مثل Squoosh؛ ثم حوّلها إلى WebP. في مثل هذه الحالة ينخفض حجم الصورة عادة من ميغابايتات إلى عشرات الكيلوبايت دون فرق تلاحظه العين في هذا المقاس.
للتطبيق أضف معرضاً من ثلاثة عناصر figure، لكل منها alt وصفي وwidth وheight. سجّل حجم كل صورة قبل الضغط وبعده، واهدف إلى أقل من 200 كيلوبايت للصورة. ثم أضف صورة زخرفية بـ alt فارغ، واكتب جملة تبرر الفرق بينها وبين صور المعرض.
alt يصف وظيفة الصورة أو معلومتها في سياقها، وalt="" للزخرفة.
width وheight على img يحجزان المكان ويمنعان قفز التخطيط.
loading="lazy" للصور البعيدة فقط، وليس للصورة الرئيسية أعلى الصفحة.
صغّر أبعاد الصورة واضغطها قبل الرفع، وSVG للشعارات.
مخطط
<header> شعار + قائمة
<main>
<section> عني + صورة
<section> معرض
<figure> img + figcaption
<section> تواصل
<footer> حقوق
مختبر — معرض صور
استبدل project1.webp بصورة محلية حقيقية، واكتب في width وheight أبعادها الأصلية.
مهمة عملية
أضف section «آراء العملاء» فيه ul بثلاثة عناصر، واكتب في كل عنصر نصاً مؤقتاً واضحاً مثل «(رأي عميل حقيقي بعد أول مشروع)». لا تنشر شهادات مختلقة أبداً.
اختبر فهمك (1/3)
لماذا تُكتب سمة alt على عنصر img؟
اختبر فهمك (2/3)
صورة زخرفية لا تضيف أي معلومة. ما الأصح؟
اختبر فهمك (3/3)
لماذا تكتب width وheight على img حتى لو حددت حجمها في CSS؟
الهدف: تنسّق مظهر الصفحة بألوان وخطوط متناسقة ومقروءة، وتعرف لماذا لا تُطبَّق قاعدة كتبتها.
يُكتب CSS في أحد ثلاثة أماكن: سمة style على العنصر نفسه، أو عنصر style داخل head، أو ملف مستقل تربطه بالسطر <link rel="stylesheet" href="styles.css">. الملف المستقل هو الخيار العملي لأي موقع من أكثر من صفحة، لأن الصفحات كلها تشاركه، ويحفظه المتصفح في ذاكرته المؤقتة بعد أول زيارة فلا يُحمَّل مع كل صفحة من جديد.
القاعدة (Rule) تبدأ بمحدِّد (Selector) يختار العناصر، ثم بين قوسين معقوفين أزواج من خاصية وقيمة تنتهي كل منها بفاصلة منقوطة. أشهر المحددات أربعة: اسم العنصر مثل p، والصنف مثل .card، والمعرّف مثل #hero، والمحدد المركب مثل nav a الذي يختار الروابط الموجودة داخل nav فقط.
لنبنِ هوية بصرية لصفحة صيدلية حي في الجيزة خطوة بخطوة. الخطوة الأولى: نحدد لوناً أساسياً ولون نص ولون خلفية، ونحفظها متغيرات (Custom Properties) في :root حتى نغيّرها من مكان واحد:
الخطوة الثانية: نفهم ما كتبناه. الصيغة hsl تصف اللون بثلاثة أرقام: درجة اللون على دائرة من 0 إلى 360، ثم التشبع، ثم الإضاءة؛ فإن أردت نسخة أفتح من اللون الأساسي للخلفيات رفعت الإضاءة وحدها. ووحدة rem تُحسب من حجم خط العنصر الجذر، وهو 16 بكسل افتراضياً في المتصفحات الشائعة، فيكبر النص كله مع من يكبّر الخط في إعدادات متصفحه. وline-height بلا وحدة بين 1.6 و1.9 يريح قراءة العربية، لأن حروفها بنقاطها وحركاتها تحتاج مساحة رأسية أكبر. أما قائمة font-family فيمر عليها المتصفح بالترتيب ويستخدم أول خط متوفر في الجهاز، ولذلك تنتهي دائماً بعائلة عامة مثل sans-serif. وborder-inline-start يضع الحد في بداية السطر: يميناً في الصفحات العربية ويساراً في الإنجليزية.
الخطوة الثالثة: التباين. يشترط معيار الوصولية WCAG في مستواه AA نسبة تباين لا تقل عن 4.5:1 بين النص العادي وخلفيته، و3:1 للنص الكبير. النص الرمادي الفاتح على الأبيض يبدو أنيقاً في ملف التصميم، لكنه يتعب كبار السن ومن يقرأ تحت الشمس، وزبائن الصيدلية فيهم الاثنان. في Chrome افحص العنصر، وانقر مربع اللون الصغير في لوحة Styles، فيعرض منتقي الألوان نسبة التباين مباشرة ويرسم خطاً يفصل الألوان المقبولة عن غيرها.
وإن أردت خطاً عربياً غير مثبت في أجهزة الزوار، من مكتبة مثل Google Fonts، فتذكّر أن كل وزن تضيفه ملف إضافي يُحمَّل قبل أن يظهر النص بشكله النهائي. اكتفِ بوزنين، عادي وعريض، واذكر بعد اسم الخط خطوطاً احتياطية في font-family. وتأكد أن رابط الخط يحتوي المعامل display=swap، فيظهر النص فوراً بخط النظام إلى أن يصل الخط المخصص، بدل أن يبقى الزائر أمام مساحة فارغة.
سجل عطل نموذجي: كتبت قاعدة لتلوين فقرة المقدمة بالأحمر ولم يتغير شيء. هذه خطوات التشخيص بالترتيب:
1) اختر الفقرة في أدوات المطوّر وابحث عن قاعدتك في لوحة Styles. إن لم تظهر إطلاقاً فالمحدد لا يطابق العنصر: راجع اسم الصنف وحالة أحرفه، أو تأكد في تبويب Network أن ملف CSS نفسه وصل.
2) إن ظهرت القاعدة مشطوبة فهناك قاعدة أقوى تتغلب عليها. قوة المحدد (Specificity) تُرتَّب هكذا: المعرّف أقوى من الصنف، والصنف أقوى من اسم العنصر، والسمة style المكتوبة على العنصر أقوى منها جميعاً.
3) عند تساوي القوة تفوز القاعدة المكتوبة أخيراً.
4) الحل الصحيح محدد بالقوة المناسبة، مثل صنف على الفقرة. تجنب !important كحل سريع، لأنها تجرّك إلى !important أخرى في كل تعديل لاحق.
للتطبيق عرّف ثلاثة متغيرات ألوان وطبّقها على العناوين والروابط وزر .btn، ثم افحص تباين كل لون نص مع خلفيته، وعدّل قيمة الإضاءة في hsl حتى تتجاوز النسبة 4.5.
ملف CSS مستقل تشاركه كل الصفحات ويحفظه المتصفح مؤقتاً.
متغيرات :root تحفظ لوحة الألوان في مكان واحد.
rem للخطوط وline-height بين 1.6 و1.9 لراحة قراءة العربية.
تباين 4.5:1 على الأقل للنص العادي وفق WCAG.
القاعدة المشطوبة في Styles تعني محدداً أقوى يتغلب عليها.
مخطط
HTML←CSS
:root←--primary, --text, --bg
body←font-family, line-height, color
h1←color: var(--primary)
تعارض؟←#id > .class > element
مختبر — لوحة ألوان
جرّب تغيير --primary ولاحظ تأثيره على h1 والروابط معاً، ثم افحص التباين من منتقي الألوان.
معاينة مباشرة
مهمة عملية
عرّف متغيرين في :root باسمي primary وaccent وطبّقهما على h1 وزر .btn، ثم سجّل نسبة تباين نص الزر مع خلفيته وتأكد أنها 4.5:1 أو أكثر.
اختبر فهمك (1/3)
أين تُكتب قواعد CSS إذا أردتها داخل ملف HTML نفسه؟
اختبر فهمك (2/3)
كتبت p { color: red; } فلم يتغير لون فقرة لها id="intro"، والقاعدة مشطوبة في Styles. لماذا؟
اختبر فهمك (3/3)
نص رمادي فاتح على خلفية بيضاء. ما المشكلة وفق WCAG؟
الهدف: تتحكم في المسافات حول العناصر، وتحسب العرض الفعلي لأي صندوق قبل أن تراه.
يعامل المتصفح كل عنصر كصندوق من أربع طبقات، من الداخل إلى الخارج: المحتوى، ثم الحشوة (padding) بين المحتوى والحد، ثم الحد (border) المرئي، ثم الهامش (margin) الذي يفصل الصندوق عن جيرانه. لون الخلفية يمتد تحت الحشوة ويتوقف عند الحد، فلا يظهر في منطقة الهامش أبداً. هذا الفرق وحده يحسم أكثر سؤال يتكرر عند المبتدئين: إن أردت مساحة ملونة حول النص داخل البطاقة فهي padding، وإن أردت إبعاد البطاقة عن جارتها فهي margin.
هنا يظهر الفرق بين نموذجين لحساب العرض. في الوضع الافتراضي content-box تنطبق width على المحتوى وحده، ثم تُضاف الحشوة والحد من الجانبين، فيكون العرض الظاهر 300 + 20×2 + 1×2 = 342 بكسل، ويُضاف الهامش خارج ذلك فتشغل البطاقة 374 بكسل من عرض السطر. أما في النموذج border-box فتشمل width الحشوة والحد، فيبقى العرض الظاهر 300 بكسل بالضبط ويتقلص المحتوى إلى 258. النموذج الثاني أسهل في التخطيط لأن الرقم الذي تكتبه هو الرقم الذي تراه، ولذلك يبدأ أغلب المطورين ملفاتهم بهذه القاعدة:
الاختصارات توفر سطوراً كثيرة: padding: 10px 20px تعني 10 أعلى وأسفل و20 على الجانبين، والقيم الأربع تُقرأ باتجاه عقارب الساعة: أعلى، يمين، أسفل، يسار، ولا يتغير هذا الترتيب في الصفحات العربية. لذلك توفر CSS خصائص منطقية (Logical Properties) تتبع اتجاه الكتابة، مثل padding-inline-start التي تعني بداية السطر، أي اليمين في العربية واليسار في الإنجليزية، وmargin-block-end التي تعني الأسفل في الكتابة الأفقية. إن كان موقعك ثنائي اللغة فهذه الخصائص توفر عليك ملف تنسيق ثانياً للاتجاه المعاكس.
ثلاثة سلوكيات تفاجئ من يبدأ:
• العناصر السطرية مثل span وa تتجاهل width وheight، وهوامشها العلوية والسفلية لا تدفع الأسطر المجاورة. إن احتجت أبعاداً لرابط يبدو كزر فغيّر display إلى inline-block أو block.
• الهامشان الرأسيان المتلاصقان لعنصرين متتاليين يندمجان (Margin Collapsing) ويبقى الأكبر فقط: هامش سفلي 24 بكسل فوق هامش علوي 16 ينتج فراغاً قدره 24. هذا الاندماج لا يحدث بين العناصر داخل حاوية flex أو grid، ولا يحدث أفقياً.
• النسبة المئوية في padding تُحسب من عرض الحاوية، حتى للحشوة العلوية والسفلية.
من أشهر الأعطال على الجوال شريط تمرير أفقي لا تعرف مصدره. السبب المتكرر عنصر أُعطي width: 100% ثم padding في نموذج content-box، فصار أعرض من الشاشة بمقدار الحشوة. لاكتشافه افتح تبويب Elements ومرّر المؤشر فوق العناصر واحداً تلو الآخر، فيلوّن المتصفح طبقات الصندوق بألوان مختلفة ويظهر العنصر الذي يتجاوز حافة الشاشة. وفي لوحة Computed يظهر مخطط الصندوق بالأرقام الفعلية لكل طبقة، وهو أسرع من أي حساب ذهني. الإصلاح قاعدة border-box السابقة، أو حذف width: 100% من عنصر كتلي يملأ العرض تلقائياً أصلاً.
سؤال أخير يتكرر: متى تستخدم gap بدل margin؟ حين تكون العناصر أبناء حاوية flex أو grid، فالخاصية gap تضع مسافة متساوية بينها فقط دون فراغ زائد عند الأطراف، وهذا أنظف من إعطاء كل بطاقة هامشاً ثم محاولة إلغائه عن الأخيرة.
للتطبيق ابنِ البطاقة بالقيم السابقة، وسجّل أرقام مخطط الصندوق من لوحة Computed، ثم بدّل box-sizing بين القيمتين وقارن العرض بحسابك اليدوي. أخيراً ضع بطاقتين إحداهما فوق الأخرى بهامشين مختلفين، وقس المسافة بينهما لتتأكد من الاندماج.
padding مسافة داخل الحد تظهر فيها الخلفية، وmargin فراغ خارجه.
box-sizing: border-box يجعل width تشمل الحشوة والحد.
الهوامش الرأسية المتلاصقة تندمج ويبقى الأكبر، إلا داخل flex وgrid.
الخصائص المنطقية مثل padding-inline-start تتبع اتجاه الكتابة.
الهدف: تجعل الصفحة مقروءة وسهلة اللمس على الشاشات الصغيرة، ثم توسّع تخطيطها للشاشات الأعرض.
يتصفح كثير من الزوار المواقع من هواتفهم، وبعضهم لا يستخدم حاسوباً أصلاً، لذلك يبدأ التصميم الحديث من الشاشة الضيقة ثم يتوسع. التصميم المتجاوب (Responsive Design) يعني صفحة واحدة بملف HTML واحد يتكيف تخطيطها مع عرض الشاشة، دون نسخة منفصلة للجوال تحتاج صيانة مستقلة.
الخطوة التي لا يعمل شيء بدونها هي سطر viewport في head. بدونه يفترض متصفح الجوال أن الصفحة صُممت لشاشة عريضة، فيرسمها بعرض افتراضي يقارب 980 بكسل في كثير من المتصفحات ثم يصغّرها كلها لتتسع، فيظهر النص ضئيلاً ولا تعمل استعلامات الوسائط كما تتوقع:
بعده تأتي الوحدات المرنة: نسب مئوية وmax-width بدل العروض الثابتة، وrem للخطوط والمسافات. وهذه القاعدة وحدها تمنع الصور من تجاوز حاويتها مع الحفاظ على نسبتها:
img { max-width: 100%; height: auto; }
مقارنة بين أسلوبين لكتابة استعلامات الوسائط (Media Queries). في أسلوب «الجوال أولاً» تكتب التنسيق الأساسي للشاشة الضيقة بلا أي استعلام، ثم تضيف استعلامات min-width تفتح أعمدة أكثر كلما اتسعت الشاشة:
النتيجة عمود واحد على الهاتف، وعمودان على الجهاز اللوحي، وثلاثة على الحاسوب. أما أسلوب «الحاسوب أولاً» فيبدأ بثلاثة أعمدة ثم يكتب استعلامات max-width تلغيها للشاشات الأصغر. الأسلوبان صحيحان تقنياً، لكن الثاني يراكم قواعد مكتوبة فقط للتراجع عن قواعد سابقة، ويصعب تتبعه حين يكبر الملف، لذلك يُفضَّل الأول في المشاريع الجديدة. وللحالات البسيطة يكفي سطر واحد بلا استعلامات: grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)) يضع أكبر عدد من الأعمدة يتسع له المكان بشرط ألا يقل عرض العمود عن 220 بكسل. وقيم نقاط التوقف مثل 640 و1024 ليست أرقاماً مقدسة؛ ضع نقطة التوقف حيث يبدأ تصميمك نفسه بالانكسار.
قائمة اختبار التجاوب: افتح أدوات المطوّر واضغط Ctrl+Shift+M لتفعيل وضع الأجهزة في Chrome أو Firefox، ثم مرّ على ثلاثة عروض هي 360 و768 و1280 بكسل، وأجب عند كل عرض عن أربعة أسئلة:
• هل النص مقروء دون تكبير بالأصابع؟
• هل يظهر شريط تمرير أفقي عند سحب الصفحة جانباً؟
• هل الأزرار والروابط سهلة اللمس؟ يشترط معيار WCAG 2.2 في مستواه AA ألا يقل الهدف عن 24×24 بكسل أو أن تحيط به مسافة كافية، ويوصي مستواه الأعلى AAA بـ 44×44.
• هل الصور حادة وغير مشوهة النسب؟
أشهر أسباب التمرير الأفقي ثلاثة: عنصر بعرض ثابت مثل width: 900px، أو جدول واسع، أو رابط طويل جداً بلا مسافات. الإصلاح على الترتيب: استبدل العرض الثابت بـ width: 100% مع max-width: 900px؛ وضع الجدول داخل غلاف فيه overflow-x: auto ليمرر الجدول وحده دون الصفحة؛ وأضف overflow-wrap: anywhere للنصوص الطويلة. وتجنب overflow: hidden على body كحل سريع، لأنه يخفي المحتوى الزائد بدل إصلاحه، وقد يقطع زراً أو حقلاً مهماً.
وتذكّر حدود المحاكاة: وضع الأجهزة يغيّر عرض الشاشة فقط، ولا يحاكي ضعف معالج الهاتف ولا دقة لمس الإصبع. لذلك افتح الصفحة على هاتف حقيقي قبل التسليم، وجرّب الضغط على كل زر بإبهامك. ويمكنك في تبويب Network اختيار سرعة شبكة أبطأ من قائمة التقييد (Throttling) لترى ما يراه زائر على باقة ضعيفة، وهو اختبار يكشف غالباً صوراً ثقيلة لم تنتبه لها.
للتطبيق اختبر صفحتك على العروض الثلاثة، واكتب عند كل عرض ملاحظة لكل سؤال من القائمة، ثم أصلح كل مشكلة بقاعدة min-width واحدة على الأكثر.
سطر meta viewport شرط أساسي لأي تصميم متجاوب.
img { max-width: 100%; height: auto; } يمنع الصور من تجاوز حاويتها.
الجوال أولاً: تنسيق أساسي للشاشة الضيقة ثم @media (min-width) للأعرض.
ضع نقطة التوقف حيث ينكسر تصميمك، واختبر على 360 و768 و1280 بكسل.
الهدف: تجمع HTML و CSS في صفحة تعريف واحدة كاملة، واضحة الرسالة وقابلة للتنقل بلوحة المفاتيح.
هذا الدرس مشروع يجمع ما سبق في صفحة تعريف شخصية واحدة. سنتابعه من خلال حالة: خريجة تصميم جرافيك في الزقازيق تريد صفحة ترسل رابطها لأصحاب المحلات والمطاعم الذين تعرض عليهم تصميم القوائم والشعارات. قبل أي كود أجابت كتابةً عن أربعة أسئلة، لأن الصفحة الجميلة بلا رسالة واضحة لا تحقق غرضها:
• من أنا في جملة؟ «مصممة هويات بصرية للمطاعم والمحلات الصغيرة».
• ماذا أقدّم؟ ثلاث خدمات محددة: شعار، وقائمة طعام، ومنشورات افتتاح.
• ما الدليل؟ ثلاثة مشاريع، منها مشروعان تدريبيان مكتوب عليهما ذلك بوضوح.
• كيف يتواصل الزائر؟ رابط واتساب ورابط بريد.
ترتيب البناء هو ما يميز المشروع المنظم: HTML بالمحتوى الحقيقي أولاً دون أي تنسيق، ثم التخطيط من حاوية وشبكة ومسافات، ثم الألوان والتفاصيل في النهاية. حين كتبت المصممة نصوصها الحقيقية مبكراً اكتشفت أن فقرة «عني» طويلة أكثر من اللازم، فاختصرتها إلى ثلاث جمل قبل أن تصمم لها مربعاً. لو بدأت بالألوان ونصوص وهمية لاكتشفت ذلك بعد أن ينكسر التصميم ويضيع وقت التنسيق.
في الهيكل عنوان h1 واحد يحمل الرسالة، وزر دعوة واحد بارز (Call to Action)، لأن خمسة أزرار متنافسة تشتت الزائر فلا يضغط أياً منها. وأقسام الصفحة كلها داخل main، ولكل قسم معرّف تشير إليه روابط nav، فيعمل التنقل حتى قبل كتابة سطر CSS واحد.
بعد التخطيط والألوان أضافت قاعدتين صغيرتين لهما أثر كبير:
القاعدة الأولى تجعل القفز إلى الأقسام ناعماً، لكنها تحترم من فعّل خيار تقليل الحركة في نظام تشغيله، لأن الحركة قد تسبب لبعض الناس دواراً. والثانية تُظهر إطاراً واضحاً حول العنصر الذي عليه التركيز عند التنقل بلوحة المفاتيح. المحدد :focus-visible يترك للمتصفح أن يقرر متى يظهر الإطار: يظهر عادة عند التنقل بمفتاح Tab، ولا يظهر عند النقر بالفأرة على رابط.
كثير من القوالب الجاهزة تحوي outline: none لإخفاء إطار التركيز لأنه «غير جميل»، والنتيجة أن من يتنقل بلوحة المفاتيح يفقد موضعه في الصفحة، وهذا يخالف معيار WCAG الخاص بوضوح التركيز. اختبر صفحتك بنفسك: ضع الفأرة جانباً واضغط Tab مراراً، وإن اختفى موضعك في أي لحظة فابحث عن outline: none في ملفات CSS واستبدلها بقاعدة focus-visible.
ولزر واتساب صيغة رسمية بسيطة: https://wa.me/201xxxxxxxxx، حيث يُكتب الرقم بالصيغة الدولية بلا علامة + ولا أصفار بادئة ولا شرطات، فيفتح النقر محادثة مباشرة في التطبيق على الهاتف أو في واتساب ويب على الحاسوب. ضعه بجانب رابط mailto:، فبعض أصحاب الأعمال يفضلون البريد لإرسال الملفات والصور بجودتها الكاملة.
وأخيراً المحتوى صادق دائماً: لا أعداد عملاء ولا آراء لم تحدث. قسم بعنوان صريح مثل «مشاريع تدريبية» يبني ثقة أكثر من ادعاء خبرة غير موجودة، لأن صاحب المطعم سيسأل عنها في أول مكالمة، وسيطلب رؤية عمل سابق.
للتطبيق ارسم صفحتك على ورقة بمربعات للأقسام، واكتب نصوصها في ملف منفصل، ثم ابنها بالترتيب السابق. اختبرها بلوحة المفاتيح وحدها، ثم على عرض 360 بكسل، ثم اطلب من شخص لا يعرف عملك أن ينظر إليها خمس ثوانٍ ويخبرك ماذا فهم. إن لم يذكر ما تقدّمه فأعد كتابة العنوان h1.
حدّد الرسالة والخدمات والدليل وطريقة التواصل قبل كتابة الكود.
ابنِ بالترتيب: محتوى HTML حقيقي، ثم التخطيط، ثم الألوان والتفاصيل.
عنوان h1 واحد وزر دعوة واحد بارز أوضح من أزرار متنافسة.
لا تحذف إطار التركيز؛ نسّقه بـ :focus-visible واختبر بمفتاح Tab.
خصّص كل section بمحتوى حقيقي — حتى لو مشروعاً تعليمياً، اكتبه كأنك تقدّمه لعميل، ثم اختبر التنقل بمفتاح Tab.
معاينة مباشرة
مهمة عملية
أكمل الصفحة: أضف section «خدمات» بثلاث بطاقات، وزر تواصل يفتح mailto: أو رابط واتساب، ثم تنقّل في الصفحة كلها بمفتاح Tab وتأكد أن إطار التركيز ظاهر على كل رابط.
اختبر فهمك (1/3)
ما أهم ما يجب أن تحمله صفحة شخصية للعمل الحر؟
اختبر فهمك (2/3)
أخفيت إطار التركيز بـ outline: none لأنه غير جميل. من يتضرر أكثر؟
اختبر فهمك (3/3)
لماذا وُضعت scroll-behavior: smooth داخل استعلام prefers-reduced-motion: no-preference؟
الهدف: تنشر صفحتك على استضافة ثابتة، وتفهم كيف يُربط النطاق بها، وتصلح أعطال ما بعد الرفع.
الملف على جهازك لا يصل إليه أحد غيرك. لنشره تحتاج شيئين منفصلين يخلط بينهما كثيرون: استضافة (Hosting)، وهي خادم متصل بالإنترنت دائماً يحفظ ملفاتك ويرسلها لمن يطلبها، ونطاق (Domain)، وهو الاسم الذي يكتبه الزائر مثل yourname.com. يُحجز النطاق من مسجّل نطاقات ويُجدَّد دورياً، ويمكن أن يكون عند جهة والاستضافة عند جهة أخرى، ويربط بينهما DNS.
الموقع المكوّن من HTML وCSS وصور فقط يسمى موقعاً ثابتاً (Static Site)، لأن الخادم يرسل الملفات كما هي دون برنامج يولّدها. هذا النوع تستضيفه خدمات مثل GitHub Pages وNetlify وCloudflare Pages بخطط مجانية مع شهادة HTTPS جاهزة وعنوان فرعي تبدأ به قبل شراء نطاق. والخيار الآخر استضافة مشتركة بلوحة تحكم مثل cPanel، ترفع إليها الملفات عبر مدير الملفات أو FTP إلى مجلد الجذر، واسمه غالباً public_html. في الحالتين، حين يطلب الزائر عنوان مجلد يعرض الخادم ملف index.html تلقائياً، ولذلك يجب أن تحمل صفحتك الرئيسية هذا الاسم بالضبط وبأحرف صغيرة.
النشر على GitHub Pages خطوة بخطوة:
1) أنشئ حساباً على GitHub ثم مستودعاً عاماً جديداً.
2) ارفع index.html وملف CSS ومجلد الصور من زر رفع الملفات في صفحة المستودع، مع الحفاظ على بنية المجلدات نفسها التي اختبرتها على جهازك.
3) من إعدادات المستودع افتح قسم Pages، واختر النشر من فرع main ومن الجذر.
4) بعد دقائق يظهر رابط بصيغة username.github.io/اسم-المستودع، وإذا سمّيت المستودع username.github.io صار الموقع على هذا العنوان مباشرة.
5) افتح الرابط وتأكد من ظهور القفل في شريط العنوان.
حين تشتري نطاقاً تربطه بالاستضافة من لوحة DNS عند المسجّل بسجلات مثل هذه. العنوان الرقمي هنا من نطاق مخصص لأمثلة التوثيق، والقيم الحقيقية تأخذها من وثائق الاستضافة:
النوع الاسم القيمة
A @ 203.0.113.10
CNAME www yourname.github.io
السجل A يربط النطاق الأساسي، ويرمز له بـ @، بعنوان IP للخادم. والسجل CNAME يجعل www اسماً مستعاراً يشير إلى اسم آخر يتولى الرد عنه. ينتشر التغيير عادة خلال دقائق أو ساعات، وقد يستغرق في بعض الحالات يوماً كاملاً، فلا تغيّر السجلات مراراً وأنت تنتظر. بعد اكتمال الانتشار فعّل HTTPS؛ أغلب الاستضافات الحديثة تصدر شهادة مجانية تلقائياً، وكثير منها عبر هيئة Let's Encrypt غير الربحية.
سجل أعطال ما بعد الرفع، مرتباً من الأكثر تكراراً:
• صور مكسورة مع أن كل شيء سليم على جهازك: الرابط images/Photo.JPG والملف photo.jpg. نظام Windows لا يميز حالة الأحرف في أسماء الملفات، أما خوادم Linux التي تشغّل معظم الاستضافات فتعدّهما ملفين مختلفين. الوقاية: أسماء بأحرف إنجليزية صغيرة، بلا مسافات، بشرطة بين الكلمات مثل team-photo.webp.
• الصفحة الرئيسية تعطي 404: الملف اسمه Index.html أو home.html، أو رُفع داخل مجلد فرعي بدل الجذر.
• الصفحة بلا تنسيق: مسار ملف CSS مطلق يشير إلى قرصك، أو يبدأ بشرطة مائلة والموقع منشور في مجلد فرعي مثل username.github.io/اسم-المستودع، فيبحث المتصفح عن الملف في جذر النطاق.
• تحذير «غير آمن»: الشهادة لم تصدر بعد، أو الصفحة تطلب صورة أو خطاً عبر http بدل https.
للتطبيق انشر صفحتك الشخصية على خدمة استضافة ثابتة مجانية. افتح الرابط من هاتفك عبر بيانات الجوال لا شبكة البيت، وتأكد من ظهور القفل، ومن تحميل كل الصور، ومن خلو تبويب Network من أي طلب باللون الأحمر.
الاستضافة تحفظ الملفات، والنطاق هو الاسم، وDNS يربط بينهما.
index.html بأحرف صغيرة في الجذر هو نقطة الدخول الافتراضية.
السجل A للنطاق الأساسي، وCNAME لاسم مستعار مثل www.
خوادم Linux تميز حالة الأحرف؛ استخدم أسماء ملفات صغيرة بلا مسافات.
الهيكل
[ ملفاتك ]
│ رفع (GitHub / cPanel)
▼
[ الاستضافة ]
│ سجلات DNS: A / CNAME
▼
[ yourname.com ] → HTTPS → الزائر يرى صفحتك
قائمة تحقق — قبل النشر
مرّ على كل بند قبل رفع أي مشروع لعميل؛ أغلب أعطال ما بعد الرفع يكشفها هذا الفحص.
مهمة عملية
انشر صفحتك على GitHub Pages أو خدمة ثابتة مشابهة، ثم أرسل الرابط لنفسك وافتحه من الهاتف، وسجّل رمز حالة كل طلب فشل في تبويب Network وسبب فشله.
اختبر فهمك (1/3)
ما الملف الذي يعرضه الخادم تلقائياً عند زيارة عنوان مجلد؟
اختبر فهمك (2/3)
الصور سليمة على Windows ومكسورة بعد الرفع؛ الرابط images/Photo.JPG والملف photo.jpg. ما السبب؟
اختبر فهمك (3/3)
في لوحة DNS، أي سجل يربط النطاق الأساسي @ بعنوان IP للخادم؟
الهدف: تراجع صفحتك كمحترف قبل التسليم، وتصلح نموذج التواصل، وتقيس النتيجة بأدوات موضوعية.
المراجعة الأخيرة تفصل بين صفحة «تعمل» وصفحة جاهزة للتسليم. اعتمد قائمة ثابتة من أربعة محاور وطبّقها على كل مشروع بالترتيب نفسه، فالقائمة الثابتة تكشف ما تنساه الذاكرة عند الاستعجال:
• المحتوى: لا أخطاء إملائية، وكل رابط يعمل، ورسالة الصفحة مفهومة خلال خمس ثوانٍ، ولا نصوص وهمية منسية مثل Lorem ipsum.
• البنية والوصولية: عنوان h1 واحد وعناوين متدرجة، وalt لكل صورة، وتباين لا يقل عن 4.5:1، وكل عنصر تفاعلي يصل إليه مفتاح Tab بإطار تركيز ظاهر.
• الأداء: صور مضغوطة بأبعاد مناسبة، وwidth وheight على كل img، ولا ملفات CSS أو صور غير مستخدمة.
• محركات البحث: title فريد لكل صفحة، ووصف meta name="description" من جملة أو جملتين يلخص الصفحة بصدق.
أكثر جزء يحتاج مراجعة دقيقة هو نموذج التواصل، لأن أخطاءه لا تظهر للعين. هذه نسخة شائعة في القوالب الجاهزة:
مشكلاتها أربع. لا يوجد label، فقد لا يعلن قارئ الشاشة اسم الحقل، والنص الرمادي داخله يختفي بمجرد الكتابة فينسى المستخدم المطلوب. ونوع الحقل text، فلا تظهر على الجوال لوحة مفاتيح فيها @ ولا يُفحص شكل البريد. ولا توجد سمة name، فلن يصل الخادم أي قيمة، لأن المتصفح لا يرسل إلا الحقول التي تحمل اسماً. ولا يوجد action ولا method، فيُرسل النموذج إلى الصفحة نفسها بطريقة GET وتظهر الرسالة كاملة في شريط العنوان. وهذه النسخة بعد الإصلاح:
تطابق for مع id يربط النص بالحقل، فالنقر على «البريد الإلكتروني» ينقل المؤشر إلى الحقل، ويقرأ قارئ الشاشة الاسم معه. وautocomplete يسمح للمتصفح بالملء التلقائي، وrequired وminlength يمنعان الإرسال الناقص قبل أن يصل الخادم. لكن هذا الفحص في المتصفح للراحة فقط، ويجب أن يتحقق الخادم من البيانات مرة أخرى، لأن أي شخص يستطيع تجاوز فحص المتصفح. والإرسال الفعلي يحتاج برنامجاً على الخادم عند العنوان المحدد في action، أو خدمة نماذج خارجية، وهذا خارج نطاق HTML وحده.
قبل الانتقال إلى الأدوات جرّب النموذج كما سيجربه زائر متعجل: اتركه فارغاً واضغط إرسال، ثم اكتب بريداً ناقصاً مثل name@، ثم رسالة من كلمتين. في كل حالة يجب أن يمنع المتصفح الإرسال ويعرض رسالة بجانب الحقل المعني، وأن يبقى ما كتبته في الحقول الأخرى كما هو. إن ضاعت البيانات أو لم يفهم الزائر سبب الرفض فالأرجح أنه سيغلق الصفحة ولن يعود.
أداتان للفحص الآلي: مدقق W3C يكشف أخطاء HTML كالتداخل الخاطئ والمعرّفات المكررة، وتقرير Lighthouse المدمج في أدوات المطوّر في Chrome يقيس أربعة محاور: الأداء، والوصولية، وأفضل الممارسات، وأساسيات محركات البحث، ويشرح كل ملاحظة مع رابط لطريقة إصلاحها. تذكّر أن الأدوات الآلية تكشف جزءاً من مشكلات الوصولية فقط؛ فهي لا تستطيع مثلاً أن تحكم هل نص alt يصف الصورة فعلاً، ولذلك يبقى اختبار لوحة المفاتيح والقراءة البشرية ضروريين حتى لو حصلت على درجة كاملة.
للتطبيق شغّل Lighthouse على صفحتك بوضع Mobile وسجّل الدرجات الأربع، ثم أصلح ثلاث ملاحظات على الأقل وأعد القياس. اكتب في ملف ملاحظات كل تغيير وسببه والدرجة قبله وبعده، واحتفظ بالملف مع المشروع، فهو دليل عملي على طريقة عملك يمكن عرضه على أول عميل.
راجع كل مشروع بأربعة محاور: المحتوى، والوصولية، والأداء، ومحركات البحث.
كل حقل يحتاج label مرتبطاً بـ for وid، وسمة name ليصل إلى الخادم.
فحص المتصفح بـ required وtype للراحة، والخادم يتحقق دائماً من جديد.
Lighthouse ومدقق W3C يكملان اختبار لوحة المفاتيح ولا يغنيان عنه.
مخطط
مسودة←قائمة الجودة (4 محاور)
←مدقق W3C + Lighthouse
←اختبار Tab + موبايل
←إصلاح←نشر←مشاركة الرابط
مختبر — نموذج تواصل
النموذج هنا للتخطيط — الإرسال الفعلي يحتاج برنامجاً على الخادم أو خدمة نماذج خارجية. انقر على كل label وتأكد أن المؤشر ينتقل إلى حقله.
معاينة مباشرة
مهمة عملية
طبّق قائمة الجودة على صفحتك من الدرس 8: أصلح 3 نقاط على الأقل، وسجّل درجات Lighthouse الأربع قبل الإصلاح وبعده.
اختبر فهمك (1/3)
ما الخطوة الأنسب بعد إنهاء هذا المسار؟
اختبر فهمك (2/3)
نقرت على عبارة «البريد الإلكتروني» بجانب الحقل فلم ينتقل المؤشر إليه. ما السبب؟
اختبر فهمك (3/3)
نموذج يصل إلى الخادم بلا قيمة البريد رغم أن المستخدم كتبه. أي سمة نسيتها غالباً؟