การสืบทอด

พอดแคสต์ CSS - 005: การสืบทอด

สมมติว่าคุณเพิ่งเขียน CSS เพื่อทำให้องค์ประกอบดูเหมือนปุ่ม

<a href="http://example.com" class="my-button">I am a button link</a>
.my-button {
  display: inline-block;
  padding: 1rem 2rem;
  text-decoration: none;
  background: pink;
  font: inherit;
  text-align: center;
}

จากนั้นเพิ่มเอลิเมนต์ของลิงก์ ลงในบทความเนื้อหา ที่มีค่า class เป็น .my-button แต่มีปัญหาเกิดขึ้น ข้อความไม่ใช่สีตามที่คุณคาดหวังไว้ เกิดขึ้นได้อย่างไร

พร็อพเพอร์ตี้ CSS บางรายการจะรับค่ามาหากคุณไม่ระบุค่า ในกรณีของปุ่มนี้ ปุ่มนี้ได้รับ color มาจาก CSS นี้

article a {
  color: maroon;
}

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

ขั้นตอนการรับค่า

มาดูวิธีการทำงานของการรับช่วงค่ากัน โดยใช้ข้อมูลโค้ด HTML นี้

<html>
  <body>
    <article>
      <p>Lorem ipsum dolor sit amet.</p>
    </article>
  </body>
</html>

องค์ประกอบรูท (<html>) จะไม่รับช่วงค่าใดๆ เนื่องจากเป็นองค์ประกอบแรกในเอกสาร เพิ่ม CSS ในองค์ประกอบ HTML และเริ่มไล่ระดับเอกสาร

html {
  color: lightslategray;
}

องค์ประกอบอื่นๆ จะรับพร็อพเพอร์ตี้ color มาโดยค่าเริ่มต้น องค์ประกอบ html มี color: lightslategray ดังนั้นองค์ประกอบทั้งหมดที่รับค่าสีได้ก็จะมีสี lightslategray

body {
  font-size: 1.2em;
}
p {
  font-style: italic;
}

เฉพาะ <p> เท่านั้นที่จะมีข้อความตัวเอียงเนื่องจากเป็นองค์ประกอบที่ฝังอยู่ลึกที่สุด การรับค่าจะเลื่อนลงไปยังระดับล่างเท่านั้น ไม่สำรองข้อมูลไปยังองค์ประกอบระดับบนสุด

พร็อพเพอร์ตี้ใดบ้างที่รับค่าเดิมมาโดยค่าเริ่มต้น

พร็อพเพอร์ตี้ CSS บางรายการไม่ได้รับค่ามาโดยค่าเริ่มต้น แต่มีอีกหลายอย่างที่เป็นเช่นนั้น ต่อไปนี้คือรายการพร็อพเพอร์ตี้ทั้งหมดที่รับค่ามาโดยค่าเริ่มต้น นำมาจากข้อมูลอ้างอิง W3 ของพร็อพเพอร์ตี้ CSS ทั้งหมด

วิธีการทำงานของการรับช่วง

องค์ประกอบ HTML ทุกรายการมีพร็อพเพอร์ตี้ CSS ทุกรายการที่กำหนดไว้โดยค่าเริ่มต้นโดยมีค่าเริ่มต้น ค่าเริ่มต้นเป็นพร็อพเพอร์ตี้ที่ไม่ได้รับสืบทอดมาและแสดงเป็นค่าเริ่มต้น หาก Cascade ไม่สามารถคำนวณค่าขององค์ประกอบนั้น

พร็อพเพอร์ตี้ที่สืบทอดต่อกันลงมาได้ และองค์ประกอบย่อยจะได้รับค่าที่คำนวณแล้วซึ่งแสดงค่าของระดับบนสุด ซึ่งหมายความว่าหากหลักมีการตั้งค่า font-weight เป็น bold องค์ประกอบย่อยทั้งหมดจะเป็นตัวหนา เว้นแต่จะตั้งค่า font-weight เป็นค่าอื่น หรือสไตล์ชีตของ User Agent มีค่าสำหรับ font-weight สำหรับองค์ประกอบนั้น

วิธีรับค่าและควบคุมการรับช่วงมาอย่างชัดแจ้ง

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

คีย์เวิร์ด inherit

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

strong {
  font-weight: 900;
}

ข้อมูลโค้ด CSS นี้ตั้งค่าองค์ประกอบ <strong> ทั้งหมดให้มี font-weight เป็น 900 แทนค่า bold เริ่มต้น ซึ่งจะเทียบเท่ากับ font-weight: 700

.my-component {
  font-weight: 500;
}

คลาส .my-component จะตั้งค่า font-weight เป็น 500 แทน หากต้องการทำให้องค์ประกอบ <strong> ภายใน .my-component font-weight: 500 ให้เพิ่มองค์ประกอบต่อไปนี้ด้วย

.my-component strong {
  font-weight: inherit;
}

ตอนนี้ องค์ประกอบ <strong> ภายใน .my-component จะมี font-weight ของ 500

คุณสามารถกำหนดค่านี้อย่างชัดแจ้ง แต่ถ้าคุณใช้ inherit และ CSS ของ .my-component การเปลี่ยนแปลงในอนาคต คุณสามารถรับประกันได้ว่า <strong> ของคุณจะอัปเดต โดยอัตโนมัติ

คีย์เวิร์ด initial

การรับค่าอาจทำให้องค์ประกอบมีปัญหาและ initial มีตัวเลือกการรีเซ็ตที่มีประสิทธิภาพให้คุณ

คุณได้เรียนรู้ก่อนหน้านี้ว่าทุกพร็อพเพอร์ตี้มีค่าเริ่มต้นใน CSS คีย์เวิร์ด initial จะตั้งค่าพร็อพเพอร์ตี้กลับไปยังค่าเริ่มต้นเริ่มต้น

aside strong {
  font-weight: initial;
}

ข้อมูลโค้ดนี้จะลบน้ำหนักตัวหนาออกจากองค์ประกอบ <strong> ทั้งหมดภายในองค์ประกอบ <aside> และจะใช้แทน ทำให้เป็นน้ำหนักปกติ ซึ่งเป็นค่าเริ่มต้น

คีย์เวิร์ด unset

พร็อพเพอร์ตี้ unset จะทำงานต่างออกไปหากพร็อพเพอร์ตี้รับค่าเดิมมาโดยค่าเริ่มต้นหรือไม่ หากพร็อพเพอร์ตี้ได้รับการรับค่ามาโดยค่าเริ่มต้น คีย์เวิร์ด unset จะเหมือนกับ inherit หากพร็อพเพอร์ตี้ไม่รับช่วงมาโดยค่าเริ่มต้น คีย์เวิร์ด unset จะเท่ากับ initial

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

/* Global color styles for paragraph in authored CSS */
p {
  margin-top: 2em;
  color: goldenrod;
}

/* The p needs to be reset in asides, so you can use unset */
aside p {
  margin: unset;
  color: unset;
}

ตอนนี้ระบบจะนำ margin ออก และ color จะเปลี่ยนกลับไปเป็นค่าที่คำนวณมาซึ่งรับค่ามา

คุณใช้ค่า unset กับพร็อพเพอร์ตี้ all ได้ด้วย กลับไปที่ตัวอย่างด้านบน จะเกิดอะไรขึ้นหากรูปแบบ p ส่วนกลางได้รับพร็อพเพอร์ตี้เพิ่มเติม 2-3 รายการ เฉพาะกฎที่ตั้งไว้สำหรับ margin และ color จะมีผล

/* Global color styles for paragraph in authored CSS */
p {
    margin-top: 2em;
    color: goldenrod;
    padding: 2em;
    border: 1px solid;
}

/* Not all properties are accounted for anymore */
aside p {
    margin: unset;
    color: unset;
}

หากคุณเปลี่ยนกฎ aside p เป็น all: unset แทน ไม่ว่าในอนาคตจะใช้รูปแบบสากลแบบใดกับ p จะยกเลิกการตั้งค่าเสมอ

aside p {
    margin: unset;
    color: unset;
    all: unset;
}

ตรวจสอบความเข้าใจ

ทดสอบความรู้ของคุณเกี่ยวกับการสืบทอดค่า

พร็อพเพอร์ตี้ใดต่อไปนี้ที่สามารถรับค่าได้

animation
ภาพเคลื่อนไหวไม่ได้ส่งต่อให้กับเด็ก
font-size
🎉
color
🎉
text-align
🎉
line-height
🎉

ค่าใดมีลักษณะเหมือน inherit เว้นแต่จะไม่มีอะไรให้รับค่า และ แล้วมีลักษณะการทำงานเหมือน initial ไหม

reset
ไม่ใช่ค่าที่ถูกต้อง โปรดลองอีกครั้ง
unset
🎉
superset
ไม่ใช่ค่าที่ถูกต้อง โปรดลองอีกครั้ง

แหล่งข้อมูล