ชุดค่าผสมของตัวเลือกและ @-rule

ปัญหา

เรามักจะต้องรวมเกณฑ์การกรองประเภทต่างๆ เช่น ตัวเลือก + Media Query, Media Query + Container Query เป็นต้น

เช่น การรวม (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;
  }
}

สิ่งที่ควรทำแทน

จัดเก็บผลลัพธ์ของตัวกรองแบบรวมในคุณสมบัติที่กำหนดเอง จากนั้นใช้การค้นหาสไตล์คอนเทนเนอร์เพื่อตั้งกฎตามคุณสมบัตินั้น

สำคัญ: เนื่องจากวิธีการทำงานของคำค้นหาคอนเทนเนอร์ เทคนิคนี้จะใช้ได้ก็ต่อเมื่อเราตั้งค่าคุณสมบัติที่กำหนดเองในระดับบนสุดของกฎที่ต้องตรงกันเท่านั้น

1. แยกตรรกะการเลือกออกจากกฎที่ใช้

: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;
  }
}

2. คีย์ในคุณสมบัติที่กำหนดเองสำหรับกฎที่ใช้

@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;
  }
}

3. ไม่บังคับ: คลาสยูทิลิตีสำหรับการสลับระดับการมองเห็น

กรณีที่พบบ่อยมากคือการสลับระดับการเข้าถึงตามเกณฑ์ที่ตรงกันหรือไม่ คลาสยูทิลิตีต้องมีความสำคัญเหนือกว่ารูปแบบคอมโพเนนต์ที่กำหนดเอง (จึงใช้ !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;
  }
}

สำรอง

ซึ่งมี 2 ประเภท ขึ้นอยู่กับความสำคัญของการแยกสาขาและสิ่งที่เป็นทางเลือกสำรองที่ยอมรับได้

  1. สำหรับการแยกสาขาที่สำคัญ ซึ่งทุกสถานะต้องทำงานอย่างถูกต้องแม้ว่าจะไม่รองรับการค้นหาสไตล์ คุณก็ไม่สามารถใช้การค้นหาสไตล์ได้ แต่ให้ใช้วิธีการแบบง่ายด้านบน โดยทำซ้ำกฎสำหรับแต่ละรัฐ คุณยังคงใช้คลาสยูทิลิตีได้ ตราบใดที่มีการกำหนดคลาสเหล่านั้นในลักษณะเดียวกัน
  2. สำหรับการแยกสาขาที่ไม่สำคัญซึ่งยอมรับสถานะเริ่มต้นได้ คุณสามารถกำหนดสไตล์พื้นฐานนอกกฎ @container และใช้การค้นหาสไตล์เป็นการลบล้างเท่านั้น วิธีนี้ยังคงรักษาแนวคิดส่วนใหญ่ของแนวทางนี้ไว้ โดยข้อเสียหลักคือการเชื่อมโยงค่าที่การลบล้างทำให้เกิดขึ้น
#logo-dark {
  display: none;
}

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

  #logo {
    display: none;
  }
}