คุณต้องการช่วยเราเลือกไวยากรณ์ 2 รายการที่แข่งขันกันเพื่อนำไปใช้เป็นข้อกำหนดเบื้องต้น
การฝัง CSS คือการเพิ่มไวยากรณ์ที่สะดวกซึ่งช่วยให้คุณเพิ่ม CSS เข้าไปในกฎได้ หากคุณเคยใช้ SCSS, Less หรือ Stylus แสดงว่าคุณได้เห็นรูปแบบต่อไปนี้อย่างแน่นอน
.nesting {
color: hotpink;
> .is {
color: rebeccapurple;
> .awesome {
color: deeppink;
}
}
}
ซึ่งหลังจากคอมไพล์เป็น CSS ปกติโดยโปรแกรมประมวลผลข้อมูลล่วงหน้าแล้ว จะกลายเป็น CSS ปกติดังนี้
.nesting {
color: hotpink;
}
.nesting > .is {
color: rebeccapurple;
}
.nesting > .is > .awesome {
color: deeppink;
}
เรากำลังพิจารณาอย่างจริงจังที่จะใช้รูปแบบคำสั่งนี้ใน CSS เวอร์ชันอย่างเป็นทางการ และเรามีความเห็นที่แตกต่างกันไปซึ่งต้องการความช่วยเหลือจากชุมชนเพื่อตัดสิน ส่วนที่เหลือของโพสต์นี้จะแนะนำตัวเลือกไวยากรณ์เพื่อให้คุณมีข้อมูลประกอบการตัดสินใจในแบบสํารวจในตอนท้าย
เหตุใดตัวอย่างการฝังที่แน่นอนซึ่งแสดงอยู่ด้านบนจึงไม่ใช่ไวยากรณ์สำหรับการฝัง CSS
สาเหตุที่ไม่สามารถนําไวยากรณ์การฝังที่ได้รับความนิยมสูงสุดไปใช้ได้โดยตรงมีดังนี้
การแยกวิเคราะห์ที่ไม่ชัดเจน
ตัวเลือกที่ฝังอยู่บางรายการอาจดูเหมือนพร็อพเพอร์ตี้และโปรแกรมประมวลผลข้อมูลล่วงหน้า สามารถแก้ไขและจัดการตัวเลือกเหล่านั้นได้เมื่อถึงเวลาสร้าง เครื่องมือของเบราว์เซอร์จะไม่มีความพร้อมใช้งานแบบเดียวกัน จึงไม่ควรจะตีความตัวเลือกอย่างหลวมๆความขัดแย้งในการแยกวิเคราะห์ของโปรแกรมประมวลผลข้อมูลล่วงหน้า
การฝัง CSS ไม่ควรทำให้โปรแกรมประมวลผลข้อมูลล่วงหน้าหรือเวิร์กโฟลว์การฝังของนักพัฒนาแอปที่มีอยู่ใช้งานไม่ได้ ซึ่งจะสร้างความสับสนและไม่คำนึงถึงระบบนิเวศและชุมชนเหล่านั้นกำลังรอ
:is()
การฝังพื้นฐานไม่จำเป็นต้องใช้:is()
แต่การฝังที่ซับซ้อนกว่านั้นต้องใช้ ดูตัวอย่างที่ 3 เพื่อดูข้อมูลเบื้องต้นเกี่ยวกับรายการตัวเลือกและการฝัง ลองจินตนาการว่ารายการตัวเลือกอยู่ตรงกลางของตัวเลือกแทนที่จะเป็นตอนต้น ในกรณีเหล่านี้ คุณต้องใช้:is()
เพื่อจัดกลุ่มตัวเลือกไว้ตรงกลางของตัวเลือกอื่น
ภาพรวมของสิ่งที่เราเปรียบเทียบ
เราต้องการทำให้การฝัง CSS ถูกต้อง และด้วยเหตุนี้ เราจึงรวมชุมชนเข้ามาด้วย ส่วนต่อไปนี้จะช่วยอธิบายเวอร์ชัน 3 รูปแบบที่เป็นไปได้ซึ่งเรากําลังประเมิน จากนั้นเราจะดูตัวอย่างการใช้งานเพื่อเปรียบเทียบ และในตอนท้ายจะมีแบบสำรวจสั้นๆ ถามว่าคุณชอบแบบไหนโดยรวม
ตัวเลือกที่ 1: @nest
นี่คือไวยากรณ์ที่ระบุในปัจจุบันใน CSS Nesting 1 ซึ่งช่วยให้คุณฝังรูปแบบต่อท้ายได้อย่างสะดวกโดยเริ่มตัวเลือกที่ฝังใหม่ด้วย &
นอกจากนี้ ยังมี@nest
เป็นวิธีวางบริบท &
ไว้ที่ใดก็ได้ภายในตัวเลือกใหม่ เช่น เมื่อคุณไม่ได้เพิ่มเรื่องต่อท้าย รูปแบบนี้มีความยืดหยุ่นและเรียบง่าย แต่คุณจะต้องจำ @nest
หรือ &
ไว้ด้วย ทั้งนี้ขึ้นอยู่กับกรณีการใช้งาน
ตัวเลือกที่ 2: @nest ถูกจำกัด
วิธีนี้เป็นทางเลือกที่เข้มงวดกว่า เพื่อช่วยลดความยุ่งยากในการจดจำวิธีการฝัง 2 วิธี ไวยากรณ์ที่จํากัดนี้อนุญาตให้ฝังได้เฉพาะตามหลัง @nest
จึงไม่มีรูปแบบที่สะดวกสำหรับการต่อท้ายเท่านั้น การนำความคลุมเครือของทางเลือกออก สร้างวิธีฝังที่จดจำได้ง่ายวิธีเดียว แต่ต้องเสียความกระชับเพื่อใช้รูปแบบ
ตัวเลือกที่ 3: วงเล็บ
เพื่อหลีกเลี่ยงรูปแบบคำสั่งที่ซ้ำกันหรือความยุ่งเหยิงเพิ่มเติมที่เกี่ยวข้องกับ@nest
ข้อเสนอ Miriam Suzanne และ Elika Etemad ได้เสนอรูปแบบคำสั่งอื่นที่ใช้วงเล็บปีกกาเพิ่มเติมแทน วิธีนี้ช่วยให้ไวยากรณ์มีความชัดเจน โดยมีอักขระเพิ่มเติมเพียง 2 ตัวเท่านั้นและไม่มีกฎ at ใหม่ นอกจากนี้ ยังช่วยให้จัดกลุ่มกฎที่ซ้อนกันตามประเภทการซ้อนที่จำเป็นได้ เพื่อลดความซับซ้อนของตัวเลือกที่ซ้อนกันหลายรายการที่คล้ายกัน
ตัวอย่างที่ 1 - การฝังโดยตรง
@nest
.foo {
color: #111;
& .bar {
color: #eee;
}
}
@nest always
.foo {
color: #111;
@nest & .bar {
color: #eee;
}
}
วงเล็บ
.foo {
color: #111;
{
& .bar {
color: #eee;
}
}
}
CSS ที่เทียบเท่า
.foo {
color: #111;
}
.foo .bar {
color: #eee;
}
ตัวอย่างที่ 2 - การฝังคอมโพเนนต์
@nest
.foo {
color: blue;
&.bar {
color: red;
}
}
@nest always
.foo {
color: blue;
@nest &.bar {
color: red;
}
}
วงเล็บ
.foo {
color: blue;
{
&.bar {
color: red;
}
}
}
CSS ที่เทียบเท่า
.foo {
color: blue;
}
.foo.bar {
color: red;
}
ตัวอย่างที่ 3 - รายการตัวเลือกและการฝัง
@nest
.foo, .bar {
color: blue;
& + .baz,
&.qux {
color: red;
}
}
@nest always
.foo, .bar {
color: blue;
@nest & + .baz,
&.qux {
color: red;
}
}
วงเล็บ
.foo, .bar {
color: blue;
{
& + .baz,
&.qux {
color: red;
}
}
}
CSS ที่เทียบเท่า
.foo, .bar {
color: blue;
}
:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux {
color: red;
}
ตัวอย่างที่ 4 - หลายระดับ
@nest
figure {
margin: 0;
& > figcaption {
background: lightgray;
& > p {
font-size: .9rem;
}
}
}
@nest always
figure {
margin: 0;
@nest & > figcaption {
background: lightgray;
@nest & > p {
font-size: .9rem;
}
}
}
วงเล็บ
figure {
margin: 0;
{
& > figcaption {
background: lightgray;
{
& > p {
font-size: .9rem;
}
}
}
}
}
CSS ที่เทียบเท่า
figure {
margin: 0;
}
figure > figcaption {
background: hsl(0 0% 0% / 50%);
}
figure > figcaption > p {
font-size: .9rem;
}
ตัวอย่างที่ 5 - การเปลี่ยนเรื่องหรือมีการฝังรายการหลัก
@nest
.foo {
color: red;
@nest .parent & {
color: blue;
}
}
@nest always
.foo {
color: red;
@nest .parent & {
color: blue;
}
}
วงเล็บ
.foo {
color: red;
{
.parent & {
color: blue;
}
}
}
CSS ที่เทียบเท่า
.foo {
color: red;
}
.parent .foo {
color: blue;
}
ตัวอย่าง 6 - การผสมการฝังโดยตรงกับการฝังระดับบน
@nest
.foo {
color: blue;
@nest .bar & {
color: red;
&.baz {
color: green;
}
}
}
@nest always
.foo {
color: blue;
@nest .bar & {
color: red;
@nest &.baz {
color: green;
}
}
}
วงเล็บ
.foo {
color: blue;
{
.bar & {
color: red;
{
&.baz {
color: green;
}
}
}
}
}
CSS ที่เทียบเท่า
.foo {
color: blue;
}
.bar .foo {
color: red;
}
.bar .foo.baz {
color: green;
}
ตัวอย่างที่ 7 - การฝัง Media Query
@nest
.foo {
display: grid;
@media (width => 30em) {
grid-auto-flow: column;
}
}
หรืออย่างชัดแจ้ง / ขยาย
.foo {
display: grid;
@media (width => 30em) {
& {
grid-auto-flow: column;
}
}
}
@nest always (เป็นคำสั่งแบบระบุค่าเสมอ)
.foo {
display: grid;
@media (width => 30em) {
@nest & {
grid-auto-flow: column;
}
}
}
วงเล็บ
.foo {
display: grid;
@media (width => 30em) {
grid-auto-flow: column;
}
}
หรืออย่างชัดแจ้ง / ขยาย
.foo {
display: grid;
@media (width => 30em) {
& {
grid-auto-flow: column;
}
}
}
CSS ที่เทียบเท่า
.foo {
display: grid;
}
@media (width => 30em) {
.foo {
grid-auto-flow: column;
}
}
ตัวอย่างที่ 8 - การฝังกลุ่ม
@nest
fieldset {
border-radius: 10px;
&:focus-within {
border-color: hotpink;
}
& > legend {
font-size: .9em;
}
& > div {
& + div {
margin-block-start: 2ch;
}
& > label {
line-height: 1.5;
}
}
}
@nest always
fieldset {
border-radius: 10px;
@nest &:focus-within {
border-color: hotpink;
}
@nest & > legend {
font-size: .9em;
}
@nest & > div {
@nest & + div {
margin-block-start: 2ch;
}
@nest & > label {
line-height: 1.5;
}
}
}
วงเล็บ
fieldset {
border-radius: 10px;
{
&:focus-within {
border-color: hotpink;
}
}
> {
legend {
font-size: .9em;
}
div {
+ div {
margin-block-start: 2ch;
}
> label {
line-height: 1.5;
}
}}
}
}
CSS ที่เทียบเท่า
fieldset {
border-radius: 10px;
}
fieldset:focus-within {
border-color: hotpink;
}
fieldset > legend {
font-size: .9em;
}
fieldset > div + div {
margin-block-start: 2ch;
}
fieldset > div > label {
line-height: 1.5;
}
ตัวอย่างที่ 9 - กลุ่มที่ฝังซ้อนกันแบบซับซ้อน "Kitchen Sink"
@nest
dialog {
border: none;
&::backdrop {
backdrop-filter: blur(25px);
}
& > form {
display: grid;
& > :is(header, footer) {
align-items: flex-start;
}
}
@nest html:has(&[open]) {
overflow: hidden;
}
}
@nest always
dialog {
border: none;
@nest &::backdrop {
backdrop-filter: blur(25px);
}
@nest & > form {
display: grid;
@nest & > :is(header, footer) {
align-items: flex-start;
}
}
@nest html:has(&[open]) {
overflow: hidden;
}
}
วงเล็บ
dialog {
border: none;
{
&::backdrop {
backdrop-filter: blur(25px);
}
& > form {
display: grid;
{
& > :is(header, footer) {
align-items: flex-start;
}
}
}
}
{
html:has(&[open]) {
overflow: hidden;
}
}
}
CSS ที่เทียบเท่า
dialog {
border: none;
}
dialog::backdrop {
backdrop-filter: blur(25px);
}
dialog > form {
display: grid;
}
dialog > form > :is(header, footer) {
align-items: flex-start;
}
html:has(dialog[open]) {
overflow: hidden;
}
เวลาลงคะแนน
เราหวังว่าคุณจะเห็นว่านี่เป็นการเปรียบเทียบที่ยุติธรรมและตัวอย่างตัวเลือกไวยากรณ์ที่เรากำลังประเมิน โปรดตรวจสอบอย่างละเอียดและแจ้งให้เราทราบว่าคุณต้องการใช้รูปแบบใดด้านล่าง ขอขอบคุณที่ช่วยให้เราสามารถพัฒนาการฝัง CSS ให้เป็นไวยากรณ์ที่เราทุกคนจะได้รู้จักและชื่นชอบ