HTML اختصار لـ HyperText Markup Language — وده اسم بيوصف وظيفتها بالظبط. مش لغة برمجة (مفيش منطق أو حسابات)، هي لغة وصف هيكل. بتقول للمتصفح: "الجزء ده عنوان، الجزء ده فقرة، الجزء ده صورة."
تخيل إنك بتبني بيت — HTML هي الطوب والحيطان والأبواب. CSS هي الدهان والديكور. JavaScript هي الكهرباء والمصاعد. مش ممكن تبدأ بالدهان قبل ما تبني الحيطان.
HTML ظهرت سنة 1991 على إيد Tim Berners-Lee. النسخة الحالية هي HTML5 (2014)، وهي اللي هنتعلمها بالكامل. مش في HTML6 — النسخة دي بتتطور باستمرار من خلال معايير W3C وWHATWG.
كل صفحة على الإنترنت — من Google لـ Facebook لـ GitHub — مبنية بـ HTML في الأساس. حتى لو الصفحة معقدة جداً، لو فتحت الـ "View Source" هتلاقي HTML.
افتح أي موقع، اضغط كليك يمين ← "View Page Source" أو Ctrl+U. شوف الـ HTML الحقيقي. ده مش غش — ده طريقة كل المبرمجين بيتعلموا بيها.
لما بتكتب رابط في المتصفح وتضغط Enter، بيحصل ده بالترتيب:
- DNS Lookup — المتصفح بيحول اسم الموقع لـ IP address
- HTTP Request — بيطلب ملف HTML من السيرفر
- HTML Parsing — المتصفح بيقرأ الـ HTML ويبني منه شجرة اسمها DOM
- CSS + JS — بيحمّل الملفات التانية ويطبق التصميم والتفاعل
- Rendering — بيرسم الصفحة على الشاشة
DOM (Document Object Model) — الشجرة اللي المتصفح بيبنيها من HTML. كل tag بيبقى "node" في الشجرة. JavaScript بتتحكم في الصفحة عن طريق تعديل الـ DOM. فاهم DOM = فاهم إزاي الويب شغال فعلاً.
كل ملف HTML لازم يبدأ بالبنية دي — مفيش استثناء:
<!-- إعلان نوع الملف — لازم يكون أول سطر —> <!DOCTYPE html> <!-- العنصر الجذر — lang مهمة للـ SEO والـ Accessibility —> <html lang="ar" dir="rtl"> <head> <!-- ترميز الأحرف — لازم يكون أول عنصر في head —> <meta charset="UTF-8" /> <!-- مهم للموبايل — بدونه الصفحة بتبان صغيرة —> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!-- عنوان التبويب في المتصفح —> <title>اسم صفحتك</title> </head> <body> <!-- كل المحتوى اللي بيظهر للمستخدم بيتحط هنا —> <h1>مرحباً بالعالم!</h1> </body> </html>
مرحباً بالعالم!
كل جزء له وظيفة محددة:
- <!DOCTYPE html> — مش tag، ده إعلان بيقول للمتصفح "الملف ده HTML5". بدونه المتصفح ممكن يدخل "Quirks Mode" وتظهر الصفحة بشكل غلط.
- <html lang="ar"> — الغلاف الخارجي. lang مهم جداً: بيساعد Google، screen readers، والمتصفح نفسه.
- <head> — معلومات عن الصفحة، مش بتظهر للمستخدم. هنا بتحط SEO، CSS، الخطوط، وغيره.
- <body> — المحتوى الفعلي. كل اللي المستخدم بيشوفه بيتحط هنا.
كتير بيحطوا كل حاجة في <body> من غير <head>. ده بيشتغل ظاهرياً بس بيفقدك SEO والـ encoding الصح وتوافق الموبايل.
1. نسيان الـ DOCTYPE تماماً
2. نسيان إغلاق Tag (Unclosed Tag)
3. استخدام id بدل class للتنسيق المتكرر
- حمّل VS Code وثبّت إضافة "Live Server" (بتفتح صفحتك وتحدثها تلقائياً)
- أنشئ مجلد اسمه my-portfolio وجوّاه ملف index.html
- اكتب البنية الأساسية من غير نسخ لصق — بإيدك من الذاكرة
- حط في body اسمك كـ <h1> وكلمة عنك كـ <p>
- افتح الملف بـ Live Server وشوف النتيجة في المتصفح
- افتح DevTools (F12) ← Elements وشوف الـ DOM شجرة
- غيّر lang="ar" لـ lang="en" وشوف الفرق في اتجاه النص
- "VS Code shortcuts for HTML" — بيوفر عليك وقت كتير
- اكتب "!" وضغط Tab في VS Code — بيكتب لك البنية كاملة (Emmet)
في HTML 6 مستويات عناوين. الأرقام مش بس للحجم — هي تسلسل منطقي للمحتوى. فكر فيها كفهرس كتاب.
<h1>اسم الموقع أو عنوان الصفحة الرئيسي</h1> <h2>قسم رئيسي (About / Skills / Projects)</h2> <h3>قسم فرعي داخل الـ h2</h3> <h4>تفصيلة داخل الـ h3</h4> <!-- h5, h6 نادر الاستخدام —>
Google بتقرأ الـ headings وبتفهم منها موضوع صفحتك. h1 مع h2s منظمة = أحسن ترتيب في نتائج البحث.
<!-- فقرة نص عادية —> <p>النص بتاعك هنا. كل فقرة في عنصر p منفصل.</p> <!-- سطر جديد داخل نفس الفقرة —> <p>سطر أول<br>سطر تاني في نفس الفقرة</p> <!-- خط فاصل أفقي —> <hr> <!-- اقتباس —> <blockquote cite="https://المصدر.com"> "الكود الجيد هو الكود المقروء." </blockquote> <!-- نص مسبق التنسيق (يحافظ على المسافات والأسطر) —> <pre> def hello(): print("مرحباً") </pre> <!-- كود inline داخل نص —> <p>استخدم <code>console.log()</code> لطباعة القيم.</p>
لو محتاج مسافة كبيرة بين عناصرين، مش الحل br متكرر — الحل CSS margin. br ليها وظيفة واحدة: سطر جديد داخل نفس الفقرة (زي عنوان قصيدة).
<p> ده <strong>مهم جداً</strong> وده <em>بنبرة مختلفة</em>. </p> <p> السعر الأصلي <del>٢٠٠ جنيه</del> بقى <ins><strong>١٠٠ جنيه</strong></ins> فقط! </p> <p> اضغط <kbd>Ctrl</kbd> + <kbd>S</kbd> للحفظ. </p> <abbr title="HyperText Markup Language">HTML</abbr> <p>E = mc<sup>2</sup></p>
<!-- Unordered List — لما الترتيب مش مهم —> <ul> <li>HTML</li> <li>CSS</li> <li>JavaScript</li> </ul> <!-- Ordered List — لما الترتيب مهم (خطوات) —> <ol> <li>افتح VS Code</li> <li>أنشئ ملف index.html</li> <li>ابدأ تكتب كود</li> </ol> <!-- Description List — مصطلح وتعريفه —> <dl> <dt>HTML</dt> <dd>لغة ترميز الهيكل</dd> <dt>CSS</dt> <dd>لغة التصميم</dd> </dl> <!-- قائمة متداخلة (nested) —> <ul> <li>Frontend <ul> <li>HTML</li> <li>CSS</li> </ul> </li> </ul>
1. استخدام <br> بدل CSS للمسافات
2. تخطي مستوى في العناوين (Heading Levels)
3. نسيان </li> أو استخدام عنصر غير li داخل ul/ol
- أضف في index.html قسم About: <h2> + <p> بيشرح مين أنت
- أضف قسم Skills: <h2> + <ul> فيها مهاراتك (ولو حتى مبتدئ)
- استخدم <strong> على أهم كلمة في وصفك
- أضف <hr> بين الأقسام
- اعمل Ordered List لخطواتك في تعلم البرمجة
- جرب <mark> على أهم مهارة عندك
- "HTML list types examples" — شوف استخدامات مختلفة
- "HTML semantic vs presentational elements" — فرق مهم
<!-- رابط خارجي — يفتح في تاب جديد —> <a href="https://google.com" target="_blank" rel="noopener noreferrer"> زور Google </a> <!-- رابط داخلي لصفحة تانية —> <a href="about.html">عني</a> <!-- Anchor Link — ينقل لجزء في نفس الصفحة —> <a href="#projects">مشاريعي</a> <!-- والـ section اللي هيتنقل ليه —> <section id="projects">...</section> <!-- رابط إيميل —> <a href="mailto:email@example.com">راسلني</a> <!-- رابط تليفون —> <a href="tel:+201234567890">اتصل بي</a> <!-- تحميل ملف —> <a href="cv.pdf" download="CV-Yahya">تحميل CV</a>
لما بتستخدم target="_blank"، لازم تضيف rel="noopener noreferrer". من غيرها، الصفحة اللي بتفتح ممكن تتحكم في صفحتك عن طريق window.opener — ده ثغرة أمنية حقيقية.
<!-- صورة أساسية — alt مش اختياري! —> <img src="PIC/profile.jpg" alt="صورة شخصية ليحيى السلامي" width="300" height="300" /> <!-- Lazy Loading — يحمل الصورة بس لما تظهر في الشاشة —> <img src="PIC/project.jpg" alt="لقطة شاشة مشروع Portfolio" loading="lazy" /> <!-- figure + figcaption — صورة مع تعليق —> <figure> <img src="PIC/project.jpg" alt="مشروع Portfolio"/> <figcaption>صفحة Portfolio بنيتها بـ HTML وCSS</figcaption> </figure> <!-- picture — صور مختلفة لأحجام مختلفة —> <picture> <source media="(max-width: 640px)" srcset="small.jpg"> <source media="(max-width: 1024px)" srcset="medium.jpg"> <img src="large.jpg" alt="صورة متجاوبة"> </picture>
سطر واحد بيحسّن أداء موقعك بشكل كبير. المتصفح مش هيحمل الصور اللي مش ظاهرة في الشاشة حتى المستخدم يوصلها.
<!-- فيديو —> <video src="demo.mp4" controls width="640" poster="thumbnail.jpg" preload="metadata" > المتصفح ده مش بيدعم الفيديو. </video> <!-- صوت —> <audio src="podcast.mp3" controls></audio> <!-- YouTube مضمّن —> <iframe src="https://www.youtube.com/embed/VIDEO_ID" width="560" height="315" title="عنوان الفيديو للـ Accessibility" allowfullscreen loading="lazy" ></iframe>
1. نسيان alt في الصور
alt="" (فاضية لكن موجودة) عشان screen readers تتخطاها بهدوء.2. روابط خارجية بدون rel="noopener noreferrer"
rel="noopener noreferrer". بدونها، الموقع اللي بتفتحه في تاب جديد يقدر يوصل لـ window.opener بتاع صفحتك الأصلية وأحياناً يعيد توجيهها لموقع ضار (تكتيك تصيّد معروف).3. مسار صورة غلط (Broken Image)
- أضف صورتك الشخصية بـ <figure> و<figcaption> مع alt واضح
- أنشئ قسم "تواصل معي" وحط روابط GitHub وLinkedIn وإيميلك
- خلي الروابط الخارجية تفتح في تاب جديد مع rel="noopener noreferrer"
- أضف Anchor Links في الـ navbar (لو عملت navbar) للتنقل بين الأقسام
- أضف رابط "تحميل CV" بـ download attribute
- جرب <picture> مع نفس الصورة بأحجام مختلفة
قبل HTML5، المبرمجين كانوا بيحطوا كل حاجة في <div>. المتصفح مش كان يعرف إيه header وإيه footer. HTML5 جابت عناصر "بتوصف معناها" — وده سمّوه Semantic HTML.
<body> <!-- رأس الصفحة: اللوجو، اسم الموقع —> <header> <h1>Yahya.DEV</h1> <!-- قائمة التنقل —> <nav> <ul> <li><a href="#about">عني</a></li> <li><a href="#projects">مشاريعي</a></li> <li><a href="#contact">تواصل</a></li> </ul> </nav> </header> <!-- المحتوى الرئيسي — واحد بس في الصفحة —> <main> <!-- قسم: موضوع واضح، عنوان —> <section id="about"> <h2>عني</h2> <p>أنا Yahya...</p> </section> <!-- article: محتوى مستقل قائم بذاته —> <section id="projects"> <h2>مشاريعي</h2> <article> <h3>مشروع Portfolio</h3> <p>صفحة شخصية بـ HTML وCSS</p> </article> </section> </main> <!-- محتوى جانبي مرتبط بالصفحة —> <aside> <h3>مهارات سريعة</h3> </aside> <!-- تذييل الصفحة —> <footer> <p>© 2026 Yahya.DEV</p> </footer> </body>
الفرق بين <section> و<article>: section = "قسم من الصفحة" مش منطقي لوحده. article = محتوى مستقل لو نقلته لصفحة تانية هيبقى منطقي. مثال: مقالة في جريدة = article. قسم في المقالة = section.
كتير ناس زمان كانوا بيبنوا layout الصفحة بجداول. ده غلط تماماً الآن. الجداول بُنيت للبيانات الجدولية زي: جداول مقارنة، بيانات مالية، مواعيد. لـ layout استخدم CSS Grid أو Flexbox.
<table> <!-- caption: عنوان الجدول للـ accessibility —> <caption>مقارنة بين Frontend Technologies</caption> <!-- رأس الجدول —> <thead> <tr> <th>اللغة</th> <th>الوظيفة</th> <th>الصعوبة</th> </tr> </thead> <!-- جسم الجدول —> <tbody> <tr> <td>HTML</td> <td>الهيكل</td> <td>سهل</td> </tr> <tr> <!-- colspan: خلية تمتد على أكثر من عمود —> <td colspan="2">CSS + JavaScript</td> <td>متوسط → متقدم</td> </tr> </tbody> <!-- تذييل الجدول —> <tfoot> <tr> <td colspan="3">مصدر: MDN Web Docs</td> </tr> </tfoot> </table>
<form action="https://formspree.io/f/your-id" method="POST" > <!-- fieldset: تجميع حقول مترابطة —> <fieldset> <legend>بياناتك</legend> <!-- label مهم: يربط الوصف بالحقل —> <label for="name">الاسم:</label> <input type="text" id="name" name="name" placeholder="اسمك الكامل" required autocomplete="name" /> <label for="email">الإيميل:</label> <input type="email" id="email" name="email" required /> </fieldset> <label for="msg">رسالتك:</label> <textarea id="msg" name="message" rows="5" required minlength="10" ></textarea> <button type="submit">إرسال الرسالة</button> </form>
| النوع | الاستخدام | المتصفح يعمل |
|---|---|---|
text | نص عام | لا شيء |
email | بريد إلكتروني | يتحقق من صحة الإيميل |
password | كلمة مرور | يخفي النص |
number | رقم | يقبل أرقام فقط + min/max |
date | تاريخ | date picker |
tel | رقم تليفون | لوحة أرقام على موبايل |
url | رابط URL | يتحقق من صحة الرابط |
checkbox | اختيار متعدد | ✓ |
radio | اختيار واحد | ● |
file | رفع ملف | file picker |
range | شريط تمرير | slider |
color | لون | color picker |
search | بحث | زرار مسح |
hidden | قيمة خفية | مش بيظهر للمستخدم |
1. نسيان for/id لربط label بالـ input
for="name" بنفس قيمة الـ id بتاع الـ input. بدون الربط ده، الضغط على نص الـ label مش هيفعّل الـ input، وscreen readers مش هتقدر تربط الوصف بالحقل — وده مشكلة accessibility حقيقية مش مجرد تفصيلة.2. استخدام div بدل العناصر الدلالية (Semantic Elements)
3. زرار submit بدون type محدد جوّا form فيها أكتر من زرار
type="submit" حتى لو ماحددتهوش. لو عندك زرار مش المفروض يبعت الفورم (زي "حفظ مؤقت" أو "إلغاء")، لازم تحدد له type="button" صراحةً.- حوّل كل الـ <div> اللي عندك لعناصر semantic صح: <header>, <main>, <section>, <footer>
- أضف <nav> مع روابط Anchor للأقسام
- أضف قسم Contact مع form فيها: الاسم، الإيميل، رسالة، وزرار إرسال
- كل حقل لازم يكون عنده label مرتبط بيه بـ for/id
- أضف required للحقول الإلزامية
- "Formspree tutorial" — عشان تشغّل الـ contact form فعلاً
- "HTML5 form validation tutorial" — شوف إزاي required وpattern بيشتغلوا
<head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <!-- ──── SEO الأساسي ──── —> <title>Yahya Al-sulami | Full-Stack Developer</title> <meta name="description" content="مطور ويب متخصص في HTML وCSS وJavaScript. شاهد مشاريعي وتواصل معي."/> <meta name="author" content="Yahya Al-sulami"/> <link rel="canonical" href="https://yahya.dev/"/> <!-- ──── Open Graph (مشاركة سوشيال ميديا) ──── —> <meta property="og:title" content="Yahya.DEV — Portfolio"/> <meta property="og:description" content="مطور ويب — Portfolio"/> <meta property="og:image" content="https://yahya.dev/PIC/og-image.jpg"/> <meta property="og:url" content="https://yahya.dev/"/> <meta property="og:type" content="website"/> <!-- ──── Twitter Card ──── —> <meta name="twitter:card" content="summary_large_image"/> <meta name="twitter:title" content="Yahya.DEV"/> </head>
<!-- Skip link: للمكفوفين يتخطوا الـ navbar —> <a href="#main" class="skip-link">تخطى للمحتوى الرئيسي</a> <!-- role + aria-label على الـ nav —> <nav aria-label="القائمة الرئيسية">...</nav> <!-- زرار بدون نص (icon فقط) —> <button aria-label="إغلاق القائمة"> <svg aria-hidden="true">...</svg> </button> <!-- Loading state —> <div aria-live="polite" aria-atomic="true"> جاري التحميل... </div> <!-- صورة ديكور: مفيش معنى، مخليش الـ screen reader يقراها —> <img src="decoration.svg" alt="" aria-hidden="true"/> <!-- tabindex: ترتيب التنقل بالكيبورد —> <div tabindex="0" role="button">عنصر تفاعلي</div>
اضغط Tab وتنقل في صفحتك من غير ماوس. لو مش قادر توصل لكل حاجة — فيه مشكلة Accessibility. ده نفس الاختبار اللي Google بتعمله.
| الخاصية | الوظيفة | مثال |
|---|---|---|
id | معرّف فريد | id="hero" |
class | تصنيف CSS | class="card active" |
style | CSS inline (تجنبه!) | style="color:red" |
hidden | إخفاء العنصر | hidden |
title | tooltip عند hover | title="نص توضيحي" |
lang | لغة هذا الجزء | lang="en" |
dir | اتجاه النص | dir="ltr" |
contenteditable | قابل للتعديل | contenteditable="true" |
data-* | بيانات خاصة | data-id="42" |
draggable | قابل للسحب | draggable="true" |
<!-- data-* بتستخدم لتخزين بيانات تقرأها JavaScript —> <div class="project-card" data-id="1" data-category="frontend" data-year="2026" > مشروع Portfolio </div> <!-- في JavaScript بتوصلها كده —> <!-- const card = document.querySelector('.project-card'); —> <!-- card.dataset.id → "1" —> <!-- card.dataset.category → "frontend" —>
<!── details + summary: accordion بدون JavaScript ──> <details> <summary>ما هي تجربتك؟</summary> <p>لدي سنة خبرة في تطوير الويب...</p> </details> <!── dialog: modal بـ HTML خالص ──> <dialog id="myDialog"> <h2>تأكيد الإرسال</h2> <p>تم إرسال رسالتك بنجاح!</p> <button onclick="this.closest('dialog').close()">إغلاق</button> </dialog> <button onclick="document.getElementById('myDialog').showModal()"> فتح الـ Modal </button> <!── template: HTML لا يظهر — JavaScript بتستخدمه ──> <template id="project-card-template"> <div class="project-card"> <h3 class="proj-title"></h3> <p class="proj-desc"></p> </div> </template> <!── canvas: للرسم والألعاب بـ JavaScript ──> <canvas id="myCanvas" width="400" height="200"></canvas>
1. نسيان viewport meta tag
<meta name="viewport" content="width=device-width, initial-scale=1.0">، المتصفحات على الموبايل بتفترض إن الصفحة مصممة لشاشة desktop عريضة (980px تقريباً) وبتعرضها مصغّرة بالكامل. ده أشهر سبب لصفحة "تبان تمام على اللابتوب لكن مكسورة على الموبايل".2. استخدام aria-label على عنصر عنده نص بالفعل
3. كتابة data-* attribute بأحرف كبيرة (camelCase) في الـ HTML
data-project-id="5" مش data-projectId="5". JavaScript بتحوّلها تلقائياً لـ camelCase في الـ dataset (تبقى element.dataset.projectId) — لكن الـ HTML نفسها لازم تتكتب بـ kebab-case دايماً.- أضف كل Meta Tags الأساسية في <head>: title، description، viewport
- أضف Open Graph tags (og:title, og:description, og:image)
- تأكد إن كل صور عندها alt واضح
- أضف aria-label للـ nav و loading="lazy" لكل الصور
- جرّب تتنقل في صفحتك بالـ Tab فقط — كل حاجة لازم تكون accessible
- أضف <details> للـ FAQ أو "اقرأ أكثر" في الـ About
- استخدم data-category في مشاريعك (هتفيدك في JavaScript لاحقاً)
- "Open Graph tester" — اختبر كيف بيظهر موقعك لما حد يشيره على Facebook
- "WAVE accessibility checker" — أداة مجانية بتحلل صفحتك
- "PageSpeed Insights" — Google بتقيّم سرعة وأداء صفحتك مجاناً
- Portfolio HTML كامل مع كل الأقسام: Hero, About, Skills, Projects, Contact, Footer
- 3 مشاريع حقيقية على الأقل في قسم Projects (ولو صغيرة)
- Meta Tags + Open Graph كاملة
- اختبار Accessibility بالـ Tab
- رفع المشروع على GitHub وتفعيل GitHub Pages
- فتح الصفحة من موبايل والتأكد إنها بتظهر صح
- أضف Structured Data (JSON-LD) لصفحتك
- اختبر صفحتك على PageSpeed Insights وطلّع نتيجة 90+
- أضف <meta name="theme-color"> لتلوين شريط العنوان في الموبايل
- "How to deploy to GitHub Pages" — عشان تنشر موقعك مجاناً
- "HTML validator W3C" — تأكد إن الكود بتاعك صح
- "Lighthouse audit Chrome DevTools" — تقرير كامل عن الأداء والـ SEO