เจาะลึกลงไปในแบบสอบถามสไตล์คอนเทนเนอร์

โหนดต้นทาง: 1765194

ฉันเขียนขึ้นบางส่วน ความคิดเบื้องต้นเกี่ยวกับข้อความค้นหาสไตล์คอนเทนเนอร์ สักครู่กลับ ยังคงเป็นวันแรก ถูกกำหนดไว้แล้วใน ข้อกำหนด CSS Containment Module ระดับ 1 (ขณะนี้อยู่ในสถานะร่างบรรณาธิการ) แต่ยังคงมีการอภิปรายที่ค้างคาอยู่สองสามเรื่อง

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

@container ?  {
  /* conditional styles */
}

ตัวอย่างที่ดีที่สุดที่ฉันเคยเห็นมาคือการลบตัวเอียงออกจากสิ่งที่ต้องการ , และ เมื่อใช้ในบริบทที่เนื้อหาเป็นตัวเอียงแล้ว:

em, i, q {
  font-style: italic; /* default UA behavior */
}

/* When the container's font-style is italic, remove italics from these elements. */
@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

นั่นคือแนวคิดทั่วไป แต่ถ้าคุณยังไม่รู้ Miriam Suzanne ซึ่งเป็นบรรณาธิการของสเป็ค บันทึกส่วนตัวเกี่ยวกับแบบสอบถามสไตล์คอนเทนเนอร์ ที่เปิดเผยต่อสาธารณะ มีการอัปเดตเมื่อวันก่อน และฉันใช้เวลาอยู่ที่นั่นเพื่อพยายามสรุปแง่มุมต่างๆ ที่เหมาะสมยิ่งขึ้นของข้อความค้นหาสไตล์ เป็นเรื่องที่ไม่เป็นทางการ แต่ฉันคิดว่าฉันจะจดบางอย่างที่โดดเด่นสำหรับฉัน ใครจะรู้? บางทีมันอาจเป็นสิ่งที่เราสามารถคาดหวังได้ในที่สุด!

ทุกองค์ประกอบคือคอนเทนเนอร์สไตล์

เราไม่จำเป็นต้องกำหนด a อย่างชัดเจนด้วยซ้ำ container-name or container-type เพื่อกำหนดสไตล์คอนเทนเนอร์เพราะทุกอย่างเป็นคอนเทนเนอร์สไตล์ตามค่าเริ่มต้น

คุณเห็นตัวอย่างข้างต้นที่ลบตัวเอียงหรือไม่ สังเกตว่าไม่ได้ระบุคอนเทนเนอร์ มันข้ามไปยังแบบสอบถามโดยใช้ style() การทำงาน. คอนเทนเนอร์ใดที่ถูกสอบถาม มันจะเป็น ผู้ปกครองโดยตรงขององค์ประกอบ ได้รับรูปแบบที่นำไปใช้ และถ้าไม่เป็นเช่นนั้นก็คือ คอนเทนเนอร์สัมพัทธ์ที่ใกล้ที่สุดถัดไป ที่ให้ความสำคัญ

ฉันชอบมัน. เป็น CSS-y มากสำหรับข้อความค้นหาเพื่อค้นหาข้อมูลที่ตรงกัน จากนั้นขยายต่อไปจนกว่าจะพบเงื่อนไขที่ตรงกัน

มันยากสำหรับสมองอันน้อยนิดของฉันที่จะเข้าใจว่าทำไมเราถึงสามารถหลีกหนีจากคอนเทนเนอร์โดยนัยตามสไตล์ แต่ไม่มากนักเมื่อเราจัดการกับข้อความค้นหาเชิงมิติ เช่น size และ inline-size. มิเรียมอธิบายไว้อย่างดี:

แบบสอบถามมิติต้องการ css บรรจุ เกี่ยวกับขนาด รูปแบบ และรูปแบบของคอนเทนเนอร์ เพื่อป้องกันการวนซ้ำของรูปแบบ การกักกันเป็นสิ่งที่รุกรานที่จะนำไปใช้ในวงกว้าง ดังนั้นจึงเป็นเรื่องสำคัญที่ผู้เขียนจะต้องควบคุมอย่างระมัดระวังว่าองค์ประกอบใดบ้างที่เป็น (หรือไม่) ขนาดคอนเทนเนอร์

ข้อความค้นหาตามสไตล์ไม่มีข้อจำกัดเช่นเดียวกัน ไม่มีทางใน CSS อยู่แล้วที่รูปแบบที่สืบทอดมาจะมีผลกระทบต่อรูปแบบที่คำนวณของบรรพบุรุษ ดังนั้นจึงไม่จำเป็นต้องมีการกักกัน และไม่มีผลข้างเคียงที่รุกรานหรือคาดไม่ถึงในการสร้างองค์ประกอบเป็น คอนเทนเนอร์แบบสอบถามสไตล์.

(เน้นของฉัน)

ทั้งหมดนี้เป็นผลที่ตามมา ซึ่งไม่มีอะไรมากเท่ากับทุกอย่างที่เป็นคอนเทนเนอร์คิวรีสไตล์ทันทีที่แกะกล่อง

  • หากพบคอนเทนเนอร์: เงื่อนไขจะแก้ไขกับคอนเทนเนอร์นั้น
  • หากคอนเทนเนอร์หลายรายการตรงกัน: คอนเทนเนอร์สัมพัทธ์ที่ใกล้ที่สุดจะมีความสำคัญเหนือกว่า
  • หากไม่พบรายการที่ตรงกัน: unknown กลับ

นั่นเหมือนกัน วิญญาณ "ให้อภัย" เป็นส่วนที่เหลือของ CSS.

คอนเทนเนอร์สามารถรองรับทั้งเคียวรีมิติและสไตล์

สมมติว่าเราต้องการกำหนดสไตล์คิวรีโดยไม่ต้องระบุอย่างชัดเจน container-name:

@container style(font-style: italic) {
  em {
    font-style: normal;
  }
}

มันได้ผลเพราะ องค์ประกอบทั้งหมดเป็นคอนเทนเนอร์สไตล์ไม่ว่า container-type. นั่นคือสิ่งที่ทำให้เราสามารถค้นหาสไตล์โดยปริยายและใช้การจับคู่ที่ใกล้เคียงที่สุด และนี่เป็นเรื่องปกติเนื่องจากไม่มีผลข้างเคียงที่ไม่พึงประสงค์เมื่อสร้างคอนเทนเนอร์สไตล์

เราต้องใช้ความชัดเจน container-type สำหรับการสืบค้นแบบมิติ แต่ไม่มากสำหรับการสืบค้นแบบเนื่องจากทุกองค์ประกอบเป็นแบบสอบถามแบบ นั่นก็หมายความว่าคอนเทนเนอร์นี้เป็นทั้งสไตล์ และ แบบสอบถามมิติ:

.card-container {
  container: card / inline-size; /* implictly a style query container as well */
}

ไม่รวมคอนเทนเนอร์จากการสอบถาม

บางทีเราไม่ต้องการให้คอนเทนเนอร์เข้าร่วมในกระบวนการจับคู่ ที่นั่นสามารถตั้งค่าได้ container-type: none บนองค์ประกอบ

.some-element {
  container-type: none;
}

คอนเทนเนอร์การสืบค้นข้อมูลแบบชัดเจนให้การควบคุมสิ่งที่ได้รับการสืบค้นมากขึ้น

ถ้าสมมติว่าเราต้องเขียนแบบสอบถามสไตล์สำหรับ padding ไม่มีวิธีที่เชื่อถือได้ในการระบุคอนเทนเนอร์ที่ตรงกันที่สุด โดยไม่คำนึงว่าเรากำลังทำงานกับคอนเทนเนอร์ที่มีชื่ออย่างชัดเจนหรือพาเรนต์โดยตรงที่ใกล้ที่สุด นั่นเป็นเพราะ padding ไม่ใช่ทรัพย์สินตกทอด

ดังนั้น ในกรณีเหล่านั้น เราควรใช้ container-name เพื่อแจ้งให้เบราว์เซอร์ทราบอย่างชัดเจนว่าสามารถดึงคอนเทนเนอร์ใดได้บ้าง เรายังสามารถตั้งชื่อที่ชัดเจนหลายชื่อให้กับคอนเทนเนอร์เพื่อให้ตรงกับเงื่อนไขมากขึ้น:

.card {
  container-name: card layout theme;
}

Oh, และ container-name ยอมรับจำนวนตัวเลือกและ นำมาใช้ใหม่ ชื่อคอนเทนเนอร์! นั่นยิ่งมีความยืดหยุ่นมากขึ้นในการช่วยให้เบราว์เซอร์เลือกเมื่อค้นหาคู่ที่ตรงกัน

.theme {
  container-name: theme;
}
.grid {
  container-name: layout;
}
.card {
  container-name: card layout theme;
}

ฉันสงสัยว่านั่นอาจถือเป็น "ทางเลือกสำรอง" หรือไม่ในกรณีที่มีการส่งต่อคอนเทนเนอร์หนึ่งรายการ

แบบสอบถามสไตล์สามารถรวมกันได้

พื้นที่ or และ and ตัวดำเนินการช่วยให้เรารวม wueries เพื่อให้สิ่งต่าง ๆ แห้ง:

@container bubble style(--arrow-position: start start) or style(--arrow-position: end start) {
  .bubble::after {
    border-block-end-color: inherit;
    inset-block-end: 100%;
  }
}

/* is the same as... */
@container bubble style(--arrow-position: start start) {
  /* etc. */
}
@container bubble style(--arrow-position: end start) {
  /* etc. */
}

รูปแบบการสลับ

มีการทับซ้อนกันเล็กน้อยระหว่างข้อความค้นหาสไตล์คอนเทนเนอร์และ งานที่ทำเพื่อกำหนด a toggle() ฟังก์ชัน. ตัวอย่างเช่น เราสามารถหมุนเวียนสองรอบ font-style ค่าพูด italic และ normal:

em, i, q {
  font-style: italic;
}

@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

เย็น. แต่ข้อเสนอสำหรับ CSS Toggles ชี้ให้เห็นว่า toggle() ฟังก์ชันจะเป็นแนวทางที่ง่ายกว่า:

em, i, q {
  font-style: toggle(italic, normal);
}

แต่สิ่งที่นอกเหนือจากกรณีการใช้งานแบบไบนารีประเภทนี้คือที่ไหน toggle() มีความเหมาะสมน้อยกว่า แบบสอบถามสไตล์เป็นสิ่งที่ดีที่จะไป Miriam ระบุสามกรณีที่ข้อความค้นหาสไตล์เหมาะสมกว่า a toggle():

/* When font-style is italic, apply background color. */
/* Toggles can only handle one property at a time. */
@container style(font-style: italic) {
  em, i, q {
    background: lightpink;
  }
}

/* When font-style is italic and --color-mode equals light */
/* Toggles can only evaluate one condition at a time */
@container style((font-style: italic) and (--color-mode: light)) {
  em, i, q {
    background: lightpink;
  }
}

/* Apply the same query condition to multiple properties */
/* Toggles have to set each one individually as separate toggles */
@container style(font-style: italic) {
  em, i, q {
    /* clipped gradient text */
    background: var(--feature-gradient);
    background-clip: text;
    box-decoration-break: clone;
    color: transparent;
    text-shadow: none;
  }
}

แบบสอบถามสไตล์ช่วยแก้ปัญหา "แฮ็กสลับคุณสมบัติที่กำหนดเอง"

โปรดสังเกตว่าการสอบถามสไตล์เป็นวิธีแก้ปัญหาที่เป็นทางการสำหรับ “เคล็ดลับการสลับคุณสมบัติที่กำหนดเองของ CSS”. ในนั้น เราตั้งค่าคุณสมบัติแบบกำหนดเองที่ว่างเปล่า (--foo: ;) และใช้วิธีการสำรองที่คั่นด้วยเครื่องหมายจุลภาคเพื่อเปิดและปิดคุณสมบัติ "สลับ" เมื่อคุณสมบัติแบบกำหนดเองถูกตั้งค่าเป็นค่าจริง

button {
  --is-raised: ; /* off by default */
  
  border: 1px solid var(--is-raised, rgb(0 0 0 / 0.1));
  box-shadow: var(
    --is-raised,
    0 1px hsl(0 0% 100% / 0.8) inset,
    0 0.1em 0.1em -0.1em rgb(0 0 0 / 0.2)
  );
  text-shadow: var(--is-raised, 0 -1px 1px rgb(0 0 0 / 0.3));
}

button:active {
  box-shadow: var(--is-raised, 0 1px 0.2em black inset);
}

#foo {
  --is-raised: initial; /* turned on, all fallbacks take effect. */
}

มันเจ๋งมาก และยังมีงานอีกมากมายที่การสืบค้นสไตล์คอนเทนเนอร์ทำให้เป็นเรื่องเล็กน้อย

ข้อความค้นหาสไตล์และเนื้อหาที่สร้างโดย CSS

สำหรับเนื้อหาที่สร้างโดย content คุณสมบัติของ ::before และ ::after องค์ประกอบหลอก คอนเทนเนอร์ที่ตรงกันคือองค์ประกอบที่สร้างเนื้อหา

.bubble {
  --arrow-position: end end;
  container: bubble;
  border: medium solid green;
  position: relative;
}

.bubble::after {
  content: "";
  border: 1em solid transparent;
  position: absolute;
}

@container bubble style(--arrow-position: end end) {
  .bubble::after {
    border-block-start-color: inherit;
    inset-block-start: 100%;
    inset-inline-end: 1em;
  }
}

แบบสอบถามสไตล์และส่วนประกอบของเว็บ

เราสามารถกำหนดองค์ประกอบเว็บเป็นคอนเทนเนอร์และสอบถามตามสไตล์ ประการแรกเรามี ของส่วนประกอบ:


  
… …

จากนั้นเราก็ใช้ :host หลอกองค์ประกอบเป็นภาชนะที่จะตั้ง container-nameที่ container-typeและแอตทริบิวต์ระดับสูงบางอย่างในนั้น:

:host {
  container: media-host / inline-size;
  --media-location: before;
  --media-style: square;
  --theme: light;
}

องค์ประกอบภายใน สามารถสอบถามพารามิเตอร์ของ ธาตุ:

@container media-host style(--media-style: round) {
  [part='img'] {
    border-radius: 100%;
  }
}

ทำอะไรต่อไป

ขอย้ำอีกครั้งว่าทุกสิ่งที่ฉันจดไว้ที่นี่อ้างอิงจากบันทึกของมิเรียม และบันทึกเหล่านั้นไม่สามารถใช้แทนข้อมูลจำเพาะที่เป็นทางการได้ แต่เป็นตัวบ่งชี้ถึงสิ่งที่กำลังพูดถึงและสิ่งที่จะเกิดขึ้นในอนาคต ฉันขอขอบคุณมิเรียมที่เชื่อมโยงการอภิปรายที่โดดเด่นจำนวนหนึ่งซึ่งยังคงเกิดขึ้นซึ่งเราสามารถติดตามเพื่อติดตามสิ่งต่างๆ ได้:

ประทับเวลา:

เพิ่มเติมจาก เคล็ดลับ CSS