أفضل ممارسات HTML
HTML المتين هو أساس كل موقع رائع. هذه النصائح تساعدك في كتابة ترميز دلالي وقوي ومستقبلي تحبه المتصفحات وقارئات الشاشة.
وضع سمات width و height صريحة على الصور يتيح للمتصفح حجز المساحة الصحيحة قبل تحميل الصورة، مما يقضي على تغيير التخطيط التراكمي (CLS) — أحد مؤشرات أداء الويب الأساسية من Google.
<!-- ❌ سيء: المتصفح لا يعرف الحجم حتى تحميل الصورة --> <img src="hero.jpg" alt="صورة رئيسية"> <!-- ✅ جيد: المساحة محجوزة فوراً --> <img src="hero.jpg" alt="صورة رئيسية" width="1200" height="630" loading="lazy">
aspect-ratio: auto في CSS وسيحسب المتصفح النسبة الصحيحة تلقائياً، حتى عندما يغير CSS حجم الصورة.يساعد هيكل المستند المبني بعناوين متداخلة بشكل صحيح كلاً من محركات البحث على فهم التسلسل الهرمي للمحتوى الخاص بك ومستخدمي قارئات الشاشة على التنقل بكفاءة في الصفحة.
<h1>عنوان الصفحة (واحد لكل صفحة)</h1> <h2>القسم الرئيسي</h2> <h3>القسم الفرعي</h3> <h3>قسم فرعي آخر</h3> <h2>قسم رئيسي آخر</h2>
عند فتح الروابط في علامة تبويب جديدة باستخدام target="_blank"، يمكن للصفحة المفتوحة الوصول إلى صفحتك عبر window.opener. إضافة rel="noopener noreferrer" تمنع هذه الثغرة الأمنية وتوقف أيضاً إرسال معلومات المُحيل.
<!-- ❌ غير آمن --> <a href="https://example.com" target="_blank">زيارة</a> <!-- ✅ آمن --> <a href="https://example.com" target="_blank" rel="noopener noreferrer">زيارة</a>
تخبر سمة autocomplete المتصفحات ومديري كلمات المرور بكيفية ملء حقول النموذج مسبقاً. هذا يحسن بشكل كبير معدلات إكمال النماذج على الجوال.
<input type="text" autocomplete="given-name"> <input type="email" autocomplete="email"> <input type="tel" autocomplete="tel"> <input type="password" autocomplete="current-password"> <input type="text" autocomplete="postal-code">
تتحكم وسوم Open Graph الوصفية في كيفية ظهور صفحتك عند مشاركتها على منصات التواصل الاجتماعي مثل فيسبوك ولينكد إن وتويتر/إكس. بدونها، تختار المنصات المحتوى عشوائياً.
<meta property="og:title" content="عنوان الصفحة"> <meta property="og:description" content="وصف قصير"> <meta property="og:image" content="https://yourdomain.com/og.jpg"> <meta property="og:url" content="https://yourdomain.com/page"> <meta property="og:type" content="website"> <!-- تويتر/إكس --> <meta name="twitter:card" content="summary_large_image">
نصائح وحيل CSS
CSS الحديث قوي بشكل لا يصدق. تغطي هذه النصائح التخطيط والخصائص المخصصة والأنماط التي توفر عليك الوقت وتحافظ على نظافة أوراق الأنماط.
توقف عن معاناة حيل التموضع. خاصية place-items المختصرة في CSS Grid توسّط المحتوى أفقياً وعمودياً في سطرين — بدون calc ولا تحويلات.
.center-everything { display: grid; place-items: center; } /* يعمل لتوسيط الصفحة بالكامل أيضاً */ body { display: grid; place-items: center; min-height: 100vh; }
تتيح لك خصائص CSS المخصصة (المتغيرات) تعريف رموز التصميم الخاصة بك مرة واحدة وإعادة استخدامها في كل مكان. كما أنها تتحدّث في الوقت الفعلي، مما يجعل الوضع الليلي والتخصيص أمراً بسيطاً.
:root { --color-primary: #6366f1; --color-bg: #ffffff; --radius-md: 12px; --spacing-md: 16px; } @media (prefers-color-scheme: dark) { :root { --color-bg: #0d1117; } } .btn { background: var(--color-primary); border-radius: var(--radius-md); padding: var(--spacing-md); }
تسمح clamp(min, preferred, max) لأحجام الخطوط بالتدرج بسلاسة مع عرض إطار العرض — بدون الحاجة لوسائط استعلام. القيمة الوسطى عادة ما تكون بوحدة vw.
/* clamp(الحد الأدنى, المفضل, الحد الأقصى) */ h1 { font-size: clamp(1.8rem, 5vw, 3.5rem); } p { font-size: clamp(0.9rem, 2vw, 1.1rem); line-height: 1.7; max-width: 65ch; /* عرض القراءة الأمثل */ }
قم بتمكين التمرير السلس عالمياً واستخدم scroll-margin-top على أهداف الارتساء لضمان عدم تداخل الترويسات الثابتة مع المحتوى الذي يتم التمرير إليه.
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } } /* تعويض للترويسة الثابتة (مثلاً بارتفاع 70px) */ [id] { scroll-margin-top: 90px; }
scroll-behavior: smooth في وسائط استعلام prefers-reduced-motion: no-preference — بعض المستخدمين يعانون من دوار الحركة بسبب التمرير المتحرك.ينشئ نمط auto-fill + minmax() شبكة تضبط عدد الأعمدة تلقائياً بناءً على المساحة المتاحة — بدون الحاجة لوسائط استعلام.
.card-grid { display: grid; grid-template-columns: repeat( auto-fill, minmax(280px, 1fr) ); gap: 24px; } /* عمود واحد على الجوال → 2 → 3 → 4 تلقائياً */
لا تقم أبداً بـ outline: none عالمياً — إنه يكسر التنقل بلوحة المفاتيح. استخدم :focus-visible لإظهار حلقات التركيز فقط لمستخدمي لوحة المفاتيح، مما يحافظ على التصميم نظيفاً لمستخدمي الفأرة.
/* ❌ لا تفعل هذا أبداً */ * { outline: none; } /* ✅ أخفِ للفأرة، أظهر للوحة المفاتيح */ :focus:not(:focus-visible) { outline: none; } :focus-visible { outline: 2px solid #6366f1; outline-offset: 3px; border-radius: 4px; }
نصائح JavaScript
اكتب JavaScript أنظف وأفضل أداءً باستخدام هذه الأنماط الحديثة وواجهات برمجة التطبيقات الخاصة بالمتصفح.
بدلاً من الاستماع إلى حدث scroll (الذي ينطلق مئات المرات في الثانية)، استخدم واجهة IntersectionObserver للتفاعل فقط عندما تدخل العناصر إلى إطار العرض أو تغادره.
const observer = new IntersectionObserver( (entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); observer.unobserve(entry.target); // توقف عن المراقبة } }); }, { rootMargin: '0px 0px -50px 0px' } ); document.querySelectorAll('.animate-on-scroll') .forEach(el => observer.observe(el));
أحداث مثل resize و input تنطلق بسرعة كبيرة. التأخير يؤجل التنفيذ حتى يتوقف المستخدم عن التفاعل، مما يمنع العمل غير الضروري.
function debounce(fn, delay = 300) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), delay); }; } // الاستخدام window.addEventListener('resize', debounce(() => { recalculateLayout(); }, 200) );
واجهة navigator.clipboard الحديثة قائمة على الوعود وهي أنظف بكثير من حيلة document.execCommand('copy') القديمة.
async function copyToClipboard(text) { try { await navigator.clipboard.writeText(text); showToast('تم النسخ!'); } catch (err) { console.error('فشل النسخ:', err); } } // الاستخدام document.querySelector('.copy-btn') .addEventListener('click', () => copyToClipboard('النص المراد نسخه') );
يمكن أن يرمي localStorage استثناءً في وضع التصفح الخاص أو عند امتلاء التخزين. قم دائماً بتغليفه في دالة مساعدة try/catch.
const storage = { get(key, fallback = null) { try { const item = localStorage.getItem(key); return item ? JSON.parse(item) : fallback; } catch { return fallback; } }, set(key, value) { try { localStorage.setItem(key, JSON.stringify(value)); return true; } catch { return false; } } }; storage.set('theme', 'dark'); const theme = storage.get('theme', 'light');
بالنسبة للتحريكات المدفوعة بـ JavaScript (مثل canvas، GSAP)، تحقق من إعداد prefers-reduced-motion للمستخدم وقم بتبسيط التحريكات أو تعطيلها وفقاً لذلك.
const prefersReduced = window .matchMedia('(prefers-reduced-motion: reduce)') .matches; if (!prefersReduced) { startAnimations(); } else { showStaticFallback(); }
نصائح الأداء
المواقع السريعة تحتل مراتب أعلى، وتحول أفضل، وتحافظ على سعادة المستخدمين. تغطي هذه النصائح أكبر المكاسب لأداء الويب.
بدون font-display: swap، تخفي المتصفحات النص حتى يتم تحميل الخط المخصص (FOIT). معها، يُعرض خط النظام فوراً ثم يُستبدل — مما يحسن بشكل كبير من أكبر رسم محتوى (LCP).
<!-- الخطوة 1: preconnect --> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <!-- الخطوة 2: أضف &display=swap إلى الرابط --> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&family=Cairo:wght@700;900&display=swap" rel="stylesheet">
صور WebP و AVIF أصغر بكثير من JPEG و PNG بنفس الجودة. استخدم عنصر <picture> لتقديم التنسيقات الحديثة مع خيار احتياطي JPEG للمتصفحات القديمة.
<picture> <source srcset="hero.avif" type="image/avif"> <source srcset="hero.webp" type="image/webp"> <img src="hero.jpg" alt="صورة رئيسية" width="1200" height="630" loading="lazy"> </picture>
وسوم <script> العادية تحظر تحليل HTML. defer يشغل البرنامج النصي بعد اكتمال التحليل (بالترتيب). async يشغل البرامج النصية بمجرد تنزيلها (الترتيب غير مضمون).
<!-- يحظر العرض ❌ --> <script src="app.js"></script> <!-- يعمل بالترتيب، بعد DOM ✅ (استخدم لمعظم البرامج النصية) --> <script src="app.js" defer></script> <!-- يعمل فوراً عندما يكون جاهزاً ✅ (التحليلات، الإعلانات) --> <script src="analytics.js" async></script>
التزم بتحريك transform و opacity — فهي تعمل على خيط منظم GPU دون إثارة التخطيط أو الرسم. أضف will-change فقط إذا قمت بتحليل الأداء ورأيت فائدة حقيقية.
/* ❌ يثير التخطيط (مكلف) */ .bad { transition: width 0.3s, top 0.3s; } /* ✅ مركب على GPU (رخيص) */ .good { transition: transform 0.3s, opacity 0.3s; } /* استخدم باعتدال، فقط قبل التحريكات المعقدة */ .modal-enter { will-change: transform; } .modal-entered { will-change: auto; } /* أعد التعيين بعد */
استخدم <link rel="preload"> لإخبار المتصفح بجلب الموارد الحرجة مبكراً — قبل أن يكتشفها في CSS أو JS. مثالي للصور الرئيسية والخطوط الحرجة والبرامج النصية الأساسية.
<!-- تحميل مسبق للصورة الرئيسية (عنصر LCP) --> <link rel="preload" as="image" href="hero.webp" fetchpriority="high"> <!-- تحميل مسبق للخط الحرج --> <link rel="preload" as="font" href="font.woff2" type="font/woff2" crossorigin>
نصائح سهولة الوصول
سهولة الوصول ليست قائمة مراجعة — إنها تصميم جيد. هذه النصائح تساعد في جعل مواقعك قابلة للاستخدام من قبل الجميع، بما في ذلك مستخدمي قارئات الشاشة والمتنقلين بلوحة المفاتيح.
الأزرار التي تحتوي على أيقونة فقط ليس لها نص مرئي لتعلنه قارئات الشاشة. أضف aria-label لتوفير تسمية وصفية.
<!-- ❌ قارئ الشاشة يقول "زر" --> <button><i class="fa-solid fa-times"></i></button> <!-- ✅ قارئ الشاشة يقول "إغلاق الحوار" --> <button aria-label="إغلاق الحوار"> <i class="fa-solid fa-times" aria-hidden="true"></i> </button>
تخبر سمة lang قارئات الشاشة باللغة التي يجب استخدامها، وتمكن الوصل الصحيح في CSS، وتساعد أدوات الترجمة في تحديد لغة المحتوى. بالنسبة للغات RTL، أضف أيضاً dir="rtl".
<!-- الإنجليزية --> <html lang="en"> <!-- العربية (RTL) --> <html lang="ar" dir="rtl"> <!-- الفرنسية --> <html lang="fr">
يتطلب WCAG 2.1 AA نسبة تباين لا تقل عن 4.5:1 للنص العادي و 3:1 للنص الكبير (18px+ غامق أو 24px+ عادي). استخدم فاحص تباين قبل النشر.
/* ❌ #6b7280 على #fff = 4.48:1 (يفشل AA للنص الصغير) */ .muted { color: #6b7280; background: #fff; } /* ✅ #4b5563 على #fff = 7.0:1 (يجتاز AA و AAA) */ .muted { color: #4b5563; background: #fff; }
تحتاج أحياناً إلى نص يمكن لقارئات الشاشة فقط سماعه — مثل رابط تخطي إلى المحتوى أو تسمية لعنصر مرئي. فئة .sr-only المساعدة تخفيه بصرياً مع إبقائه قابلاً للوصول.
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; } <!-- مثال رابط التخطي --> <a href="#main" class="sr-only">تخطي إلى المحتوى</a>
عندما يكون الحوار المشروط مفتوحاً، يجب حصر تركيز لوحة المفاتيح داخله. وإلا فإن Tab سيركز العناصر خلف الطبقة الفوقية — مما يجعل الحوار غير قابل للاستخدام لمستخدمي لوحة المفاتيح.
function trapFocus(modal) { const focusable = modal.querySelectorAll( 'a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])' ); const first = focusable[0]; const last = focusable[focusable.length - 1]; modal.addEventListener('keydown', e => { if (e.key !== 'Tab') return; if (e.shiftKey ? document.activeElement === first : document.activeElement === last) { e.preventDefault(); (e.shiftKey ? last : first).focus(); } }); first.focus(); }
نصائح التجاوب والجوال
حركة المرور على الجوال هي المهيمنة. تضمن هذه النصائح أن تعمل تصميماتك بشكل جميل عبر كل حجم شاشة — من هاتف 320px إلى شاشة 4K.
بدون وسمة viewport الوصفية، تعرض متصفحات الجوال بعرض سطح مكتب ~980px ثم تبتعد. اسمح بتكبير المستخدم — تعطيله هو حاجز رئيسي لسهولة الوصول ويكسر تكبير المتصفح.
<!-- ❌ يعطل تكبير المستخدم (انتهاك لسهولة الوصول) --> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <!-- ✅ صحيح: يسمح بالتكبير حتى 5× --> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=5">
توصي إرشادات Apple HIG و WCAG 2.5.5 بحد أدنى 44×44 بكسل CSS لأهداف اللمس. الأهداف الصغيرة تحبط المستخدمين وتؤدي إلى نقرات خاطئة. يمكنك توسيع المنطقة القابلة للنقر دون تغيير الحجم المرئي باستخدام padding أو العناصر الزائفة.
/* توسيع منطقة اللمس دون تغيير مرئي */ .icon-btn { position: relative; width: 24px; height: 24px; } .icon-btn::before { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); min-width: 44px; min-height: 44px; }
خصائص CSS المنطقية مثل margin-inline-start بدلاً من margin-left تنعكس تلقائياً بناءً على وضع كتابة المستند — مما يجعل دعم RTL بلا مجهود تقريباً.
/* فيزيائي (لا ينعكس لـ RTL) */ .icon { margin-right: 8px; } /* منطقي (ينعكس تلقائياً في RTL) */ .icon { margin-inline-end: 8px; } /* المزيد من أمثلة الخصائص المنطقية */ .card { padding-inline: 16px; /* يمين + يسار */ padding-block: 12px; /* أعلى + أسفل */ border-start-start-radius: 12px; /* أعلى اليسار في LTR */ }
100vh على متصفحات الجوال تشمل واجهة متصفح Chrome، مما يسبب تجاوزاً عند ظهور الشريط. وحدة dvh (ارتفاع إطار العرض الديناميكي) الجديدة تتكيف عند ظهور أو إخفاء واجهة المتصفح.
/* ❌ يتجاوز على الجوال عند ظهور واجهة المتصفح */ .hero { height: 100vh; } /* ✅ مع خيار احتياطي للمتصفحات القديمة */ .hero { height: 100vh; /* احتياطي */ height: 100dvh; /* ارتفاع إطار العرض الديناميكي */ }
svh (إطار عرض صغير، يستبعد دائماً واجهة المتصفح) و lvh (إطار عرض كبير، يشمل دائماً مساحة واجهة المتصفح).المزيد من أداة فحص تجاوب المواقع
ضع هذه النصائح قيد التنفيذ
اختبر كيف تبدو تغييراتك المتجاوبة عبر الجوال والتابلت وسطح المكتب — فوراً، مجاناً، بدون تسجيل.
اختبر موقعك الآن