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
- สี
- เคอร์เซอร์
- ทิศทาง
- empty-cells
- font-family
- font-size
- font-style
- font-variant
- font-weight
- แบบอักษร
- letter-spacing
- line-height
- list-style-image
- list-style-position
- list-style-type
- list-style
- orphans
- คำคม
- text-align
- text-indent
- text-transform
- ระดับการแชร์
- white-space
- บรรทัดสุดท้าย
- 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>
จะอัปเดตตามโดยอัตโนมัติ
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;
}
revert
คีย์เวิร์ด
ดังที่ได้เรียนรู้ในบทเรียนเกี่ยวกับการเรียงซ้อน สไตล์มาจากแหล่งที่มาต่างๆ ได้แก่ สไตล์พื้นฐานของ User Agent, สไตล์ที่ผู้ใช้กำหนด และสไตล์ที่คุณสร้างขึ้น คีย์เวิร์ด revert
จะยกเลิกรูปแบบที่ตั้งค่าไว้ในต้นทางเดียวกันกับที่ใช้คีย์เวิร์ด revert
ซึ่งจะมีประโยชน์เมื่อคุณตั้งค่าสไตล์ไว้แล้ว แต่ไม่ต้องการให้ใช้ในบางอินสแตนซ์ แม้ว่า inherit
, initial
และ unset
จะระบุวิธีคำนวณค่าของสไตล์ แต่ revert
จะระบุเพียงว่าสไตล์อื่นๆ ที่คุณเขียนจะไม่มีผล
p {
padding: 2em;
}
aside p {
padding: revert;
}
ข้อมูลโค้ดนี้จะให้ระยะห่างภายในแก่องค์ประกอบ <p>
แต่เมื่อองค์ประกอบ <p>
อยู่ภายใน <aside>
จะไม่มีการระบุ padding
เลย แต่จะเปลี่ยนกลับไปเป็นสไตล์ค่ากำหนดของผู้ใช้ (หากมีการตั้งค่าไว้) หรือสไตล์พื้นฐานของ User Agent
revert-layer
คีย์เวิร์ด
เลเยอร์ Cascade เป็นวิธีที่มีประโยชน์ในการจัดระเบียบสไตล์ และจัดลำดับความสำคัญของสไตล์ภายในต้นทางของผู้เขียนของ Cascade revert-layer
คีย์เวิร์ดคล้ายกับ revert
แต่แทนที่จะระบุว่าไม่ควรใช้สไตล์ผู้เขียนใดๆ กับพร็อพเพอร์ตี้ คีย์เวิร์ดนี้จะยกเลิกสไตล์ในเลเยอร์ปัจจุบันเท่านั้น
หากคุณใช้ไลบรารี UI ของบุคคลที่สาม รูปแบบที่มีประโยชน์คือการนำเข้าไลบรารีลงในเลเยอร์ และเพิ่มการลบล้างลงในเลเยอร์ที่มีลำดับความสำคัญสูงกว่า จากนั้นคุณสามารถนำการลบล้างออกได้โดยใช้ revert-layer
และระบบจะใช้ค่าเริ่มต้นของไลบรารี UI แทน
หากเลเยอร์อื่นๆ ไม่ได้ระบุค่าสำหรับพร็อพเพอร์ตี้ดังกล่าว พร็อพเพอร์ตี้จะทำงานเหมือน revert
และใช้ค่าจากต้นทางก่อนหน้า
ทดสอบความเข้าใจ
ทดสอบความรู้เกี่ยวกับการรับค่า
พร็อพเพอร์ตี้ใดต่อไปนี้จะรับค่าโดยค่าเริ่มต้น
animation
font-size
color
text-align
line-height
ค่าใดที่ทำงานเหมือน inherit
เว้นแต่จะไม่มีอะไรให้รับช่วงและ
จากนั้นจะทำงานเหมือน initial
reset
unset
superset