สถานะของ CSS 2022

ฟีเจอร์สไตล์เว็บของวันนี้และวันต่อๆ ไป ตามที่เห็นใน Google IO 2022 รวมถึงฟีเจอร์เสริมบางอย่าง

ปี 2022 จะเป็นปีที่ดีที่สุดปีหนึ่งของ CSS ทั้งในด้านฟีเจอร์และการเปิดตัวฟีเจอร์เบราว์เซอร์แบบร่วมมือกัน โดยมีเป้าหมายร่วมกันในการใช้งานฟีเจอร์ 14 รายการ

ภาพรวม

โพสต์นี้เป็นรูปแบบบทความของการเสวนาที่ให้ไว้ที่ Google IO 2022 เนื้อหานี้ไม่ได้มีไว้เพื่อเป็นคําแนะนําเชิงลึกเกี่ยวกับฟีเจอร์แต่ละรายการ แต่เป็นเพียงการแนะนําและภาพรวมโดยย่อเพื่อกระตุ้นความสนใจของคุณ โดยให้ข้อมูลแบบกว้างๆ แทนที่จะให้ข้อมูลแบบเจาะลึก หากสนใจ โปรดดูลิงก์แหล่งข้อมูลเพื่อดูข้อมูลเพิ่มเติมที่ส่วนท้ายของส่วน

สารบัญ

ใช้รายการด้านล่างเพื่อข้ามไปยังหัวข้อที่สนใจ

ความเข้ากันได้กับเบราว์เซอร์

เหตุผลหลักที่ฟีเจอร์ CSS จำนวนมากได้รับการตั้งค่าให้เปิดตัวร่วมกันคือความพยายามของ Interop 2022 ก่อนจะศึกษาเกี่ยวกับความพยายามในการทำงานร่วมกัน คุณควรดูความพยายามของ Compat 2021

Compat 2021

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

  1. sticky การวางตำแหน่ง
  2. aspect-ratio การปรับขนาด
  3. เลย์เอาต์ flex
  4. เลย์เอาต์ grid
  5. transform การจัดตำแหน่งและภาพเคลื่อนไหว

คะแนนการสอบเพิ่มขึ้นทั่วทั้งกระดาน ซึ่งแสดงให้เห็นว่ามีความเสถียรและความน่าเชื่อถือมากขึ้น ขอแสดงความยินดีอย่างยิ่งกับทีม

Interop 2022

ปีนี้ เบราว์เซอร์ต่างๆ ได้พบปะกันเพื่อพูดคุยเกี่ยวกับฟีเจอร์และลำดับความสำคัญที่ต้องการพัฒนาร่วมกัน โดยวางแผนที่จะให้บริการฟีเจอร์ต่อไปนี้บนเว็บสำหรับนักพัฒนาซอฟต์แวร์

  1. @layer
  2. พื้นที่สีและฟังก์ชัน
  3. การเก็บไว้
  4. <dialog>
  5. ความเข้ากันได้ของแบบฟอร์ม
  6. การเลื่อน
  7. ตารางย่อย
  8. การพิมพ์
  9. หน่วยวิวพอร์ต
  10. การทำงานร่วมกับเว็บ

นี่เป็นรายการที่น่าตื่นเต้นและทะเยอทะยานที่ฉันอดใจรอไม่ไหวที่จะเผยให้เห็น

ใหม่สำหรับปี 2022

ไม่น่าแปลกใจเลยที่สถานะของ CSS 2022 จะได้รับผลกระทบอย่างมากจากการทำงานด้านการทำงานร่วมกันในปี 2022

เรียงซ้อนเลเยอร์

การรองรับเบราว์เซอร์

  • Chrome: 99.
  • Edge: 99.
  • Firefox: 97
  • Safari: 15.4

แหล่งที่มา

ก่อน @layer ลำดับที่พบของสไตล์ชีตที่โหลดมีความสำคัญมากเนื่องจากสไตล์ที่โหลดล่าสุดจะเขียนทับสไตล์ที่โหลดไว้ก่อนหน้านี้ได้ ด้วยเหตุนี้ สไตล์ชีตรายการจึงได้รับการจัดการอย่างละเอียด ซึ่งนักพัฒนาซอฟต์แวร์ต้องโหลดสไตล์ที่ไม่สำคัญก่อน แล้วจึงโหลดสไตล์ที่สำคัญกว่าในภายหลัง มีวิธีการมากมายที่จะช่วยนักพัฒนาซอฟต์แวร์ในการจัดการความสำคัญนี้ เช่น ITCSS

เมื่อใช้ @layer ไฟล์รายการจะกำหนดเลเยอร์และลำดับของเลเยอร์ล่วงหน้าได้ จากนั้นเมื่อโหลดหรือกำหนดสไตล์ สไตล์จะวางไว้ในเลเยอร์ได้ ซึ่งช่วยให้คงความสำคัญของการลบล้างสไตล์ไว้ได้โดยไม่ต้องมีการจัดการการโหลดอย่างละเอียด

วิดีโอนี้แสดงให้เห็นว่าเลเยอร์ Cascade ที่กําหนดไว้ช่วยให้กระบวนการเขียนและโหลดแบบอิสระและยืดหยุ่นมากขึ้นได้อย่างไร ทั้งยังคง Cascade ไว้ตามที่ต้องการ

เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome มีประโยชน์ในการแสดงให้เห็นว่าสไตล์ใดมาจากเลเยอร์ใด

ภาพหน้าจอของแถบด้านข้างสไตล์ของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome ซึ่งไฮไลต์ลักษณะที่สไตล์ปรากฏภายในกลุ่มเลเยอร์ใหม่

แหล่งข้อมูล

ตารางกริดย่อย

การรองรับเบราว์เซอร์

  • Chrome: 117
  • Edge: 117
  • Firefox: 71.
  • Safari: 16.

แหล่งที่มา

ก่อนวันที่ subgrid ตารางกริดในตารางกริดอื่นจะจัดเรียงตัวเองให้ตรงกับเซลล์ระดับบนสุดหรือเส้นตารางกริดไม่ได้ เลย์เอาต์ตารางกริดแต่ละรายการจะแตกต่างกัน นักออกแบบหลายคนจัดวางตารางกริดเดียวสำหรับการออกแบบทั้งหมดและจัดรายการให้อยู่ในแนวเดียวกันอย่างสม่ำเสมอ ซึ่งทำใน CSS ไม่ได้

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

ในการสาธิตต่อไปนี้ องค์ประกอบเนื้อหาจะสร้างตารางกริดแบบคลาสสิกที่ประกอบด้วย 3 คอลัมน์ ได้แก่ คอลัมน์กลางชื่อว่า main และคอลัมน์ซ้ายและขวาตั้งชื่อเส้น fullbleed จากนั้น แต่ละองค์ประกอบในส่วนเนื้อหา <nav> และ <main> จะใช้บรรทัดที่มีชื่อจากเนื้อความโดยการตั้งค่า grid-template-columns: subgrid

​​body {
  display: grid;
  grid-template-columns:
    [fullbleed-start]
    auto [main-start] min(90%, 60ch) [main-end] auto
    [fullbleed-end]
  ;
}

body > * {
  display: grid;
  grid-template-columns: subgrid;
}

สุดท้าย ผู้เผยแพร่โฆษณาย่อยของ <nav> หรือ <main> สามารถปรับแนวหรือปรับขนาดตัวเองได้โดยใช้คอลัมน์และเส้น fullbleed และ main

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}

เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ช่วยให้คุณเห็นเส้นและตารางย่อยได้ (ขณะนี้ใช้ได้เฉพาะใน Firefox) ในรูปภาพต่อไปนี้ ตารางกริดหลักและตารางกริดย่อยวางซ้อนกัน ตอนนี้เลยมีลักษณะคล้ายกับวิธีที่นักออกแบบคิดเกี่ยวกับเลย์เอาต์

ภาพหน้าจอของการสาธิตตารางกริดย่อยซึ่งใช้เครื่องมือซ้อนทับแบบตารางกริดของ Chrome Devtools เพื่อแสดงเส้นที่กำหนดโดย CSS

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

ภาพหน้าจอของแผงองค์ประกอบ Chrome Devtools ซึ่งมีการติดป้ายกำกับว่าองค์ประกอบใดมีเลย์เอาต์แบบตารางกริดหรือตารางกริดย่อย
ภาพหน้าจอจากเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Firefox

แหล่งข้อมูล

การค้นหาคอนเทนเนอร์

การรองรับเบราว์เซอร์

  • Chrome: 105
  • Edge: 105
  • Firefox: 110
  • Safari: 16

แหล่งที่มา

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

หลังจากวันที่ @container องค์ประกอบจะตอบสนองต่อขนาดหรือสไตล์คอนเทนเนอร์ระดับบนสุดได้ ข้อควรระวังข้อเดียวคือคอนเทนเนอร์ต้องประกาศว่าตนเองเป็นเป้าหมายการค้นหาที่เป็นไปได้ ซึ่งเป็นข้อกำหนดเล็กๆ น้อยๆ เพื่อประโยชน์ที่ยิ่งใหญ่

/* establish a container */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}

รูปแบบเหล่านี้ทําให้คอลัมน์ จันทร์ อังคาร พุธ พฤหัสบดี และศุกร์ในวิดีโอต่อไปนี้สามารถค้นหาโดยองค์ประกอบเหตุการณ์ได้

การสาธิต โดย Una Kravets

ต่อไปนี้คือ CSS สำหรับการค้นหาขนาดของคอนเทนเนอร์ calendar-day จากนั้นจึงปรับเลย์เอาต์และขนาดแบบอักษร

@container calendar-day (max-width: 200px) {
  .date {
    display: block;
  }

  .date-num {
    font-size: 2.5rem;
    display: block;
  }
}

อีกตัวอย่างหนึ่งก็คือ คอมโพเนนต์หนังสือรายการหนึ่งจะปรับตัวเองให้เข้ากับพื้นที่ว่างในคอลัมน์ที่ลากไปไว้

Demo โดย Max Böck

Una ประเมินสถานการณ์ได้อย่างถูกต้องว่าตอบสนองได้ดี มีการตัดสินใจเกี่ยวกับการออกแบบที่น่าตื่นเต้นและมีความหมายมากมายเมื่อใช้ @container

แหล่งข้อมูล

accent-color

การรองรับเบราว์เซอร์

  • Chrome: 93
  • Edge: 93
  • Firefox: 92
  • Safari: 15.4

แหล่งที่มา

ก่อน accent-color เมื่อคุณต้องการแบบฟอร์มที่มีสีตรงกับแบรนด์ คุณอาจต้องใช้ไลบรารีที่ซับซ้อนหรือโซลูชัน CSS ที่จัดการได้ยากเมื่อเวลาผ่านไป แม้ว่าจะมีตัวเลือกทั้งหมดให้คุณและหวังว่าจะมีตัวเลือกการช่วยเหลือพิเศษด้วย แต่ตัวเลือกในการใช้คอมโพเนนต์ในตัวหรือใช้คอมโพเนนต์ของคุณเองก็ทำให้การเลือกต่อไปเป็นเรื่องน่าเบื่อ

หลังจาก accent-color จะมี CSS 1 บรรทัดที่นำสีของแบรนด์ไปใช้กับคอมโพเนนต์ในตัว นอกจากการปรับสีแล้ว เบราว์เซอร์จะเลือกสีที่ตัดกันอย่างชาญฉลาดสำหรับส่วนเสริมของคอมโพเนนต์และปรับให้เข้ากับรูปแบบสีของระบบ (สว่างหรือมืด)

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

องค์ประกอบ HTML ที่มีเครื่องหมายกำกับแบบสว่างและแบบเข้มแสดงคู่กันเพื่อเปรียบเทียบ

หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับ accent-color โปรดอ่านโพสต์ของฉันใน web.dev ซึ่งจะอธิบายแง่มุมต่างๆ เพิ่มเติมของพร็อพเพอร์ตี้ CSS ที่มีประโยชน์นี้

แหล่งข้อมูล

ระดับสี 4 และ 5

เว็บใช้ sRGB มาหลายทศวรรษแล้ว แต่ในโลกดิจิทัลที่ขยายตัวอย่างรวดเร็วของจอแสดงผลความละเอียดสูงและอุปกรณ์เคลื่อนที่ที่ติดตั้งหน้าจอ OLED หรือ QLED ไว้ล่วงหน้า sRGB นั้นไม่เพียงพอ นอกจากนี้ หน้าเว็บแบบไดนามิกที่ปรับตามความต้องการของผู้ใช้ก็เป็นสิ่งที่คาดหวังได้ และการจัดการสีก็เป็นสิ่งที่นักออกแบบ ระบบการออกแบบ และผู้ดูแลโค้ดให้ความสำคัญมากขึ้นเรื่อยๆ

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

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

หลังจากใช้ฟีเจอร์สีทั้งหมดแล้ว เบราว์เซอร์และ CSS จะทํางานทั้งหมดได้แบบไดนามิกและทันท่วงที แทนที่จะส่ง KB ของ CSS และ JavaScript จำนวนมากไปยังผู้ใช้เพื่อเปิดใช้การกำหนดธีมและสีของการแสดงข้อมูลผ่านภาพ CSS สามารถทำการจัดเป็นกลุ่มและการคำนวณได้ CSS ยังมีความพร้อมมากขึ้นในการตรวจสอบการสนับสนุนก่อนใช้งาน หรือจัดการกับวิดีโอสำรองอย่างมีชั้นเชิง

@media (dynamic-range: high) {
  .neon-pink {
    --neon-glow: color(display-p3 1 0 1);
  }
}

@supports (color: lab(0% 0 0)) {
  .neon-pink {
    --neon-glow: lab(150% 160 0);
  }
}

hwb()

การรองรับเบราว์เซอร์

  • Chrome: 101.
  • Edge: 101
  • Firefox: 96
  • Safari: 15.

แหล่งที่มา

HWB ย่อมาจาก Hue, Whiteness และ Blackness รูปแบบนี้นำเสนอตัวเองว่าเป็นวิธีสื่อสีที่เข้าใจง่าย เนื่องจากเป็นเพียงสีและปริมาณสีขาวหรือสีดําเพื่อปรับให้อ่อนหรือเข้ม ศิลปินที่ผสมสีกับสีขาวหรือสีดำอาจชื่นชอบการเพิ่มไวยากรณ์สีนี้

การใช้ฟังก์ชันสีนี้จะแสดงผลเป็นสีจากพื้นที่สี sRGB ซึ่งเหมือนกับ HSL และ RGB ในแง่ของความใหม่ของปี 2022 นี่ไม่ได้ให้สีใหม่ๆ แก่คุณ แต่อาจทำให้งานบางอย่างง่ายขึ้นสำหรับแฟนๆ ของรูปแบบไวยากรณ์และจิตใจ

แหล่งข้อมูล

พื้นที่สี

การแสดงสีจะใช้พื้นที่สี แต่ละพื้นที่สีมีฟีเจอร์และข้อเสียต่างๆ สำหรับการทำงานกับสี บางแบรนด์อาจจัดเรียงสีสดทั้งหมดไว้ด้วยกัน บางแบรนด์อาจจัดเรียงตามระดับความสว่างก่อน

CSS ปี 2022 มีกำหนดที่จะนำเสนอพื้นที่สีใหม่ 10 รายการ โดยแต่ละรายการจะมีฟีเจอร์เฉพาะตัวที่จะช่วยนักออกแบบและนักพัฒนาซอฟต์แวร์ในการแสดง เลือก และผสมสี ก่อนหน้านี้ sRGB เป็นตัวเลือกเดียวสำหรับการทำงานกับสี แต่ตอนนี้ CSS ได้ปลดล็อกศักยภาพใหม่ๆ และพื้นที่สีเริ่มต้นใหม่อย่าง LCH

color-mix()

การรองรับเบราว์เซอร์

  • Chrome: 111.
  • ขอบ: 111
  • Firefox: 113
  • Safari: 16.2

แหล่งที่มา

ก่อนวันที่ color-mix() นักพัฒนาซอฟต์แวร์และนักออกแบบต้องการเครื่องมือประมวลผลล่วงหน้าอย่าง Sass เพื่อผสมสีต่างๆ ก่อนที่เบราว์เซอร์จะเห็น ฟังก์ชันการผสมสีส่วนใหญ่ไม่มีตัวเลือกให้ระบุพื้นที่สีที่จะใช้ผสม ซึ่งบางครั้งอาจทำให้เกิดผลลัพธ์ที่ไม่น่าพอใจ

หลังจาก color-mix() นักพัฒนาซอฟต์แวร์และนักออกแบบจะผสมสีในเบราว์เซอร์ควบคู่ไปกับสไตล์อื่นๆ ทั้งหมดได้โดยไม่ต้องเรียกใช้กระบวนการบิลด์หรือรวม JavaScript นอกจากนี้ ผู้ใช้ยังระบุพื้นที่สีที่จะใช้ผสม หรือใช้พื้นที่สีผสมเริ่มต้นของ LCH ได้ด้วย

บ่อยครั้ง ระบบจะใช้สีของแบรนด์เป็นพื้นฐานและสร้างรูปแบบต่างๆ จากสีนั้น เช่น สีอ่อนหรือเข้มขึ้นสำหรับสไตล์โฮเวอร์ ตัวอย่างของการดำเนินการนี้เมื่อใช้ color-mix()มีดังนี้

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(var(--brand) 25%, black);
  --lighter: color-mix(var(--brand) 25%, white);
}

และหากต้องการผสมสีเหล่านั้นในพื้นที่สีอื่น เช่น sRGB ให้เปลี่ยนดังนี้

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}

ต่อไปนี้เป็นตัวอย่างการใช้ธีมโดยใช้ color-mix() ลองเปลี่ยนสีแบรนด์แล้วดูการอัปเดตธีม

สนุกกับการผสมสีในเชิงพื้นที่สีต่างๆ ในสไตล์ชีตในปี 2022

แหล่งข้อมูล

color-contrast()

การรองรับเบราว์เซอร์

  • Chrome: ไม่รองรับ
  • Edge: ไม่รองรับ
  • Firefox: ไม่รองรับ
  • Safari: อยู่หลังธง

แหล่งที่มา

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

ภาพหน้าจอของชุดสี Material 3 ชุด ซึ่งแสดงสี 14 สีและสีตัดกันสีขาวหรือสีดําที่เหมาะสมสําหรับข้อความ
ตัวอย่างจากชุดสี Material Design ปี 2014

หลังจาก color-contrast() ผู้เขียนสไตล์ชีตจะส่งงานทั้งหมดไปยังเบราว์เซอร์ได้ คุณไม่เพียงใช้เบราว์เซอร์เพื่อเลือกสีดําหรือสีขาวโดยอัตโนมัติเท่านั้น แต่ยังระบุรายการสีที่เหมาะสมกับระบบการออกแบบและเลือกสีแรกเพื่อให้ผ่านอัตราส่วนคอนทราสต์ที่ต้องการได้ด้วย

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

ภาพหน้าจอของตัวอย่าง HWB ที่แต่ละชุดสีมีการจับคู่ข้อความแบบสว่างหรือแบบเข้มที่แตกต่างกันตามที่กำหนดโดยเบราว์เซอร์
ลองใช้เดโม

รูปแบบไวยากรณ์พื้นฐานมีลักษณะดังนี้ โดยระบบจะส่งสีเทาไปยังฟังก์ชัน และเบราว์เซอร์จะระบุว่าสีดำหรือสีขาวมีความเปรียบต่างมากที่สุด

color: color-contrast(gray);

นอกจากนี้ คุณยังปรับแต่งฟังก์ชันนี้ด้วยรายการสีได้ โดยระบบจะเลือกสีที่ตัดกันมากที่สุดจากรายการต่อไปนี้

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);

สุดท้ายนี้ ในกรณีที่ไม่ต้องการเลือกสีที่มีคอนทราสต์สูงสุดจากรายการ คุณระบุอัตราส่วนคอนทราสต์เป้าหมายได้ และระบบจะเลือกสีแรกที่ผ่านเกณฑ์นี้

color: color-contrast(
  var(--bg-blue-1)
  vs
  var(--text-lightest), var(--text-light), var(--text-subdued)
  to AA /* 4.5 could also be passed */
);

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

แหล่งข้อมูล

ไวยากรณ์สีสัมพัทธ์

การรองรับเบราว์เซอร์

  • Chrome: 111.
  • Edge: 111
  • Firefox: 113
  • Safari: 15.

แหล่งที่มา

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

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

ในตัวอย่างไวยากรณ์ต่อไปนี้ มีการกำหนดฐาน 16 บิตและสร้างสีใหม่ 2 สีโดยอิงตามฐาน 16 บิตนั้น สีแรก --absolute-change สร้างสีใหม่ใน LCH จากสีฐาน จากนั้นแทนที่ความสว่างของสีฐานด้วย 75% โดยยังคงรักษาความเข้ม (c) และสี (h) ไว้ สีที่ 2 --relative-change สร้างสีใหม่ใน LCH จากสีฐาน แต่ครั้งนี้จะลดความเข้ม (c) ลง 20%

.relative-color-syntax {
  --color: #0af;
  --absolute-change: lch(from var(--color) 75% c h);
  --relative-change: lch(from var(--color) l calc(c-20%) h);
}

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

ในการสาธิตต่อไปนี้ ฉันใช้ไวยากรณ์สีสัมพัทธ์เพื่อสร้างรูปแบบสีอ่อนและเข้มขึ้นของสีฐาน และใช้ color-contrast() เพื่อให้แน่ใจว่าป้ายกำกับมีคอนทราสต์ที่เหมาะสม

ภาพหน้าจอที่มี 3 คอลัมน์ โดยแต่ละคอลัมน์มีสีเข้มหรืออ่อนกว่าคอลัมน์กลาง
ลองใช้เดโม

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

:root {
  --_color-base: #339af0;

  --color-0:  lch(from var(--_color-base) 98% 10 h);
  --color-1:  lch(from var(--_color-base) 93% 20 h);
  --color-2:  lch(from var(--_color-base) 85% 40 h);
  --color-3:  lch(from var(--_color-base) 75% 46 h);
  --color-4:  lch(from var(--_color-base) 66% 51 h);
  --color-5:  lch(from var(--_color-base) 61% 52 h);
  --color-6:  lch(from var(--_color-base) 55% 57 h);
  --color-7:  lch(from var(--_color-base) 49% 58 h);
  --color-8:  lch(from var(--_color-base) 43% 55 h);
  --color-9:  lch(from var(--_color-base) 39% 52 h);
  --color-10: lch(from var(--_color-base) 32% 48 h);
  --color-11: lch(from var(--_color-base) 25% 45 h);
  --color-12: lch(from var(--_color-base) 17% 40 h);
  --color-13: lch(from var(--_color-base) 10% 30 h);
  --color-14: lch(from var(--_color-base) 5% 20 h);
  --color-15: lch(from var(--_color-base) 1% 5 h);
}
ภาพหน้าจอของชุดสี 15 ชุดที่ CSS สร้างขึ้นแบบไดนามิก
ลองใช้เดโม

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

แหล่งข้อมูล

พื้นที่สีของไล่ระดับสี

ก่อนที่พื้นที่สีแบบไล่ระดับจะเข้ามา sRGB เป็นพื้นที่สีเริ่มต้นที่ใช้โดยทั่วไป sRGB เชื่อถือได้โดยทั่วไป แต่ก็มีจุดอ่อนบางอย่าง เช่น โซนสีเทา

การไล่ระดับสี 4 รายการในตารางกริด โดยไล่ระดับจากสีฟ้าซีดไปจนถึงสีชมพูเข้ม LCH และ LAB มีความสดสม่ำเสมอมากกว่า โดย sRGB จะสีจางลงเล็กน้อยตรงกลาง

หลังจากพื้นที่สีของไล่ระดับสีแล้ว ให้บอกเบราว์เซอร์ว่าจะใช้พื้นที่สีใดในการเติมสี ซึ่งช่วยให้นักพัฒนาแอปและนักออกแบบเลือกรูปแบบไล่ระดับสีที่ต้องการได้ นอกจากนี้ Color Space เริ่มต้นจะเปลี่ยนเป็น LCH แทน sRGB ด้วย

ไวยากรณ์เพิ่มเติมจะอยู่หลังทิศทางของไล่ระดับ ใช้ไวยากรณ์ in ใหม่ และเป็นแบบไม่บังคับ

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);

วิธีการไล่ระดับสีพื้นฐานและจำเป็นจากสีดำถึงขาวมีดังนี้ ดูช่วงของผลลัพธ์ในแต่ละพื้นที่สี บางภาพเป็นสีดำเข้มเร็วกว่าภาพอื่นๆ บางภาพซีดเป็นสีขาวช้าเกินไป

พื้นที่สี 11 ช่องที่แสดงการเปรียบเทียบสีดำกับสีขาว

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

พื้นที่สี 11 ช่องที่แสดงการเปรียบเทียบสีน้ำเงินกับสีดำ

หากต้องการดูการสํารวจเชิงลึก ตัวอย่าง และความคิดเห็นเพิ่มเติม โปรดอ่านชุดข้อความนี้ใน Twitter

แหล่งข้อมูล

inert

การรองรับเบราว์เซอร์

  • Chrome: 102.
  • Edge: 102
  • Firefox: 112
  • Safari: 15.5

แหล่งที่มา

ก่อน inert แนวทางปฏิบัติแนะนำคือการนำโฟกัสของผู้ใช้ไปยังส่วนต่างๆ ของหน้าเว็บหรือแอปที่ต้องดำเนินการทันที กลยุทธ์โฟกัสที่แนะนำนี้กลายเป็นที่รู้จักในชื่อ "การกักเก็บโฟกัส" เนื่องจากนักพัฒนาแอปจะวางโฟกัสในพื้นที่ทำงานแบบอินเทอร์แอกทีฟ คอยฟังเหตุการณ์การเปลี่ยนแปลงโฟกัส และหากโฟกัสออกจากพื้นที่ทำงานแบบอินเทอร์แอกทีฟ ระบบจะบังคับให้โฟกัสกลับเข้าไป ระบบจะนําผู้ใช้ที่ใช้แป้นพิมพ์หรือโปรแกรมอ่านหน้าจอกลับไปยังพื้นที่ทำงานแบบอินเทอร์แอกทีฟเพื่อให้แน่ใจว่างานเสร็จสมบูรณ์แล้วก่อนที่จะไปยังส่วนถัดไป

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

ตัวอย่างที่ดีของฟังก์ชันนี้คือฟังก์ชัน alert() ของ JavaScript

เว็บไซต์แสดงเป็นอินเทอร์แอกทีฟ จากนั้นมีการเรียกใช้ alert() และหน้าเว็บไม่ทำงานอีกต่อไป

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

ต่อไปนี้คือตัวอย่างโค้ดสั้นๆ ที่แสดงวิธีการทํางาน

<body>
  <div class="modal">
    <h2>Modal Title</h2>
    <p>...<p>
    <button>Save</button>
    <button>Discard</button>
  </div>
  <main inert>
    <!-- cannot be keyboard focused or clicked -->
  </main>
</body>

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

แหล่งข้อมูล

แบบอักษร COLRv1

ก่อนที่จะมีแบบอักษร COLRv1 เว็บมีแบบอักษร OT-SVG ซึ่งเป็นรูปแบบแบบเปิดสำหรับแบบอักษรที่มีไล่ระดับสี รวมถึงสีและเอฟเฟกต์ในตัว แต่ไฟล์เหล่านี้อาจมีขนาดใหญ่มาก และแม้ว่าจะอนุญาตให้แก้ไขข้อความได้ แต่ก็ปรับแต่งได้น้อยมาก

หลังจากแบบอักษร COLRv1 แล้ว เว็บจะมีแบบอักษรที่กินพื้นที่น้อยกว่า ปรับขนาดเป็นเวกเตอร์ได้ ปรับตำแหน่งได้ แสดงไล่ระดับสีได้ และทำงานในโหมดผสมได้ ซึ่งยอมรับพารามิเตอร์เพื่อปรับแต่งแบบอักษรตามกรณีการใช้งานหรือเพื่อให้เข้ากับแบรนด์

ภาพเปรียบเทียบและแผนภูมิแท่งแสดงว่าแบบอักษร COLRv1 คมชัดและเล็กกว่าอย่างไร
รูปภาพนี้มาจาก https://developer.chrome.com/blog/colrv1-fonts/

ต่อไปนี้คือตัวอย่างจากบล็อกโพสต์เกี่ยวกับอีโมจิของนักพัฒนาซอฟต์แวร์ Chrome คุณอาจจะสังเกตเห็นว่าหากคุณปรับขนาดตัวอักษรบนอีโมจิ อีโมจิจะไม่คมชัด เป็นรูปภาพ ไม่ใช่เวกเตอร์อาร์ต เมื่อใช้อีโมจิ บ่อยครั้งในแอปพลิเคชัน เราจะเปลี่ยนไปใช้เนื้อหาที่มีคุณภาพสูงกว่า เมื่อใช้แบบอักษร COLRv1 อีโมจิจะเป็นเวกเตอร์และสวยงาม

ฟอนต์ไอคอนสามารถทําสิ่งต่างๆ ที่น่าทึ่งได้โดยใช้รูปแบบนี้ ซึ่งจะเสนอพาเล็ตสีแบบ 2 โทนที่กำหนดเอง และอื่นๆ การโหลดแบบอักษร COLRv1 ก็เหมือนกับไฟล์แบบอักษรอื่นๆ ดังนี้

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

การปรับแต่งแบบอักษร COLRv1 ทำได้โดยใช้ @font-palette-values ซึ่งเป็นกฎ at ของ CSS พิเศษสำหรับการจัดกลุ่มและตั้งชื่อชุดตัวเลือกการปรับแต่งเป็นกลุ่มเพื่อใช้อ้างอิงภายหลัง โปรดสังเกตวิธีระบุชื่อที่กำหนดเองเช่นเดียวกับพร็อพเพอร์ตี้ที่กำหนดเอง โดยเริ่มต้นด้วย --

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

เมื่อใช้ --colorized เป็นชื่อแทนสำหรับการปรับแต่ง ขั้นตอนสุดท้ายคือการใช้จานสีกับองค์ประกอบที่ใช้ชุดแบบอักษรสี ดังนี้

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

.spicy {
  font-family: "Bungee Spice";
  font-palette: --colorized;
}
ภาพหน้าจอของแบบอักษร Bungee Spice ที่มีคำว่า DUNE
แบบอักษร Bungee Spice ที่แสดงด้วยสีที่กำหนดเอง แหล่งที่มาจาก https://developer.chrome.com/blog/colrv1-fonts/

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

แหล่งข้อมูล

หน่วยวิวพอร์ต

กราฟิกแสดงวิธีที่หน้าจออุปกรณ์ หน้าต่างเบราว์เซอร์ และ iframe โดยทั้งหมดมีวิวพอร์ตต่างกัน

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

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

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

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

กราฟิกที่มีโทรศัพท์ 3 เครื่องเพื่อช่วยอธิบาย DVH, LVH และ SVH โทรศัพท์ตัวอย่าง DVH มีเส้นแนวตั้ง 2 เส้น เส้นหนึ่งอยู่ตรงด้านล่างของแถบค้นหาและด้านล่างของวิวพอร์ต และอีกเส้นหนึ่งอยู่เหนือแถบค้นหา (ใต้แถบสถานะของระบบ) ไปจนถึงด้านล่างของวิวพอร์ต ซึ่งแสดงให้เห็นว่า DVH อาจมีความยาวใดความยาวหนึ่งก็ได้ LVH จะแสดงอยู่ตรงกลางโดยมี 1 เส้นอยู่ระหว่างด้านล่างของแถบสถานะของอุปกรณ์กับปุ่มของวิวพอร์ตโทรศัพท์ ตัวอย่างสุดท้ายคือตัวอย่างหน่วย SVH ซึ่งแสดงเส้นจากด้านล่างของแถบค้นหาของเบราว์เซอร์ไปจนถึงด้านล่างของวิวพอร์ต

ต่อไปนี้คือรายการตัวเลือกหน่วยวิวพอร์ตใหม่ทั้งหมดที่พร้อมใช้งานกับตัวแปรวิวพอร์ตใหม่

หน่วยความสูงของวิวพอร์ต
​​.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}
หน่วยความกว้างของวิวพอร์ต
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}
หน่วยด้านข้างของวิวพอร์ตที่เล็กที่สุด
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
หน่วยด้านข้างวิวพอร์ตที่ใหญ่ที่สุด
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

หวังว่าข้อมูลเหล่านี้จะช่วยให้นักพัฒนาซอฟต์แวร์และนักออกแบบมีความยืดหยุ่นที่จำเป็นสำหรับการออกแบบที่ปรับเปลี่ยนตามอุปกรณ์ของวิวพอร์ต

แหล่งข้อมูล

:has()

การรองรับเบราว์เซอร์

  • Chrome: 105
  • Edge: 105
  • Firefox: 121
  • Safari: 15.4

แหล่งที่มา

ก่อน :has() ตัวเลือกจะมีเรื่องอยู่ท้ายเสมอ เช่น เรื่องของตัวเลือกนี้คือรายการ: ul > li ตัวเลือกจำลองสามารถเปลี่ยนตัวเลือกได้ แต่ไม่เปลี่ยนเรื่อง ul > li:hover หรือ ul > li:not(.selected)

หลังจาก :has() หัวข้อที่สูงกว่าในลําดับชั้นองค์ประกอบจะยังคงเป็นหัวข้อได้ขณะแสดงคําค้นหาเกี่ยวกับเด็ก ul:has(> li) คุณจะเข้าใจได้ไม่ยากว่าเหตุใด :has() จึงมีชื่อเรียกทั่วไปว่า "ตัวเลือกหลัก" เนื่องจากในกรณีนี้ เรื่องของตัวเลือกคือรายการหลัก

ต่อไปนี้คือตัวอย่างไวยากรณ์พื้นฐานที่คลาส .parent ยังคงเป็นหัวเรื่องแต่จะเลือกก็ต่อเมื่อองค์ประกอบย่อยมีคลาส .child เท่านั้น

.parent:has(.child) {...}

นี่คือตัวอย่างที่มีองค์ประกอบ <section> เป็นชื่อเรื่อง แต่ตัวเลือกจะจับคู่ก็ต่อเมื่อองค์ประกอบย่อยรายการใดรายการหนึ่งมี :focus-visible

section:has(*:focus-visible) {...}

ตัวเลือก :has() จะเริ่มกลายเป็นยูทิลิตีที่ยอดเยี่ยมเมื่อกรณีการใช้งานที่เป็นประโยชน์มากขึ้นปรากฏขึ้น เช่น ตอนนี้ยังเลือกแท็ก <a> ไม่ได้เมื่อตัดรูปภาพเข้าไว้ด้วยกัน ซึ่งทำให้สอนให้แท็ก Anchor เปลี่ยนวิธีเปลี่ยนรูปแบบเมื่ออยู่ใน Use Case นั้นได้ยาก การดำเนินการนี้ทำได้ด้วย :has() แต่มีข้อจำกัดดังนี้

a:has(> img) {...}

ตัวอย่างทั้งหมดนี้แสดงให้เห็นว่า :has() ดูเหมือนตัวเลือกระดับบนสุดเท่านั้น พิจารณากรณีการใช้งานรูปภาพภายในองค์ประกอบ <figure> และการปรับสไตล์ในรูปภาพหากรูปภาพมี <figcaption> ในตัวอย่างต่อไปนี้ ระบบจะเลือกรูปภาพที่มีคำอธิบายรูปภาพ แล้วเลือกรูปภาพภายในบริบทนั้น :has() ใช้และไม่เปลี่ยนเรื่อง เนื่องจากเรื่องที่เรากําลังกําหนดเป้าหมายคือรูปภาพ ไม่ใช่ตัวเลข

figure:has(figcaption) img {...}

ดูเหมือนว่าจะมีชุดค่าผสมไม่รู้จบ รวม :has() เข้ากับการค้นหาจำนวนและปรับเลย์เอาต์ตารางกริด CSS ตามจํานวนรายการย่อย รวม :has() เข้ากับสถานะคลาสจำลองแบบอินเทอร์แอกทีฟ และสร้างแอปพลิเคชันที่ตอบสนองด้วยวิธีใหม่ๆ ที่สร้างสรรค์

การตรวจสอบการรองรับนั้นง่ายดายด้วย @supports และฟังก์ชัน selector() ของ @supports ซึ่งจะทดสอบว่าเบราว์เซอร์เข้าใจไวยากรณ์หรือไม่ก่อนที่จะใช้งาน

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

แหล่งข้อมูล

ปี 2022 เป็นต้นไป

แต่ยังมีอีกหลายสิ่งที่จะทำได้ยากหลังจากฟีเจอร์ที่น่าทึ่งเหล่านี้เปิดตัวในปี 2022 ส่วนถัดไปจะกล่าวถึงปัญหาบางส่วนที่ยังคงอยู่และโซลูชันที่กําลังพัฒนาเพื่อแก้ปัญหา โซลูชันเหล่านี้เป็นโซลูชันเวอร์ชันทดลอง แม้ว่าจะมีการระบุหรือมีให้บริการหลัง Flag ในเบราว์เซอร์ก็ตาม

สรุปจากส่วนถัดไปคือคุณควรสบายใจได้ว่าปัญหาที่ระบุไว้มีผู้คนจำนวนมากจากหลายบริษัทที่พยายามหาวิธีแก้ไข ไม่ใช่ว่าโซลูชันเหล่านี้จะเปิดตัวในปี 2023

พร็อพเพอร์ตี้ที่กำหนดเองแบบไม่บังคับ

การรองรับเบราว์เซอร์

  • Chrome: 85
  • ขอบ: 85
  • Firefox: 128
  • Safari: 16.4

แหล่งที่มา

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

พิจารณาสถานการณ์ที่ box-shadow ใช้พร็อพเพอร์ตี้ที่กำหนดเองสำหรับค่า ดังนี้

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

ทั้งหมดนี้ทํางานได้ดีจนกว่าจะมีการเปลี่ยนแปลงพร็อพเพอร์ตี้ใดพร็อพเพอร์ตี้หนึ่งเป็นค่าที่ CSS ไม่ยอมรับ เช่น --x: red เงาทั้งหมดจะหายไปหากตัวแปรที่ซ้อนกันอันใดอันหนึ่งหายไปหรือมีการตั้งค่าเป็นประเภทค่าที่ไม่ถูกต้อง

@property เข้ามามีบทบาทตรงนี้ --x กลายเป็นพร็อพเพอร์ตี้ที่กําหนดเองแบบมีประเภท ซึ่งไม่หลวมและไม่ยืดหยุ่นอีกต่อไป แต่ปลอดภัยด้วยขอบเขตที่กําหนดไว้

@property --x {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

ในตอนนี้ เมื่อ box-shadow ใช้ var(--x) และใช้ --x: red เวอร์ชันหลังจากนั้น ระบบจะไม่สนใจ red เนื่องจากไม่ใช่ <length> ซึ่งหมายความว่าเงาจะยังทำงานต่อไป แม้ว่าจะมีการระบุค่าที่ไม่ถูกต้องให้กับคุณสมบัติที่กำหนดเองแบบใดแบบหนึ่งก็ตาม โดยจะเปลี่ยนกลับเป็น initial-value จาก 0px แทนไม่สำเร็จ

แอนิเมชัน

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

ลองดูตัวอย่างการสาธิตนี้ซึ่งใช้การไล่ระดับสีแบบรัศมีเพื่อเป็นส่วนหนึ่งของการวางซ้อน ซึ่งทำให้เกิดเอฟเฟกต์การโฟกัสแบบสปอตไลท์ JavaScript จะตั้งค่าเมาส์ x และ y เมื่อกดแป้น alt/opt แล้วเปลี่ยนขนาดโฟกัสให้มีค่าน้อยลง เช่น 25% จะสร้างวงกลมโฟกัสของสปอตไลท์ที่ตำแหน่งเมาส์ ดังนี้

ลองใช้เดโม
.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );
}

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

วิดีโอเกมที่ใช้เอฟเฟกต์โฟกัสนี้มักจะแสดงภาพวงกลมเป็นภาพเคลื่อนไหวเสมอ ตั้งแต่วงกลมขนาดใหญ่ไปจนถึงวงกลมรูเข็ม วิธีใช้ @property กับการแสดงตัวอย่างเพื่อให้เบราว์เซอร์แสดงภาพเคลื่อนไหวของมาสก์ไล่ระดับมีดังนี้

@property --focal-size {
  syntax: '<length-percentage>';
  initial-value: 100%;
  inherits: false;
}

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );

  transition: --focal-size .3s ease;
}
ลองใช้การสาธิต

ตอนนี้เบราว์เซอร์สามารถสร้างภาพเคลื่อนไหวขนาดของไล่ระดับสีได้แล้ว เนื่องจากเราได้ลดพื้นที่ผิวของการแก้ไขให้เหลือเพียงพร็อพเพอร์ตี้เดียวและพิมพ์ค่าเพื่อให้เบราว์เซอร์สามารถหาค่าความยาวได้

@property ทำได้อีกมากมาย แต่การเปิดใช้เล็กๆ น้อยๆ เหล่านี้ก็ช่วยได้มาก

แหล่งข้อมูล

อยู่ใน min-width หรือ max-width

ก่อนช่วงของคำค้นหาสื่อ คำค้นหาสื่อ CSS ใช้ min-width และ max-width เพื่อระบุเงื่อนไขที่มากกว่าและน้อยกว่า ซึ่งอาจมีลักษณะดังนี้

@media (min-width: 320px) {
  
}

หลังจากช่วงการค้นหาสื่อแล้ว การค้นหาสื่อเดียวกันอาจมีลักษณะดังนี้

@media (width >= 320px) {
  
}

คิวรี่สื่อ CSS ที่ใช้ทั้ง min-width และ max-width อาจมีลักษณะดังนี้

@media (min-width: 320px) and (max-width: 1280px) {
  
}

หลังจากช่วงการค้นหาสื่อแล้ว การค้นหาสื่อเดียวกันอาจมีลักษณะดังนี้

@media (320px <= width <= 1280px) {
  
}

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

แหล่งข้อมูล

ไม่มีตัวแปรคิวรี่สื่อ

ก่อน @custom-media ต้องมีการค้นหาสื่อซ้ำๆ หรือต้องอาศัยโปรแกรมประมวลผลข้อมูลล่วงหน้าเพื่อสร้างเอาต์พุตที่เหมาะสมตามตัวแปรแบบคงที่ในระหว่างเวลาสร้าง

หลังจาก @custom-media CSS จะอนุญาตการใช้ชื่อแทนสื่อและการอ้างอิง เช่นเดียวกับพร็อพเพอร์ตี้ที่กำหนดเอง

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

@custom-media --OSdark  (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);

@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse   (hover) and (pointer: fine);

@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);

เมื่อกําหนดค่าแล้ว ฉันจะใช้ค่าใดค่าหนึ่งได้ดังนี้

@media (--OSdark) {
  :root {
    
  }
}

ค้นหารายการคำค้นหาสื่อที่กำหนดเองทั้งหมดที่ฉันใช้อยู่ในไลบรารีพร็อพเพอร์ตี้ CSS ที่กำหนดเอง Open Props

แหล่งข้อมูล

การวางตัวเลือกซ้อนกันนั้นยอดเยี่ยมมาก

ก่อน @nest ไฟล์สไตล์มีบรรทัดซ้ำกันมาก ซึ่งจะใช้งานยากมากเมื่อตัวเลือกมีความยาวมากและแต่ละรายการมีความแตกต่างเล็กน้อย ความสะดวกในการฝังเป็นหนึ่งในสาเหตุที่พบบ่อยที่สุดของการใช้โปรแกรมประมวลผลข้อมูลล่วงหน้า

หลังจาก @nest รายการ ระบบจะไม่แสดงรายการซ้ำอีก ฟีเจอร์เกือบทั้งหมดของการวางซ้อนที่เปิดใช้ตัวประมวลผลล่วงหน้าจะพร้อมใช้งานใน CSS

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

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

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

พิจารณาคอมโพเนนต์ย่อยที่ต้องการปรับตัวเองเมื่ออยู่ในบริบทของคอมโพเนนต์หลักอื่น แทนที่จะเป็นคอมโพเนนต์หลักที่เป็นเจ้าของสไตล์และเปลี่ยนแปลงคอมโพเนนต์ย่อย

/* parent owns this, adjusting children */
section:focus-within > article {
  border: 1px solid hotpink;
}

/* with @nest becomes */

/* article owns this, adjusting itself when inside a section:focus-within */
article {
  @nest section:focus-within > & {
     border: 1px solid hotpink;
  }
}

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

แหล่งข้อมูล

การกำหนดขอบเขตสไตล์นั้นยากมาก

การรองรับเบราว์เซอร์

  • Chrome: 118
  • Edge: 118
  • Firefox: อยู่หลังธง
  • Safari: 17.4

แหล่งที่มา

ก่อน @scope กลยุทธ์ต่างๆ มีอยู่มากมายเนื่องจากสไตล์ใน CSS ทำงานแบบเป็นลําดับชั้น มีการรับค่า และกำหนดขอบเขตเป็นแบบทั่วโลกโดยค่าเริ่มต้น ฟีเจอร์เหล่านี้ของ CSS มีประโยชน์มากในหลายๆ ด้าน แต่สำหรับเว็บไซต์และแอปพลิเคชันที่ซับซ้อนซึ่งมีคอมโพเนนต์ที่มีรูปแบบแตกต่างกันหลายแบบ พื้นที่ส่วนกลางและลักษณะของการเรียงลําดับชั้นอาจทําให้รูปแบบดูเหมือนว่าจะรั่วไหล

หลังจาก @scope คุณจะกำหนดขอบเขตสไตล์ให้อยู่ภายในบริบท เช่น คลาส เท่านั้นได้ และยังระบุจุดสิ้นสุดของสไตล์ที่จะไม่ทํางานแบบตามลําดับชั้นหรือรับค่าต่อ

ในตัวอย่างนี้ รูปแบบการตั้งชื่อ BEM สำหรับการกําหนดขอบเขตสามารถกลับเป็นเจตนาจริงได้ ตัวเลือก BEM พยายามกำหนดขอบเขตสีขององค์ประกอบ header ในคอนเทนเนอร์ .card โดยมีรูปแบบการตั้งชื่อ ซึ่งกำหนดให้ส่วนหัวต้องมีคลาสนี้ จึงจะบรรลุเป้าหมาย เมื่อใช้ @scope คุณไม่จำเป็นต้องตั้งชื่อรูปแบบเพื่อบรรลุเป้าหมายเดียวกันโดยไม่ต้องมาร์กอัปองค์ประกอบส่วนหัว

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

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

​​@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

@scope ยังช่วยให้คุณระบุจุดสิ้นสุดของขอบเขตสไตล์ได้ด้วย การดำเนินการนี้ไม่สามารถทำตามรูปแบบการตั้งชื่อหรือโปรแกรมประมวลผลข้อมูลก่อนการคอมไพล์ได้ เพราะเป็นการดำเนินการพิเศษที่ทำได้เฉพาะกับ CSS ในตัวเบราว์เซอร์เท่านั้น ในตัวอย่างนี้ ระบบจะใช้สไตล์ img และ .content เฉพาะในกรณีที่บุตรของ .media-block เป็นพี่น้องหรือบุตรของ .content

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

แหล่งข้อมูล

ไม่มีวิธี CSS สำหรับเลย์เอาต์แบบเรียงต่อกัน

ก่อนที่ CSS จะมีการจัดเรียงแบบ Masonry ที่มีตารางกริด JavaScript เป็นวิธีที่ดีที่สุดในการสร้างเลย์เอาต์แบบ Masonry เนื่องจากเมธอด CSS ที่มีคอลัมน์หรือ Flexbox จะแสดงลำดับเนื้อหาอย่างไม่ถูกต้อง

หลังจากการก่ออิฐ CSS พร้อมตารางกริดแล้ว ก็ไม่จำเป็นต้องมีไลบรารี JavaScript และลำดับเนื้อหาจะเป็นไปอย่างถูกต้อง

ภาพหน้าจอของเลย์เอาต์แบบเรียงต่อกันซึ่งแสดงตัวเลขที่เลื่อนไปด้านบนแล้วเลื่อนลง
รูปภาพและเดโมจาก Smashing Magazine
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

การแสดงตัวอย่างก่อนหน้านี้ทำได้ด้วย CSS ต่อไปนี้

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

เรายินดีที่ได้ทราบว่าเรื่องนี้อยู่ในเรดาร์ในฐานะกลยุทธ์เลย์เอาต์ที่ขาดหายไป และคุณลองใช้วันนี้ใน Firefox ได้ด้วย

แหล่งข้อมูล

CSS ไม่สามารถช่วยให้ผู้ใช้ลดปริมาณข้อมูลได้

การรองรับเบราว์เซอร์

  • Chrome: อยู่หลังธง
  • Edge: อยู่หลังธง
  • Firefox: ไม่รองรับ
  • Safari: ไม่รองรับ

แหล่งที่มา

ก่อนมี prefers-reduced-data Media Query นั้น JavaScript และเซิร์ฟเวอร์จะเปลี่ยนลักษณะการทำงานตามตัวเลือก "ประหยัดอินเทอร์เน็ต" ของระบบปฏิบัติการหรือเบราว์เซอร์ของผู้ใช้ แต่ CSS เปลี่ยนไม่ได้

หลังการค้นหาสื่อ prefers-reduced-data แล้ว CSS จะเข้าร่วมการเพิ่มประสิทธิภาพประสบการณ์ของผู้ใช้และมีส่วนร่วมในการบันทึกข้อมูลได้

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

CSS ที่อยู่ข้างหน้าใช้ในคอมโพเนนต์การเลื่อนสื่อนี้และประหยัดค่าใช้จ่ายได้มาก ยิ่งวิวพอร์ตที่กําลังเข้าชมมีขนาดใหญ่เท่าใด การโหลดหน้าเว็บก็จะยิ่งประหยัดมากขึ้นเท่านั้น ระบบจะบันทึกต่อไปขณะที่ผู้ใช้โต้ตอบกับแถบเลื่อนสื่อ รูปภาพทั้งหมดมีแอตทริบิวต์ loading="lazy" และนั่นประกอบกับ CSS ที่ซ่อนองค์ประกอบทั้งหมดไว้ หมายความว่าจะไม่มีการส่งคำขอเครือข่ายสำหรับรูปภาพ

ภาพหน้าจอของอินเทอร์เฟซภาพสไลด์รายการทีวีที่มีการแสดงภาพปกและชื่อรายการจำนวนมาก

ในการทดสอบของเรา วิวพอร์ตขนาดกลางมีการโหลดคำขอ 40 รายการและทรัพยากร 700 KB ในการโหลดครั้งแรก เมื่อผู้ใช้เลื่อนตัวเลือกสื่อ ระบบจะโหลดคําขอและทรัพยากรเพิ่มเติม เมื่อใช้ CSS และการค้นหาสื่อแบบลดข้อมูล ระบบจะโหลดคําขอ 10 รายการและทรัพยากร 172 KB เท่ากับว่าประหยัดได้ครึ่งเมกะไบต์และผู้ใช้ไม่เคยเลื่อนผ่านสื่อใดๆ เลย ทำให้ไม่มีคำขอเพิ่มเลย

ภาพหน้าจอของอินเทอร์เฟซภาพสไลด์รายการทีวีที่ไม่มีภาพปกและแสดงชื่อรายการจำนวนมาก

ประสบการณ์การใช้งานแบบลดปริมาณอินเทอร์เน็ตนี้มีข้อดีมากกว่าแค่การประหยัดอินเทอร์เน็ต ผู้ใช้จะเห็นหนังสือได้มากขึ้นและไม่มีภาพปกที่ดึงดูดความสนใจไปจากหนังสือ ผู้ใช้จํานวนมากท่องเว็บในโหมดประหยัดอินเทอร์เน็ตเนื่องจากต้องจ่ายเงินต่อเมกะไบต์ของอินเทอร์เน็ต เราจึงดีใจที่เห็น CSS ช่วยแก้ปัญหานี้ได้

แหล่งข้อมูล

ฟีเจอร์การเลื่อนแบบ Snap ถูกจํากัดมากเกินไป

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

API ใหม่

snapChanging()

เหตุการณ์นี้จะเริ่มต้นขึ้นทันทีที่เบราว์เซอร์ปล่อยรายการย่อยของ Snap วิธีนี้ช่วยให้ UI แสดงการขาดการสแนปและสถานะการสแนปที่ไม่ชัดเจนของแถบเลื่อน เนื่องจากขณะนี้มีการใช้งานและจะเข้าสู่ที่ใหม่

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()

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

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
scroll-start

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

:root { --nav-height: 100px }

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
:snap-target

ตัวเลือก CSS นี้จะจับคู่องค์ประกอบในคอนเทนเนอร์การเลื่อนที่แสดงผลอยู่ในปัจจุบันซึ่งเบราว์เซอร์จับคู่ไว้

.card {
  --shadow-distance: 5px;
  box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
  transition: box-shadow 350ms ease;
}

.card:snapped {
  --shadow-distance: 30px;
}

หลังจากใช้การเสนอภาพสแนปในการเลื่อนแล้ว การสร้างแถบเลื่อน ภาพสไลด์ หรือแกลเลอรีจะง่ายขึ้นมาก เนื่องจากตอนนี้เบราว์เซอร์มีความสะดวกสำหรับงานดังกล่าวแล้ว ซึ่งจะช่วยลดผู้สังเกตการณ์และโค้ดการจัดระเบียบการเลื่อนเพื่อหันมาใช้ API ในตัว

ฟีเจอร์ CSS และ JS เหล่านี้ยังอยู่ในขั้นเริ่มต้น แต่โปรดคอยติดตาม polyfill ที่จะช่วยในการนำฟีเจอร์เหล่านี้ไปใช้และทดสอบในเร็วๆ นี้

แหล่งข้อมูล

การสลับไปมาระหว่างสถานะที่รู้จัก

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

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

ในตัวอย่างต่อไปนี้ รายการในลิสต์ที่มีขีดทับจะแสดงผลแบบเดียวกันกับรายการที่เสร็จสมบูรณ์ แต่จะไม่มีองค์ประกอบช่องทําเครื่องหมาย

<ul class='ingredients'>
   <li>1 banana
   <li>1 cup blueberries
  ...
</ul>

และสไตล์ toggle() ของ CSS ที่เกี่ยวข้อง

li {
  toggle-root: check self;
}

li:toggle(check) {
  text-decoration: line-through;
}

หากคุ้นเคยกับสถานะการทำงานของเครื่องแล้ว คุณอาจสังเกตเห็นการทับซ้อนกันของ toggle() ฟีเจอร์นี้จะช่วยให้นักพัฒนาซอฟต์แวร์สร้างสถานะเพิ่มเติมใน CSS ได้ ซึ่งหวังว่าจะส่งผลให้มีวิธีจัดการการโต้ตอบและสถานะที่ชัดเจนและมีความหมายมากขึ้น

แหล่งข้อมูล

กำลังปรับแต่งองค์ประกอบที่เลือก

ก่อน <selectmenu> CSS ไม่สามารถปรับแต่งองค์ประกอบ <option> ด้วย HTML แบบริชมีเดียหรือเปลี่ยนแปลงการแสดงรายการตัวเลือกได้ ด้วยเหตุนี้ นักพัฒนาซอฟต์แวร์จึงต้องโหลดไลบรารีภายนอกซึ่งสร้างฟังก์ชันการทำงานของ <select> ขึ้นมาใหม่เกือบทั้งหมด ซึ่งทำให้ต้องทํางานมากขึ้น

หลังจาก <selectmenu> นักพัฒนาแอปสามารถระบุ HTML ที่เป็นริชมีเดียสำหรับองค์ประกอบตัวเลือกและจัดรูปแบบได้ตามต้องการ ขณะเดียวกันก็ยังคงเป็นไปตามข้อกำหนดการช่วยเหลือพิเศษและระบุ HTML เชิงความหมาย

ในตัวอย่างนี้ซึ่งนำมาจาก<selectmenu>หน้าอธิบาย ระบบจะสร้างเมนูตัวเลือกใหม่ที่มีตัวเลือกพื้นฐานบางอย่าง ดังนี้

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

CSS สามารถกําหนดเป้าหมายและจัดรูปแบบส่วนต่างๆ ขององค์ประกอบได้ ดังนี้

.my-select-menu::part(button) {
  color: white;
  background-color: red;
  padding: 5px;
  border-radius: 5px;
}

.my-select-menu::part(listbox) {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid red;
  border-radius: 5px;
}

เมนูที่ดูมีสไตล์พร้อมสีไฮไลต์สีแดง

คุณลองใช้องค์ประกอบ <selectmenu> ใน Chromium ใน Canary ได้เมื่อเปิดใช้ Flag การทดลองบนเว็บ ระวังในปี 2023 และปีต่อๆ ไปสำหรับ องค์ประกอบเมนูการเลือกที่ปรับแต่งได้

แหล่งข้อมูล

การยึดองค์ประกอบกับองค์ประกอบอื่น

ก่อนวันที่ anchor() ตำแหน่งแบบสัมบูรณ์และสัมพัทธ์คือกลยุทธ์ตำแหน่งที่ให้ไว้เพื่อให้นักพัฒนาแอปเพื่อให้องค์ประกอบย่อยย้ายไปมาภายในองค์ประกอบหลัก

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

เอกสารอธิบายมีตัวอย่างที่ยอดเยี่ยมและโค้ดตัวอย่างบางส่วน หากต้องการดูข้อมูลเพิ่มเติม

แหล่งข้อมูล