ترکیب‌های انتخابگر و @-rule

ویژگی‌های وب: پرس‌وجوهای سبک محفظه

مشکل

اغلب لازم است معیارهای فیلتر کردن انواع مختلف را ترکیب کنیم، مثلاً انتخابگرها + پُرسمان‌های رسانه، پُرسمان‌های رسانه + پُرسمان‌های محفظه، و غیره.

برای مثال، ترکیب کردن (prefers-color-scheme: dark) با گزینشگری که لغو آرایش رنگ‌ها را هدف قرار می‌دهد (مثلاً :root:has(> head > meta[name="color-scheme"][content="dark"]) یا :root.dark) برای اعمال سبک‌های خاص در حالت روشن/تیره، صرف‌نظر از اینکه آرایش رنگ‌ها چگونه تنظیم شده است.

رویکرد ساده منجر به کد تکراری می‌شود:

/* Light mode styles */
.card.featured {
  font-weight: 400;
}

#logo-dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  /* Dark mode styles */
  :root:not(.light) {
    .card.featured {
      font-weight: 300;
    }

    #logo-dark {
      display: inline;
    }

    #logo {
      display: none;
    }
  }
}

/* Dark mode styles, again */
:root.dark {
  .card.featured {
    font-weight: 300;
  }

  #logo-dark {
    display: inline;
  }

  #logo {
    display: none;
  }
}

به‌جای آن چه کاری باید انجام داد

نتیجه فیلتر ترکیبی را در یک ویژگی سفارشی ذخیره کنید، سپس از پرسمان‌های سبک محتوا برای تنظیم قوانین براساس آن ویژگی استفاده کنید.

مهم: به‌دلیل نحوه عملکرد پرسمان‌های محفظه، این تکنیک فقط درصورتی کار می‌کند که بتوانیم ویژگی سفارشی را روی جد هر قانونی که باید مطابقت داده شود تنظیم کنیم.

۱. جدا کردن منطق انتخاب از قوانین اعمال‌شده

:root {
  --color-scheme: light;

  @media (prefers-color-scheme: dark) {
    --color-scheme: dark;
  }

  &:has(> head > meta[name="color-scheme"][content="dark"]) {
    --color-scheme: dark;
  }

  &:has(> head > meta[name="color-scheme"][content="light"]) {
    --color-scheme: light;
  }
}

۲. کلید در دارایی سفارشی برای قوانین اعمال‌شده

@container not style(--color-scheme: dark) {
  .card.featured {
    font-weight: 400;
  }

  #logo-dark {
    display: none;
  }
}

@container style(--color-scheme: dark) {
  .card.featured {
    font-weight: 300;
  }

  #logo {
    display: none;
  }
}

۳. اختیاری: کلاس‌های کاربردی برای تغییر وضعیت رؤیت‌پذیری

یک مورد بسیار رایج، تغییر وضعیت رؤیت‌پذیری براساس مطابقت یا عدم مطابقت معیارها است. کلاس‌های سودمند باید بر سبک‌های مؤلفه دلخواه (ازاین‌رو !important) غلبه کنند و display نشان‌داده‌شده آن‌ها ناشناخته است، بنابراین نمی‌توانند از لغو استفاده کنند — آن‌ها را با not style(...) محدود کنید:

@container not style(--color-scheme: dark) {
  .if-dark {
    display: none !important;
  }
}

@container not style(--color-scheme: light) {
  .if-light {
    display: none !important;
  }
}

گزینه‌های جایگزین

دو نوع جایگزین وجود دارد که به میزان اهمیت انشعاب و آنچه جایگزین قابل‌قبول را تشکیل می‌دهد بستگی دارد.

  1. برای انشعاب‌های حیاتی، که در آن‌ها همه حالت‌ها باید به‌درستی کار کنند حتی اگر پرسمان‌های سبک پشتیبانی نشوند، به‌سادگی نمی‌توانید از پرسمان‌های سبک استفاده کنید. به‌جای آن، از رویکرد ساده بالا استفاده کنید و قوانین را برای هر ایالت تکرار کنید. کلاس‌های کاربردی همچنان می‌توانند استفاده شوند، به شرطی که به همان روش تعریف شده باشند.
  2. برای انشعاب غیربحرانی، که در آن حالت پیش‌فرض قابل‌قبول است، می‌توانید سبک‌های پایه را خارج از هر قانون @container تعریف کنید و فقط از پرسمان‌های سبک به‌عنوان لغو استفاده کنید. این کار بیشتر روح این رویکرد را حفظ می‌کند، اما عیب اصلی آن جفت شدن مقادیری است که لغو کردن معرفی می‌کند.
#logo-dark {
  display: none;
}

@container style(--color-scheme: dark) {
  #logo-dark {
    display: inline; /* override */
  }

  #logo {
    display: none;
  }
}