CSS3 والتصميم المتجاوب

استعلامات الوسائط: الصياغة ونقاط التوقف والميزات

30 دقيقة الدرس 33 من 60

ما هي استعلامات الوسائط؟

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

تم تقديم هذا المفهوم في CSS3 ومنذ ذلك الحين تطور عبر مواصفات Media Queries Level 4 و Level 5، مضيفًا ميزات جديدة قوية مثل اكتشاف تفضيلات المستخدم وصياغة النطاقات. فهم استعلامات الوسائط بشكل شامل أمر ضروري لأي مطور يبني مواقع ويب حديثة ومتجاوبة.

صياغة قاعدة @media

تُكتب استعلامات الوسائط باستخدام قاعدة @media. تتكون من نوع وسائط اختياري، وصفر أو أكثر من ميزات الوسائط المحاطة بأقواس، وقواعد CSS التي يجب تطبيقها عند استيفاء الشروط. إليك البنية الأساسية:

مثال: البنية الأساسية لاستعلام الوسائط

@media media-type and (media-feature: value) {
    /* قواعد CSS تُطبق عند تحقق الشروط */
}

/* مثال حقيقي: تطبيق الأنماط فقط على الشاشات الأضيق من 768px */
@media screen and (max-width: 768px) {
    .sidebar {
        display: none;
    }
    .main-content {
        width: 100%;
    }
}

تبدأ الكلمة المفتاحية @media الاستعلام. نوع الوسائط (مثل screen) اختياري وقيمته الافتراضية all. الشرط بين الأقواس هو ميزة الوسائط التي يتم اختبارها. الأقواس المعقوفة تحتوي على قواعد CSS التي تُطبق عندما يكون الشرط صحيحًا. يمكنك وضع أي CSS صالح داخل كتلة استعلام الوسائط، بما في ذلك المحددات والخصائص والرسوم المتحركة وحتى القواعد المتداخلة.

أنواع الوسائط: all و screen و print و speech

تصف أنواع الوسائط الفئة العامة للجهاز. يحدد CSS أربعة أنواع وسائط، رغم أنك ستستخدم اثنين منها بشكل أساسي في الممارسة:

  • all -- يطابق كل جهاز. هذا هو الافتراضي عند عدم تحديد نوع. إذا كتبت @media (max-width: 768px) بدون تحديد نوع، فهذا يعني ضمنيًا @media all and (max-width: 768px).
  • screen -- يطابق الأجهزة ذات الشاشات: أجهزة الكمبيوتر المكتبية والمحمولة والأجهزة اللوحية والهواتف وأي شاشة عرض مرئية. هذا هو النوع الأكثر تحديدًا شيوعًا.
  • print -- يطابق الطابعات ووضع معاينة الطباعة. استخدمه لإنشاء أوراق أنماط مناسبة للطباعة تزيل التنقل وتغير الألوان إلى الأبيض والأسود وتعدل التخطيط للورق.
  • speech -- يطابق قارئات الشاشة ومركبات الكلام. نادرًا ما يُستخدم هذا النوع في الممارسة لأن إمكانية الوصول عادةً تُعالج من خلال دلالات HTML وسمات ARIA بدلاً من CSS.

مثال: استخدام أنواع وسائط مختلفة

/* يُطبق على جميع الأجهزة (افتراضي) */
@media (max-width: 600px) {
    body { font-size: 14px; }
}

/* يُطبق فقط على الشاشات */
@media screen and (max-width: 600px) {
    .mobile-menu { display: block; }
}

/* يُطبق فقط عند الطباعة */
@media print {
    nav, footer, .sidebar { display: none; }
    body { font-size: 12pt; color: #000; }
    a { text-decoration: underline; }
    a[href]::after { content: " (" attr(href) ")"; }
}

/* يُطبق على مركبات الكلام */
@media speech {
    .decorative { display: none; }
}
ملاحظة: تم إيقاف أنواع الوسائط القديمة مثل tv و handheld و projection و tty. يتعرف CSS الحديث فقط على all و screen و print و speech. إذا رأيت هذه الأنواع المهملة في كود قديم، يمكن استبدالها بأمان بـ screen أو إزالتها.

ميزات الوسائط: العرض والارتفاع والاتجاه والمزيد

ميزات الوسائط هي الشروط التي تختبرها داخل الأقواس. تصف خصائص محددة لوكيل المستخدم أو جهاز الإخراج أو البيئة. إليك أهمها:

ميزات العرض والارتفاع

هذه هي ميزات الوسائط الأكثر استخدامًا. تختبر عرض وارتفاع منفذ العرض (المنطقة المرئية من نافذة المتصفح):

مثال: ميزات وسائط العرض والارتفاع

/* عرض محدد (نادر الاستخدام) */
@media (width: 768px) {
    /* يطابق فقط عندما يكون منفذ العرض 768px بالضبط */
}

/* الحد الأقصى للعرض: يُطبق عند هذا العرض وأقل */
@media (max-width: 768px) {
    .container { padding: 0 15px; }
}

/* الحد الأدنى للعرض: يُطبق عند هذا العرض وأكثر */
@media (min-width: 768px) {
    .container { max-width: 720px; margin: 0 auto; }
}

/* استعلامات قائمة على الارتفاع (أقل شيوعًا لكنها مفيدة) */
@media (max-height: 500px) {
    .hero { min-height: auto; padding: 20px 0; }
}

/* دمج min و max لنطاق */
@media (min-width: 768px) and (max-width: 1024px) {
    /* يستهدف الأجهزة اللوحية تحديدًا */
    .grid { grid-template-columns: repeat(2, 1fr); }
}

الاتجاه

ميزة orientation تكشف ما إذا كان منفذ العرض أعرض مما هو طويل (أفقي) أو أطول مما هو عريض (عمودي):

مثال: ميزة وسائط الاتجاه

@media (orientation: portrait) {
    .gallery { grid-template-columns: 1fr; }
}

@media (orientation: landscape) {
    .gallery { grid-template-columns: repeat(3, 1fr); }
}

/* الدمج مع العرض لاستهداف أكثر تحديدًا */
@media (orientation: landscape) and (max-height: 500px) {
    /* الهواتف الأفقية: تقليل ارتفاع الرأس */
    .header { height: 50px; }
}

نسبة العرض إلى الارتفاع

ميزة aspect-ratio تختبر نسبة عرض منفذ العرض إلى ارتفاعه. هذا مفيد لاستهداف الشاشات فائقة العرض أو أشكال أجهزة محددة:

مثال: ميزة وسائط نسبة العرض إلى الارتفاع

/* الشاشات فائقة العرض (21:9 أو أعرض) */
@media (min-aspect-ratio: 21/9) {
    .content { max-width: 1400px; margin: 0 auto; }
}

/* منافذ عرض مربعة تقريبًا */
@media (aspect-ratio: 1/1) {
    .layout { grid-template-columns: 1fr; }
}

/* شاشات طويلة وضيقة (هواتف عمودية) */
@media (max-aspect-ratio: 3/4) {
    .sidebar { position: fixed; bottom: 0; width: 100%; }
}

العوامل المنطقية: and و or (الفاصلة) و not و only

تتيح لك العوامل المنطقية دمج أو نفي ميزات الوسائط لإنشاء شروط معقدة. إتقان هذه العوامل هو المفتاح لكتابة استعلامات وسائط دقيقة وفعالة.

العامل "and"

العامل and يجمع عدة شروط يجب أن تكون جميعها صحيحة لتطبيق الأنماط:

مثال: العامل "and"

/* يجب أن يكون كلا الشرطين صحيحًا */
@media screen and (min-width: 768px) and (max-width: 1024px) {
    /* يُطبق فقط على الشاشات بين 768px و 1024px */
    .tablet-layout { display: grid; grid-template-columns: 1fr 1fr; }
}

/* ثلاثة شروط مجتمعة */
@media screen and (min-width: 1024px) and (orientation: landscape) and (min-height: 600px) {
    .desktop-sidebar { display: block; width: 250px; }
}

عامل الفاصلة (أو)

الفاصلة بين استعلامات الوسائط تعمل كعامل OR منطقي. إذا تطابق أي من الاستعلامات المفصولة بفاصلة، تُطبق الأنماط. في Media Queries Level 4، يمكنك أيضًا استخدام الكلمة المفتاحية or الصريحة داخل استعلام واحد:

مثال: عامل الفاصلة (OR)

/* أي من الشرطين يُفعّل الأنماط */
@media (max-width: 600px), (orientation: portrait) {
    .flexible-layout { flex-direction: column; }
}

/* الطباعة أو الشاشات الضيقة */
@media print, (max-width: 768px) {
    .sidebar { display: none; }
}

/* نقاط توقف متعددة تتشارك نفس الأنماط */
@media (max-width: 480px), (min-width: 768px) and (max-width: 1024px) {
    .special-layout { padding: 10px; }
}

العامل "not"

الكلمة المفتاحية not تنفي استعلام وسائط كاملاً. تعكس النتيجة بحيث تُطبق الأنماط عندما يكون الشرط خاطئًا. مهم: not تُطبق على الاستعلام بأكمله وليس على ميزة واحدة فقط:

مثال: العامل "not"

/* يُطبق على كل شيء ما عدا الشاشات */
@media not screen {
    body { font-family: serif; }
}

/* يُطبق عندما لا يكون منفذ العرض ضيقًا */
@media not all and (max-width: 600px) {
    .desktop-only { display: block; }
}

/* مع الفاصلة: "not" تُطبق فقط على استعلامها */
@media not screen and (color), print {
    /* "not" تنفي "screen and (color)" فقط */
    /* "print" هو استعلام منفصل غير منفي */
}

الكلمة المفتاحية "only"

صُممت الكلمة المفتاحية only لمنع المتصفحات القديمة (IE8 وما قبله) من تطبيق أنماط لا تستطيع تفسيرها بشكل صحيح. تتعامل معها المتصفحات الحديثة بشفافية. قد تراها في كود قديم لكنها ليست ضرورية في المشاريع الجديدة:

مثال: الكلمة المفتاحية "only"

/* استخدام قديم -- يمنع المتصفحات القديمة من سوء قراءة الاستعلام */
@media only screen and (min-width: 768px) {
    .container { max-width: 720px; }
}

/* في التطوير الحديث، هذا مكافئ */
@media screen and (min-width: 768px) {
    .container { max-width: 720px; }
}

صياغة النطاقات الحديثة (Media Queries Level 4)

قدم Media Queries Level 4 صياغة نطاقات أكثر سهولة باستخدام عوامل المقارنة الرياضية. بدلاً من كتابة min-width و max-width، يمكنك استخدام عوامل >= و <= و > و <. هذه الصياغة مدعومة الآن في جميع المتصفحات الرئيسية.

مثال: صياغة النطاقات الحديثة

/* الصياغة القديمة */
@media (min-width: 768px) { /* ... */ }
@media (max-width: 1024px) { /* ... */ }
@media (min-width: 768px) and (max-width: 1024px) { /* ... */ }

/* صياغة النطاقات الجديدة -- نفس المعنى، أكثر قابلية للقراءة */
@media (width >= 768px) { /* ... */ }
@media (width <= 1024px) { /* ... */ }
@media (768px <= width <= 1024px) { /* ... */ }

/* المزيد من الأمثلة */
@media (height > 600px) {
    .tall-hero { min-height: 80vh; }
}

@media (400px <= width <= 800px) {
    .mid-range { padding: 20px; }
}

/* يعمل مع ميزات أخرى أيضًا */
@media (aspect-ratio >= 16/9) {
    .cinematic { /* أنماط فائقة العرض */ }
}
نصيحة احترافية: صياغة النطاقات (768px <= width <= 1024px) أوضح بكثير من الصياغة القديمة (min-width: 768px) and (max-width: 1024px). تُقرأ بشكل طبيعي كـ "العرض بين 768px و 1024px." اعتمد هذه الصياغة للمشاريع الجديدة، لكن كن على دراية بأن قواعد الكود القديمة قد لا تزال تستخدم أسلوب البادئة min/max.

قيم نقاط التوقف الشائعة واصطلاحات التسمية

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

مثال: أنظمة نقاط التوقف الشائعة

/* نقاط توقف Bootstrap 5 */
/* xs: 0 - 575px (لا حاجة لاستعلام وسائط، الافتراضي للجوال أولاً) */
/* sm: 576px وما فوق */
/* md: 768px وما فوق */
/* lg: 992px وما فوق */
/* xl: 1200px وما فوق */
/* xxl: 1400px وما فوق */

/* نقاط توقف Tailwind CSS */
/* sm: 640px */
/* md: 768px */
/* lg: 1024px */
/* xl: 1280px */
/* 2xl: 1536px */

/* نظام مخصص عملي باستخدام خصائص CSS المخصصة */
:root {
    --bp-phone: 480px;
    --bp-tablet: 768px;
    --bp-desktop: 1024px;
    --bp-wide: 1280px;
    --bp-ultrawide: 1536px;
}

/* ملاحظة: لا يمكن استخدام خصائص CSS المخصصة داخل
   شروط استعلامات الوسائط. القيم أعلاه لأغراض التوثيق.
   استخدم قيم البكسل الفعلية في قواعد @media. */

@media (min-width: 480px)  { /* هاتف أفقي */ }
@media (min-width: 768px)  { /* جهاز لوحي */ }
@media (min-width: 1024px) { /* سطح المكتب */ }
@media (min-width: 1280px) { /* سطح مكتب عريض */ }
@media (min-width: 1536px) { /* فائق العرض */ }
مهم: لا تحدد نقاط التوقف بناءً على أجهزة محددة (مثلاً 375px لـ iPhone X). تتغير الأجهزة باستمرار ويجب أن يتكيف تصميمك بسلاسة. بدلاً من ذلك، حدد نقاط التوقف حيث يحتاج تصميمك بشكل طبيعي إلى التغيير. قم بتغيير حجم متصفحك ببطء وأضف نقطة توقف أينما بدأ التخطيط يبدو مكسورًا أو غريبًا.

الجوال أولاً مقابل سطح المكتب أولاً

هناك نهجان أساسيان لكتابة استعلامات الوسائط، والاختيار بينهما يؤثر على بنية CSS بالكامل.

الجوال أولاً (min-width)

في تطوير الجوال أولاً، تكتب CSS الأساسي للشاشات الأصغر ثم تستخدم استعلامات min-width لإضافة أنماط تدريجيًا للشاشات الأكبر. هذا هو النهج الموصى به لمعظم المشاريع:

مثال: نهج الجوال أولاً

/* الأنماط الأساسية: الجوال (لا حاجة لاستعلام وسائط) */
.container {
    width: 100%;
    padding: 0 16px;
}

.grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
}

.sidebar {
    display: none;
}

/* الجهاز اللوحي وما فوق */
@media (min-width: 768px) {
    .container {
        max-width: 720px;
        margin: 0 auto;
        padding: 0 24px;
    }

    .grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 24px;
    }
}

/* سطح المكتب وما فوق */
@media (min-width: 1024px) {
    .container {
        max-width: 960px;
    }

    .grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 32px;
    }

    .sidebar {
        display: block;
        width: 250px;
    }
}

سطح المكتب أولاً (max-width)

في تطوير سطح المكتب أولاً، يستهدف CSS الأساسي الشاشات الكبيرة وتستخدم استعلامات max-width لتجاوز الأنماط للشاشات الأصغر. قد يكون هذا النهج منطقيًا عند إعادة تصميم موقع سطح مكتب حالي ليكون متجاوبًا:

مثال: نهج سطح المكتب أولاً

/* الأنماط الأساسية: سطح المكتب */
.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 32px;
}

.grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 32px;
}

.sidebar {
    display: block;
    width: 300px;
}

/* الجهاز اللوحي وما دون */
@media (max-width: 1024px) {
    .grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 24px;
    }

    .sidebar {
        width: 200px;
    }
}

/* الهاتف وما دون */
@media (max-width: 768px) {
    .container {
        padding: 0 16px;
    }

    .grid {
        grid-template-columns: 1fr;
        gap: 16px;
    }

    .sidebar {
        display: none;
    }
}
نصيحة احترافية: يُفضل نهج الجوال أولاً لأن اتصالات الجوال غالبًا ما تكون أبطأ، لذا فإن إرسال CSS أقل في البداية يحسن الأداء. كما يجبرك على إعطاء الأولوية للمحتوى والتصميم لأكثر البيئات تقييدًا أولاً. ثم تعزز الشاشات الأكبر التجربة تدريجيًا بدلاً من تجريد الميزات.

دمج عدة شروط

غالبًا ما يتطلب التصميم المتجاوب في العالم الحقيقي دمج عدة ميزات وسائط لاستهداف سيناريوهات محددة بدقة. إليك أنماطًا ستواجهها كثيرًا:

مثال: دمج عدة شروط

/* جهاز لوحي في الوضع الأفقي */
@media (min-width: 768px) and (max-width: 1024px) and (orientation: landscape) {
    .video-player { height: 60vh; }
}

/* شاشات كبيرة ليست طويلة جدًا (شاشات فائقة العرض) */
@media (min-width: 1400px) and (max-height: 800px) {
    .content { max-width: 1200px; }
    .sidebar { position: sticky; top: 0; }
}

/* إما شاشات صغيرة جدًا أو طباعة */
@media (max-width: 480px), print {
    .complex-table {
        display: block;
    }
    .complex-table thead {
        display: none;
    }
    .complex-table td {
        display: block;
        text-align: right;
    }
    .complex-table td::before {
        content: attr(data-label);
        float: left;
        font-weight: bold;
    }
}

أوراق أنماط الطباعة مع @media print

تتيح لك استعلامات وسائط الطباعة تحسين صفحتك لمخرجات الورق. عندما يطبع مستخدم صفحتك أو يستخدم معاينة الطباعة، تسري هذه الأنماط. ورقة أنماط الطباعة الجيدة تزيل عناصر واجهة المستخدم غير الضرورية وتعدل الألوان لسهولة القراءة على الورق وتضمن أن المحتوى يناسب الصفحة المطبوعة بشكل صحيح.

مثال: ورقة أنماط طباعة شاملة

@media print {
    /* إعادة تعيين الألوان للطباعة */
    * {
        color: #000 !important;
        background: #fff !important;
        box-shadow: none !important;
        text-shadow: none !important;
    }

    /* إزالة العناصر غير الأساسية */
    nav, .sidebar, .footer-social, .cookie-banner,
    .back-to-top, .chat-widget, .ads {
        display: none !important;
    }

    /* ضمان تدفق المحتوى بشكل صحيح */
    body {
        font-size: 12pt;
        line-height: 1.5;
        font-family: Georgia, "Times New Roman", serif;
    }

    /* عرض عناوين URL الكاملة للروابط */
    a[href]::after {
        content: " (" attr(href) ")";
        font-size: 10pt;
        color: #666 !important;
    }

    /* عدم عرض URL للروابط الداخلية أو JavaScript */
    a[href^="#"]::after,
    a[href^="javascript"]::after {
        content: "";
    }

    /* التحكم في فواصل الصفحات */
    h1, h2, h3 {
        page-break-after: avoid;
    }

    img, table, figure {
        page-break-inside: avoid;
    }

    /* ضمان أن الصور تناسب الصفحة */
    img {
        max-width: 100% !important;
        height: auto !important;
    }

    /* تعيين هوامش الصفحة */
    @page {
        margin: 2cm;
    }

    @page :first {
        margin-top: 3cm;
    }
}

prefers-reduced-motion لإمكانية الوصول

ميزة الوسائط prefers-reduced-motion تكشف ما إذا كان المستخدم قد طلب من النظام تقليل الحركة غير الأساسية. هذه ميزة وصول حاسمة للمستخدمين الذين يعانون من اضطرابات الدهليز أو حساسية الحركة أو الذين يجدون الرسوم المتحركة مشتتة ببساطة. توفر أنظمة التشغيل هذا الإعداد (مثل "تقليل الحركة" على macOS/iOS و "إظهار الرسوم المتحركة" على Windows).

مثال: احترام تفضيلات تقليل الحركة

/* الافتراضي: تضمين الرسوم المتحركة */
.hero-element {
    animation: fadeInUp 0.8s ease-out;
}

.card {
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
    transform: translateY(-5px);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
}

/* إزالة أو تقليل الرسوم المتحركة للمستخدمين الذين يفضلون ذلك */
@media (prefers-reduced-motion: reduce) {
    .hero-element {
        animation: none;
    }

    .card {
        transition: none;
    }

    .card:hover {
        transform: none;
    }

    /* استبدال الحركة بتغييرات حالة فورية */
    * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* بديل: إضافة الحركة فقط للمستخدمين الموافقين عليها */
/* هذا النهج "الحركة أولاً" أصبح مفضلاً: */
.element {
    /* لا رسوم متحركة افتراضيًا */
    opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
    .element {
        animation: fadeIn 0.5s ease-out;
    }
}
تحذير إمكانية الوصول: لا تتجاهل أبدًا prefers-reduced-motion. الرسوم المتحركة المفرطة يمكن أن تسبب الدوار والغثيان والصداع للمستخدمين الذين يعانون من اضطرابات الدهليز. على الأقل، قم بتغليف جميع الرسوم المتحركة والانتقالات غير الأساسية داخل فحص prefers-reduced-motion: no-preference. الرسوم المتحركة الأساسية (مثل مؤشر التحميل) يمكن أن تبقى لكن يجب تبسيطها.

prefers-color-scheme للوضع الداكن

ميزة الوسائط prefers-color-scheme تكشف ما إذا كان المستخدم يفضل سمة ألوان فاتحة أو داكنة. يتيح لك هذا مطابقة مظهر موقعك تلقائيًا مع تفضيلات نظام المستخدم. تقبل قيمتين: light و dark.

مثال: تنفيذ الوضع الداكن مع prefers-color-scheme

/* تعريف نظام الألوان بخصائص CSS المخصصة */
:root {
    /* السمة الفاتحة (افتراضي) */
    --bg-primary: #ffffff;
    --bg-secondary: #f5f5f5;
    --text-primary: #1a1a1a;
    --text-secondary: #666666;
    --border-color: #e0e0e0;
    --accent: #2563eb;
    --accent-hover: #1d4ed8;
    --shadow: rgba(0, 0, 0, 0.1);
}

@media (prefers-color-scheme: dark) {
    :root {
        /* السمة الداكنة */
        --bg-primary: #1a1a2e;
        --bg-secondary: #16213e;
        --text-primary: #e0e0e0;
        --text-secondary: #a0a0a0;
        --border-color: #2d2d44;
        --accent: #60a5fa;
        --accent-hover: #93c5fd;
        --shadow: rgba(0, 0, 0, 0.4);
    }
}

/* استخدام الخصائص المخصصة في جميع أنحاء CSS */
body {
    background-color: var(--bg-primary);
    color: var(--text-primary);
}

.card {
    background-color: var(--bg-secondary);
    border: 1px solid var(--border-color);
    box-shadow: 0 2px 8px var(--shadow);
}

a {
    color: var(--accent);
}

a:hover {
    color: var(--accent-hover);
}

/* التعامل مع الصور التي قد تبدو سيئة في الوضع الداكن */
@media (prefers-color-scheme: dark) {
    img:not([src*=".svg"]) {
        filter: brightness(0.9);
    }
}

ميزات وسائط hover و pointer

تتيح لك ميزات الوسائط hover و pointer اكتشاف آلية إدخال المستخدم. هذا ضروري للتمييز بين تجارب سطح المكتب المعتمدة على الفأرة وتجارب الجوال المعتمدة على اللمس، بغض النظر عن حجم الشاشة. قد يكون لدى المستخدم على جهاز لوحي كبير منفذ عرض واسع لكن بدون قدرة التحويم.

مثال: اكتشاف آلية الإدخال

/* hover: هل يمكن للإدخال الأساسي التحويم؟ */
/* "hover" = نعم (فأرة)، "none" = لا (لمس) */

/* pointer: ما مدى دقة الإدخال الأساسي؟ */
/* "fine" = فأرة/لوحة لمس، "coarse" = إصبع/قلم، "none" = لا مؤشر */

/* عرض تأثيرات التحويم فقط للأجهزة التي تدعمها */
@media (hover: hover) {
    .nav-link:hover {
        background-color: var(--bg-secondary);
        transform: translateY(-2px);
    }

    .tooltip-trigger:hover .tooltip {
        opacity: 1;
        visibility: visible;
    }
}

/* لأجهزة اللمس، جعل أهداف النقر أكبر */
@media (pointer: coarse) {
    .button {
        min-height: 48px;
        min-width: 48px;
        padding: 12px 24px;
    }

    .nav-link {
        padding: 16px 20px;
    }

    /* إزالة واجهة المستخدم المعتمدة على التحويم التي لن تعمل باللمس */
    .hover-dropdown {
        display: none;
    }
}

/* مؤشر دقيق: يمكن استخدام تخطيطات أصغر وأكثر إحكامًا */
@media (pointer: fine) {
    .compact-table td {
        padding: 4px 8px;
    }

    .button-sm {
        min-height: 32px;
        padding: 4px 12px;
    }
}

/* any-hover و any-pointer تتحقق من جميع أجهزة الإدخال */
/* مفيد للأجهزة الهجينة مثل الحواسيب المحمولة ذات الشاشات اللمسية */
@media (any-hover: hover) {
    /* إدخال واحد على الأقل يمكنه التحويم */
}

@media (any-pointer: fine) {
    /* إدخال واحد على الأقل لديه دقة عالية */
}
نصيحة احترافية: لا تعتمد فقط على عرض الشاشة لتحديد اللمس مقابل الفأرة. المستخدم على Surface Pro لديه شاشة واسعة لكنه يستخدم إدخال اللمس. ميزات الوسائط hover و pointer تعطيك صورة أكثر دقة بكثير لقدرات إدخال المستخدم.

تنظيم استعلامات الوسائط: الاستراتيجيات

كيفية تنظيم استعلامات الوسائط في قاعدة الكود لها تأثير كبير على قابلية الصيانة. هناك استراتيجيتان رئيسيتان، ومعظم المشاريع المهنية تستخدم مزيجًا من الاثنتين.

الاستراتيجية 1: استعلامات الوسائط على مستوى المكونات

ضع استعلامات الوسائط بجانب المكون الذي تؤثر عليه مباشرة. هذا يحافظ على جميع أنماط المكون معًا ويسهل العثور على القواعد المتجاوبة:

مثال: استعلامات الوسائط على مستوى المكونات

/* ========= مكون الرأس ========= */
.header {
    padding: 10px 16px;
    display: flex;
    align-items: center;
}

.header__logo {
    width: 120px;
}

.header__nav {
    display: none; /* مخفي على الجوال */
}

.header__menu-btn {
    display: block;
}

@media (min-width: 768px) {
    .header {
        padding: 16px 32px;
    }

    .header__logo {
        width: 160px;
    }

    .header__nav {
        display: flex;
        gap: 24px;
    }

    .header__menu-btn {
        display: none;
    }
}

/* ========= مكون البطاقة ========= */
.card {
    padding: 16px;
    border-radius: 8px;
}

@media (min-width: 768px) {
    .card {
        padding: 24px;
        border-radius: 12px;
    }
}

الاستراتيجية 2: ملفات نقاط توقف منفصلة

اجمع جميع استعلامات الوسائط لنقطة توقف محددة في ملف مخصص. هذا يعطيك نظرة عامة واضحة على كل ما يتغير عند كل نقطة توقف:

مثال: بنية ملفات نقاط التوقف المنفصلة

/* ملف: styles/base.css -- أنماط الجوال أولاً الأساسية */
/* ملف: styles/tablet.css -- @media (min-width: 768px) */
/* ملف: styles/desktop.css -- @media (min-width: 1024px) */

/* في ورقة الأنماط الرئيسية أو HTML: */
/* <link rel="stylesheet" href="styles/base.css"> */
/* <link rel="stylesheet" href="styles/tablet.css" media="(min-width: 768px)"> */
/* <link rel="stylesheet" href="styles/desktop.css" media="(min-width: 1024px)"> */

/* ملاحظة: يقوم المتصفح بتنزيل جميع أوراق الأنماط بغض النظر عن
   سمة media، لكنه يطبق فقط المطابقة منها ولن
   يحجب العرض لأوراق الأنماط غير المطابقة. */
ملاحظة: تفضل معظم المشاريع الحديثة استعلامات الوسائط على مستوى المكونات لأنها أسهل في الصيانة عند العمل مع بنيات قائمة على المكونات (CSS Modules أو منهجية BEM أو أطر العمل القائمة على الأدوات). نهج الملفات المنفصلة يعمل بشكل أفضل للمشاريع الأصغر ذات البنية الأبسط.

مثال عملي متجاوب مع نقاط توقف متعددة

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

مثال: تخطيط متجاوب كامل

/* ===== إعادة تعيين CSS والأنماط الأساسية (الجوال أولاً) ===== */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

:root {
    --color-bg: #f8f9fa;
    --color-surface: #ffffff;
    --color-text: #212529;
    --color-primary: #0d6efd;
    --radius: 8px;
    --shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

body {
    font-family: system-ui, -apple-system, sans-serif;
    background: var(--color-bg);
    color: var(--color-text);
    line-height: 1.6;
}

/* ===== تخطيط الجوال (الافتراضي) ===== */
.page-header {
    background: var(--color-surface);
    padding: 12px 16px;
    box-shadow: var(--shadow);
    position: sticky;
    top: 0;
    z-index: 100;
}

.nav-list {
    display: none; /* مخفي على الجوال، يتم تبديله عبر JS */
    list-style: none;
}

.mobile-menu-toggle {
    display: block;
    background: none;
    border: none;
    font-size: 1.5rem;
    cursor: pointer;
}

.page-layout {
    padding: 16px;
}

.main-content {
    margin-bottom: 24px;
}

.card-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
}

.sidebar {
    background: var(--color-surface);
    padding: 16px;
    border-radius: var(--radius);
}

/* ===== الجهاز اللوحي: 768px وما فوق ===== */
@media (min-width: 768px) {
    .page-header {
        padding: 16px 32px;
        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .nav-list {
        display: flex;
        gap: 24px;
    }

    .mobile-menu-toggle {
        display: none;
    }

    .page-layout {
        padding: 24px 32px;
    }

    .card-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 24px;
    }
}

/* ===== سطح المكتب: 1024px وما فوق ===== */
@media (min-width: 1024px) {
    .page-layout {
        display: grid;
        grid-template-columns: 1fr 300px;
        gap: 32px;
        max-width: 1200px;
        margin: 0 auto;
        padding: 32px;
    }

    .card-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .sidebar {
        position: sticky;
        top: 80px;
        align-self: start;
    }
}

/* ===== سطح مكتب عريض: 1280px وما فوق ===== */
@media (min-width: 1280px) {
    .card-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .page-layout {
        max-width: 1400px;
        grid-template-columns: 1fr 350px;
    }
}

/* ===== الوضع الداكن ===== */
@media (prefers-color-scheme: dark) {
    :root {
        --color-bg: #121212;
        --color-surface: #1e1e1e;
        --color-text: #e0e0e0;
        --color-primary: #60a5fa;
        --shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    }
}

/* ===== الطباعة ===== */
@media print {
    .page-header, .sidebar, .mobile-menu-toggle {
        display: none;
    }

    .page-layout {
        display: block;
        padding: 0;
    }

    .card-grid {
        display: block;
    }
}

/* ===== إمكانية الوصول ===== */
@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* ===== تحسين اللمس ===== */
@media (pointer: coarse) {
    .nav-list a {
        padding: 12px 16px;
        min-height: 48px;
        display: flex;
        align-items: center;
    }

    button, .button {
        min-height: 48px;
        min-width: 48px;
    }
}

تمرين عملي

ابنِ صفحة عرض منتجات متجاوبة تستخدم نهج الجوال أولاً. ابدأ بتخطيط عمود واحد للهواتف. عند 640px، انتقل إلى شبكة من عمودين. عند 1024px، أضف شريطًا جانبيًا مع خيارات التصفية واعرض ثلاثة أعمدة منتجات. عند 1280px، اعرض أربعة أعمدة منتجات. أضف ورقة أنماط طباعة تزيل الشريط الجانبي وتعرض المنتجات في قائمة نظيفة. أضف دعم prefers-color-scheme: dark مع ألوان خلفية داكنة ونص فاتح مناسبة. استخدم prefers-reduced-motion: reduce لتعطيل أي رسوم متحركة عند التحويم. أخيرًا، استخدم استعلام pointer: coarse لزيادة حجم خانات اختيار التصفية والأزرار لأجهزة اللمس. اختبر تصميمك بتغيير حجم المتصفح في كل مرحلة للتأكد من عدم وجود حالات وسيطة غريبة ينكسر فيها التخطيط.