การซ้อนกฎสไตล์ 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