ไวยากรณ์ 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 ตัวและไม่มีกฎ @ ใหม่ นอกจากนี้ ยังช่วยให้จัดกลุ่มกฎที่ซ้อนกัน
ตามประเภทการซ้อนที่ต้องการได้ ซึ่งเป็นวิธีลดความซับซ้อนของ
ตัวเลือกที่ซ้อนกันหลายรายการในลักษณะเดียวกัน
ตัวอย่างที่ 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 (is always explicit)
.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 ให้เป็นไวยากรณ์ที่ ทุกคนจะรู้จักและชื่นชอบ