การฝัง

การซ้อนกฎสไตล์ CSS จะช่วยให้สไตล์ชีตเป็นระเบียบมากขึ้น อ่านง่ายขึ้น และดูแลรักษาได้ง่ายขึ้น

ภาพรวม

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

.feature {
  button {
    color: blue;
  }

  .link {
    color: red;
  }

  .text {
    font-size: 1.3em;
  }
}

ซึ่งจะเหมือนกับการเขียนแต่ละสไตล์แยกกัน ดังนี้

.feature button {
  color: blue;
}

.feature .link {
   color: red;
}

.feature .text {
   font-size: 1.3em;
}

คุณซ้อนเลเยอร์ได้มากเท่าที่ต้องการ

.feature {
  .heading {
    color: blue;

    a {
      color: green;
    }
  }
}

การจัดกลุ่มและการสร้างความสัมพันธ์

การซ้อนช่วยให้คุณจัดกลุ่มและสร้างความสัมพันธ์ระหว่างกฎสไตล์ได้อย่างกระชับยิ่งขึ้น

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

/* targets headings that are siblings of the .feature element and come immediately after it */
.feature {
  + .heading {
    color: blue;
  }

/* targets all paragraphs that are direct children of the .feature element */
  > p {
    font-size: 1.3em;
  }
}

กำหนดความสัมพันธ์ที่ชัดเจนด้วยตัวเลือก &

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

.feature {
 & button {
    color: blue;
  }
}

ซึ่งจะเทียบเท่ากับการเขียนรูปแบบดังนี้

.feature button {
  color: blue;
}

เมื่อต้องใช้ &

หากไม่มี & ตัวเลือกที่ซ้อนกันจะเป็นตัวเลือกลูกหลานของตัวเลือกหลัก หากต้องการสร้างตัวเลือกแบบผสม & ต้องระบุ

.feature {
  &:last-child {
    /* Selects the .feature element that is the :last-child, equivalent to .feature:last-child */
  }
   
  & :last-child {
    /* Selects the :last-child inside of a .feature element, equivalent to .feature :last-child */
  }

  &.highlight {
    /* Selects .feature elements that also have a .highlight class, equivalent to .feature.highlight */
  }

  & .highlight {
     /* Selects elements inside of the .feature element with the class .highlight, equivalent to .feature .highlight */
  }
}

นอกจากนี้ คุณยังเปลี่ยนบริบทและวางตัวเลือก & ไว้ที่ท้ายตัวเลือกบุตรหลานหรือทั้ง 2 ด้านได้ด้วย


/* Targets buttons with an adjacent sibling button */
button {
  & + & {
    /* … */
  }
}
img {
  .my-component & {
    /* styles for images inside of `.my-component` ... */
  }
}

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

การซ้อนและการเจาะจง

เช่น :is() ตัวเลือกการซ้อนจะใช้ความเฉพาะเจาะจงของตัวเลือกที่มีความเฉพาะเจาะจงสูงสุดในรายการตัวเลือกขององค์ประกอบหลัก

#main-header,
.intro {
  & a {
    color: green;
  }
}

.intro a {
  color: blue;
}

กฎแรกกำหนดเป้าหมายลิงก์ทั้งหมดภายในองค์ประกอบ #main-header และ .intro โดยกำหนดให้มีสีเขียว

กฎที่ 2 พยายามลบล้างกฎนี้เพื่อให้ลิงก์ภายในองค์ประกอบ .intro เป็นสีน้ำเงิน

เราจะเห็นว่าเหตุใดจึงใช้ไม่ได้หากดูความเฉพาะเจาะจงของแต่ละกฎ

/* equivalent to :is(#main-header, .intro) a with a specificity of (1, 0, 1) */
#main-header,
.intro {
  & a {
    color: green;
  }
}

/* lower specificity of (0, 1, 1) */
.intro a {
  color: blue;
}

เนื่องจากกฎแรกมี id ในรายการตัวเลือก และกฎที่ซ้อนกันจะใช้ความเฉพาะเจาะจงของตัวเลือกที่มีความเฉพาะเจาะจงสูงสุด กฎแรกจึงมีความเฉพาะเจาะจงสูงกว่ากฎที่ 2 ลิงก์จะเป็นสีเขียวแม้สำหรับองค์ประกอบ a ที่ไม่ได้อยู่ภายในองค์ประกอบที่มีตัวเลือก #main-header

การซ้อนไม่ถูกต้อง

ตัวเลือกการซ้อนไม่สามารถแสดงองค์ประกอบเสมือนได้เช่นเดียวกับ :is()

blockquote, blockquote::before, blockquote::after {
  color: navy;

  & {
    border: 1px solid navy;
  }
}

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

เมื่อสร้างตัวเลือกแบบผสมโดยใช้ & และตัวเลือกประเภท ตัวเลือกประเภทต้องมาก่อนโดยไม่มีช่องว่างระหว่างกัน

/* valid css nesting */
.feature {
  p& {
    font-weight: bold;
  }
}

/* invalid css nesting */
.feature {
  &p {
    font-weight: bold;
  }
}

กฎนี้ช่วยให้การซ้อน CSS ทำงานร่วมกับเครื่องมือก่อนการประมวลผล เช่น Sass ได้ ใน Sass การเขียน &p จะต่อท้ายตัวเลือกหลักกับตัวเลือกประเภทที่ซ้อนกัน และผลลัพธ์จะเป็น .featurep

การซ้อนกฎ @

นอกจากนี้ คุณยังซ้อนกฎกลุ่มแบบมีเงื่อนไขของ CSS เช่น @container, @media, @supports และ @layer ได้ด้วย

.feature {
  @media (min-width: 40em) {
    /* ... */
  }

  @container (inline-size > 900px) {
    /* ... */
  }
}

.feature {
  @supports (display: grid) {
    /* ... */
  }
}

.feature {
  @layer component {
    h2 {
      /* ... */
    }
  }
}

ทดสอบความเข้าใจ

เมื่อใช้ CSS Nesting ตัวเลือก & จะแสดงถึงอะไร

ตัวเลือกองค์ประกอบย่อยที่ซ้อนกัน
ผิด
ตัวเลือกหลัก
ถูกต้อง
ตัวเลือกพี่น้องที่ใกล้ที่สุด
ผิด

คุณซ้อนได้เพียง 2 ระดับเท่านั้น

จริง
ผิด
เท็จ
ถูกต้อง

กฎ @ ใดบ้างที่ซ้อนกันได้

@media
ถูกต้อง
@container
ถูกต้อง
@import
ผิด
@supports
ถูกต้อง
@layer
ถูกต้อง