The CSS Podcast - 005: Inheritance
สมมติว่าคุณเพิ่งเขียน 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 แล้ว CSS จะเริ่มมีผลกับส่วนต่างๆ ของเอกสาร
html {
color: lightslategray;
}
องค์ประกอบอื่นๆ จะรับค่าพร็อพเพอร์ตี้ color
มาจากค่าเริ่มต้น
องค์ประกอบ html
มี color: lightslategray
ดังนั้นองค์ประกอบทั้งหมดที่รับค่าสีมาจะมีสีเป็น lightslategray
body {
font-size: 1.2em;
}
p {
font-style: italic;
}
เฉพาะ <p>
เท่านั้นที่จะมีข้อความตัวเอียงเนื่องจากเป็นองค์ประกอบที่ฝังอยู่ลึกที่สุด
การสืบทอดจะส่งต่อไปยังองค์ประกอบที่ต่ำกว่าเท่านั้น แต่จะไม่มีการส่งต่อกลับไปยังองค์ประกอบหลัก
พร็อพเพอร์ตี้ใดบ้างที่รับค่าตามค่าเริ่มต้น
คุณสมบัติ CSS บางรายการจะรับค่าโดยค่าเริ่มต้น แต่ก็มีอีกหลายรายการที่รับค่า ต่อไปนี้เป็นรายการพร็อพเพอร์ตี้ทั้งหมดที่รับช่วงค่าโดยค่าเริ่มต้นซึ่งนำมาจากข้อมูลอ้างอิง W3 ของพร็อพเพอร์ตี้ CSS ทั้งหมดเพื่อเป็นข้อมูลอ้างอิง
- azimuth
- border-collapse
- border-spacing
- caption-side
- color
- cursor
- direction
- empty-cells
- font-family
- font-size
- font-style
- font-variant
- font-weight
- font
- letter-spacing
- line-height
- list-style-image
- list-style-position
- list-style-type
- list-style
- orphans
- quotes
- text-align
- text-indent
- text-transform
- visibility
- white-space
- widows
- word-spacing
วิธีการทํางานของการรับช่วง
องค์ประกอบ HTML ทุกรายการจะมีพร็อพเพอร์ตี้ CSS ทั้งหมดที่กําหนดไว้โดยค่าเริ่มต้นด้วยค่าเริ่มต้น ค่าเริ่มต้นคือพร็อพเพอร์ตี้ที่ไม่ได้รับค่ามาและแสดงเป็นค่าเริ่มต้นหากแคสเคดคำนวณค่าสำหรับองค์ประกอบนั้นไม่สำเร็จ
พร็อพเพอร์ตี้ที่รับค่ามาได้โดยสืบทอดจะส่งต่อค่าไปยังองค์ประกอบย่อย และองค์ประกอบย่อยจะได้รับค่าที่คำนวณแล้วซึ่งแสดงถึงค่าขององค์ประกอบหลัก
ซึ่งหมายความว่าหากองค์ประกอบหลักตั้งค่า 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>
จะอัปเดตตามค่า CSS นั้นโดยอัตโนมัติ
คีย์เวิร์ด 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