دليل كامل حول كيفية عمل Responsive web Design أفضل

تم التحديث: ٢٧ مارس ٢٠٢٦

How to Make a Better Responsive web Design Full Guide

ملخص

تُحدث استعلامات الحاوية (Container Queries) ثورة في التصميم المتجاوب — حيث تتكيف المكونات مع حجم الحاوية الخاصة بها، وليس مع نافذة العرض (viewport). ادمجها مع CSS Subgrid للتخطيطات المعقدة، والصور المتجاوبة باستخدام picture و AVIF، واختبر التصميم عبر الأجهزة القابلة للطي والشاشات الكبيرة. استخدم Chrome DevTools وأطر عمل الاختبار المتجاوب لضمان الاتساق في كل مكان.

كان التصميم المتجاوب يعني سابقًا ثلاث نقاط توقف (breakpoints): الهاتف المحمول، الجهاز اللوحي، والكمبيوتر المكتبي. أصبح هذا الآن جزءًا من الماضي البعيد.

في عام 2026، أنت تصمم لأكثر من 100 حجم جهاز مختلف. هواتف ذكية بشاشات 6-7 بوصة. أجهزة قابلة للطي تفتح لتصل إلى حجم الجهاز اللوحي. أجهزة كمبيوتر مكتبية بشاشات 5K. ساعات. نظارات واقع معزز (AR). يجب أن تعمل التطبيقات بلا عيوب عبر مجموعة واسعة من السياقات، وقد يكون نفس المكون بعرض 300 بكسل في شريط جانبي أو 1000 بكسل في الواجهة الرئيسية.

لقد غيرت استعلامات الحاوية (Container Queries) كل شيء. بدلاً من السؤال "ما هو عرض نافذة العرض؟" أنت تسأل "ما هو عرض الحاوية الخاصة بي؟" يغطي هذا الدليل أدوات التصميم المتجاوب الحديثة: Container Queries، و CSS Subgrid، والصور المتجاوبة، وكيفية الاختبار عبر التنوع الحقيقي للأجهزة التي يمتلكها المستخدمون.

استعلامات الحاوية: مغير قواعد اللعبة

تسمح استعلامات الحاوية (Container Queries) للمكونات بالتكيف بناءً على حجمها هي، وليس نافذة العرض. هذا هو أهم تقدم في التصميم المتجاوب منذ ظهور استعلامات الوسائط (media queries).

الصيغة الأساسية

/* Define a container context */
.card-container {
  container-type: inline-size; /* Watch the width of this element */
  container-name: card; /* Optional: name it for specificity */
}

/* Query the container size */
@container (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}

@container (max-width: 300px) {
  .card {
    display: block;
  }
}

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

لماذا هذا مهم

النهج القديم باستخدام استعلامات الوسائط (media queries):

/* You have to know the card sits in a sidebar on mobile, main on desktop */
@media (min-width: 768px) {
  .card { grid-template-columns: 1fr 1fr; }
}

النهج الجديد باستخدام استعلامات الحاوية (Container Queries):

/* The card doesn't care where it is—it adapts to its space */
@container (min-width: 400px) {
  .card { grid-template-columns: 1fr 1fr; }
}

هذا يعني أن نفس مكون Card يعمل في:

  • شريط جانبي بعرض 300 بكسل (عمود واحد)
  • نافذة منبثقة (modal) بعرض 600 بكسل (عمودان)
  • منطقة رئيسية بعرض 1200 بكسل (عمودان)
  • جزء أيسر من جهاز قابل للطي (عمود واحد)

دون الحاجة لكتابة نسخ متعددة أو استعلامات وسائط إضافية.

مثال عملي: بطاقة مدونة

// Component stays the same—CSS adapts it
export function BlogCard({ post }) {
  return (
    <article className="card">
      <img src={post.image} alt={post.title} className="card-image" />
      <h3>{post.title}</h3>
      <p>{post.excerpt}</p>
      <a href={post.url}>Read more</a>
    </article>
  );
}
.card-container {
  container-type: inline-size;
}

.card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.card-image {
  width: 100%;
  aspect-ratio: 16 / 9;
}

/* Narrow: stacked layout */
@container (max-width: 350px) {
  .card-image {
    height: 150px;
  }
}

/* Wide: side-by-side */
@container (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 250px 1fr;
  }

  .card-image {
    height: auto;
  }
}

/* Very wide: larger image */
@container (min-width: 700px) {
  .card {
    grid-template-columns: 350px 1fr;
  }
}

نفس المكون يعمل الآن بشكل مثالي في أي سياق.

CSS Subgrid لتخطيطات متجاوبة معقدة

تسمح Subgrid للشبكات الفرعية بوراثة مسارات الشبكة الأم. هذا يحل كوابيس المحاذاة.

المشكلة: بدون Subgrid

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

.card {
  display: grid;
  grid-template-rows: auto 1fr auto;
  /* These rows don't align across cards! */
}

كل بطاقة لها ارتفاعات صفوف مختلفة لأن محتواها يختلف. بدون Subgrid، تصبح محاذاة الأزرار في الأسفل مستحيلة.

الحل: مع Subgrid

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto 1fr auto; /* Define rows for all children */
  gap: 1rem;
}

.card {
  display: grid;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid; /* Inherit parent's rows */
}

الآن تتم محاذاة أزرار جميع البطاقات في الأسفل تلقائيًا.

مثال عملي: شبكة منتجات

export function ProductGrid({ products }) {
  return (
    <div className="product-grid">
      {products.map(product => (
        <article key={product.id} className="product-card">
          <img src={product.image} alt={product.name} />
          <h3>{product.name}</h3>
          <p className="description">{product.description}</p>
          <p className="price">{product.price}</p>
          <button>Add to Cart</button>
        </article>
      ))}
    </div>
  );
}
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  grid-template-rows: auto 1fr auto auto auto; /* Image, title, description, price, button */
  gap: 1rem;
}

.product-card {
  display: grid;
  grid-template-columns: subgrid; /* Inherit parent columns */
  grid-template-rows: subgrid; /* Inherit parent rows */
}

img {
  grid-column: 1;
  grid-row: 1;
}

h3 {
  grid-column: 1;
  grid-row: 2;
}

.description {
  grid-column: 1;
  grid-row: 3;
}

.price {
  grid-column: 1;
  grid-row: 4;
}

button {
  grid-column: 1;
  grid-row: 5;
}

تتم محاذاة جميع الأزرار بشكل مثالي، بغض النظر عن طول المحتوى.

الصور المتجاوبة

يجب أن تتكيف الصور مع نافذة العرض، والجهاز، وكثافة البكسل.

عنصر <picture>

تقديم صور مختلفة بناءً على حجم نافذة العرض:

<picture>
  <!-- Desktop: full-width image -->
  <source media="(min-width: 1200px)" srcset="hero-2000w.avif" />

  <!-- Tablet: medium image -->
  <source media="(min-width: 768px)" srcset="hero-1000w.avif" />

  <!-- Mobile: small image -->
  <source media="(max-width: 767px)" srcset="hero-500w.avif" />

  <!-- Fallback for older browsers -->
  <img src="hero-500w.jpg" alt="Hero section" />
</picture>

سمة srcset

دع المتصفح يختار أفضل دقة:

<img
  src="image-400w.avif"
  srcset="
    image-400w.avif 400w,
    image-800w.avif 800w,
    image-1200w.avif 1200w,
    image-2000w.avif 2000w
  "
  sizes="
    (max-width: 600px) 100vw,
    (max-width: 1200px) 90vw,
    1000px
  "
  alt="Product image"
/>

هذا يخبر المتصفح:

  • على الشاشات التي تصل إلى 600 بكسل، قم بتحميل صورة تمثل 100% من عرض نافذة العرض.
  • على الشاشات من 600 إلى 1200 بكسل، قم بتحميل 90% من عرض نافذة العرض.
  • للشاشات الأكبر، قم بتحميل صورة ثابتة بعرض 1000 بكسل.
  • استخدم دائمًا أصغر صورة تغطي هذا العرض.

يختار المتصفح من srcset (400w، 800w، إلخ) بناءً على حساباته.

تنسيق AVIF

AVIF هو أحدث تنسيق للصور. إنه أصغر بكثير من WebP أو JPEG:

<picture>
  <!-- Use AVIF for modern browsers -->
  <source srcset="image.avif" type="image/avif" />

  <!-- Fallback to WebP -->
  <source srcset="image.webp" type="image/webp" />

  <!-- Fallback to JPEG -->
  <img src="image.jpg" alt="Description" />
</picture>

التوفير المعتاد في الحجم:

  • JPEG: 100 كيلوبايت
  • WebP: 65 كيلوبايت
  • AVIF: 40 كيلوبايت

هذا يعني تقليل حجم الملف بنسبة 60% مع الحفاظ على نفس الجودة البصرية.

التصميم المتجاوب لأشكال الأجهزة الجديدة

الأجهزة القابلة للطي

تحتوي الأجهزة القابلة للطي على شاشتين يفصل بينهما مفصل. نافذة العرض تحتوي حرفيًا على فجوة.

/* Detect the fold line */
@media (fold-left: 0px) and (fold-right: 400px) {
  /* On left side of fold (0-400px) */
  .sidebar {
    width: 100%;
  }

  /* On right side (400px+) */
  body {
    margin-left: 400px;
  }
}

اختبر على Samsung Galaxy Z Fold أو Google Pixel Fold باستخدام محاكيات Android.

الشاشات الكبيرة (>1920 بكسل)

لا تمدد المحتوى إلى ما لا نهاية. استخدم عرضًا أقصى (max-width) وقم بتوسيطه:

body {
  max-width: 1400px;
  margin: 0 auto;
}

/* For ultra-wide screens, add whitespace */
@media (min-width: 2560px) {
  body {
    max-width: 1600px;
  }
}

الساعات والشاشات الصغيرة

تخطيط بعمود واحد، وأهداف لمس أكبر (44 بكسل كحد أدنى):

@container (max-width: 280px) {
  button {
    padding: 0.75rem 1rem; /* 44px+ height */
  }

  .card {
    display: block; /* No grid */
  }
}

اختبار التصميم المتجاوب

وضع الجهاز في Chrome DevTools

F12 ← تبديل شريط أدوات الجهاز (Ctrl+Shift+M). اختبر:

  • جميع نقاط التوقف (breakpoints)
  • تفاعلات اللمس
  • نسب بكسل الجهاز (Device pixel ratios)

أطر عمل الاختبار المتجاوب

تسمح لك منصات مثل BrowserStack و Sauce Labs و LambdaTest بالاختبار على أجهزة حقيقية.

التحقق من صحة CSS

# Check for responsive issues
npx stylelint "**/*.css"

اختبار A/B للتخطيطات المتجاوبة

استخدم ميزات التبديل (feature flags) لاختبار المتغيرات:

export function CardLayout({ post }) {
  const isNewLayout = useFeatureFlag('new-card-layout');

  return isNewLayout ? (
    <CardNewLayout post={post} />
  ) : (
    <CardOldLayout post={post} />
  );
}

قم بقياس معدل الارتداد، والتفاعل، والتحويل لكل متغير. البيانات هي ما يحرك القرارات، وليس التخمينات.

النقاط الرئيسية

التصميم المتجاوب في عام 2026:

  1. استعلامات الحاوية أولاً: صمم مكونات تتكيف مع سياقها، وليس مع نافذة العرض.
  2. Subgrid للمحاذاة: تخطيطات معقدة مع خطوط أساس متسقة.
  3. الصور المتجاوبة: AVIF + srcset لملفات أصغر وأداء أفضل.
  4. تبني أشكال الأجهزة الجديدة: الأجهزة القابلة للطي والشاشات الكبيرة هي حالات استخدام حقيقية.
  5. الاختبار المكثف: استخدم أجهزة حقيقية، وليس فقط جهاز الكمبيوتر المحمول الخاص بك.
  6. قياس التأثير: اختبر تغييرات التخطيط عبر A/B وكرر العملية بناءً على البيانات.

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


نشرة أسبوعية مجانية

ابقَ على مسار النيرد

بريد واحد أسبوعياً — دورات، مقالات معمّقة، أدوات، وتجارب ذكاء اصطناعي.

بدون إزعاج. إلغاء الاشتراك في أي وقت.