วันนี้ ผมคิดอะไรออกบางอย่าง เป็นกรณีเส้นขนบังภูเขาไฟ ชนิดที่เรียกได้ว่า ผมน่าจะคิดพบตั้งนานแล้ว ได้แต่นั่ง งงๆ ในความโง่ของตัวเอง เลยเอามาเขียนไว้ตรงนี้อีกที
เหตุการณ์ที่ว่านี้คือ การสั่ง element ใดใด ที่เป็น child element ยกเว้น child ตัวที่ 1
เช่นว่า เราแบ่งเนื้อหาออกเป็น คอลัมน์ แล้วเราต้องการขีดเส้นกั้นเอาไว้ แต่ ถ้าเราสั่ง border เช่น border-left เข้าไปตรงๆ นั้น มันจะทำให้ เกิด เส้นขอบขึ้นที่ ด้านซ้ายสุดของกล่องข้อมูลด้วย เราจำเป็นต้องหาทางลบเส้นขอบมันออกไป โดยที่ยังคงความเป็น semantic ของ html เอาไว้ให้ได้มากที่สุด
เมื่อครั้งเก่าก่อน เราอาจจะเขียน class ขึ้นมา 1 class ซื่อว่า .none-border {border: none;} แล้วเอาไปใส่ ใน element ตัวแรกที่เกิดเส้นขอบขึ้น เพื่อลบเส้นขอบออกไปแทน แต่เกิดคำถามขึ้นว่า ทำไม เราต้องไปเพิ่ม ค่าให้กับ Attribute class นั้น โดยที่ชื่อ class ไม่ได้แสดงออกถึงการสื่อสารด้าน เนื้อหา ข่าวสารในความเป็น Semantic web ของภาษาเลย
ซึ่งหน้าที่เหล่านี้ โดยความรับผิดชอบแล้ว มันอยู่ที่ภาษา CSS ไม่ใช่ HTML
มาดูกันว่า เราจะลบเส้นขอบด้านซ้ายของ คอลัมน์แรกออกไปได้ยังไง โดยที่ไม่ใส่ class เพื่อสั่งลบเส้นขอบออกไป
ตัวอย่างโครงสร้าง HTML ผมขอใช้ ตัวอย่างนี้นะครับ
<h2>...</h2>
<ul>
<li><article>
...
</article></li>
<li><article>
...
</article></li>
<li><article>
...
</article></li>
<li><article>
...
</article></li>
</ul>
โดยที่ CSS นั้น เราสามารถเขียนได้หลากหลายรูปแบบ ผมขอยอกมา 4 แบบ นะครับ
ก่อนที่จะ เริ่มกับคำอธิบาย ให้คลิ๊กไปดูตัวอย่างการเขียน CSS เพื่อสั่งงาน Child Element กันก่อนครับ
ตามตัวอย่างนั้น Code CSS ผมเขียนไว้ ประมาณนี้
/*สั่งทุก Article ยกเว้น article ตัวแรกสุด โดย li+li*/
.ตัวอย่างที่หนึ่ง>h2+ul>li+li>article {
border-left: dotted 1px #7C7C7C;
}
/*สั่งทุก Article */
.ตัวอย่างที่สอง>h2+ul>li>article {
border-left: dotted 1px #7C7C7C;
}
.ตัวอย่างที่สอง>h2+ul>li:first-child>article {/*remove เส้นขอบด้านซ้าย*/
border-left: none;
}
/*สั่งทุก Article ยกเว้น article ตัวแรกสุด โดย :not()*/
.ตัวอย่างที่สาม>h2+ul>li:not(:first-child)>article {
border-left: dotted 1px #7C7C7C;
}
/**/
.ตัวอย่างที่สี่>h2+ul>li:not(:nth-child(4n+1))>article {
border-left: dotted 1px #7C7C7C;
}
มาไล่ดูคำอธิบายกัน
แบบที่ 1
/*สั่งทุก Article ยกเว้น article ตัวแรกสุด โดย li+li*/
.ตัวอย่างที่หนึ่ง>h2+ul>li+li>article {
border-left: dotted 1px #7C7C7C;
}
ul>li+li
ให้สังเกตที่ li+li นะครับ ซึ่งหมายถึงว่า li ที่อยู่ถัดไปจาก li ตัวก่อนหน้าอยู่ 1 ตัว
ซึ่งทั้งหมดเป็น child ของ ul
ซึ่งการเขียนแบบนี้เอง จะมี li อยู่หนึ่งตัว ที่ไม่ถูกนำหน้าด้วย element ใดๆ ทั้งสิ้น นั่นคือ li ตัวแรก นั่นเอง
การเขียน Selector แบบนี้จึงสามารถข้ามการสั่ง li ตัวที่หนึ่งไปได้
** การเขียน CSS แบบนี้นี่เองที่ผม เพิ่งคิดพบ จึงได้เอามาเขียนไว้ตรงนี้ครับ
แบบที่ 2
/*สั่งทุก Article */
.ตัวอย่างที่สอง>h2+ul>li>article {
border-left: dotted 1px #7C7C7C;
}
.ตัวอย่างที่สอง>h2+ul>li:first-child>article {/*remove เส้นขอบด้านซ้าย*/
border-left: none;
}
ul>li และ ul>li:first-child
ในขั้นแรก ทำการสั่ง ul>li ไปแล้ว นั่นหมายความว่า ให้กระทำการกับ li ที่เป็นลูกของ ul ในทุกๆ ตัว
แต่เมื่อเราไม่ต้องการให้ li ตัวแรกแสดงผลเหมือน li ตัวอื่นๆ เราจึงจำเป็นต้อง เขียน Selector ขึ้นมาอีก 1 ชุด เพื่อลบค่าคำสั่งที่ถูกสั่งไปแล้ว
ซึ่งนั่นก็คือ ul>li:first-child ที่จำเป็นต้องทำแบบนี้ เพราะ IE7 ก็สามารถใช้งานได้ด้วย เพราะว่า IE7 นั้น รู้จัก :first-child
แบบที่ 3
/*สั่งทุก Article ยกเว้น article ตัวแรกสุด โดย :not()*/
.ตัวอย่างที่สาม>h2+ul>li:not(:first-child)>article {
border-left: dotted 1px #7C7C7C;
}
ul>li:not(:first-child)
หมายความว่า li ทุกตัว ที่ไม่ใช่ (:not(x)) ในที่นี้ ค่าที่อยู่ใน :not() นั้น ผมนำ :first-child ไปใส่
จึงหมายความว่า ทุกตัว ที่ไม่ใช่ ตัวแรก
ซึ่ง Selector ชุดนี้ ถือเป็นชุดที่ใช้งานได้หลากหลายแง่มุมมากที่สุด แต่ตอนนี้ ตระกูล IE มีแค่ IE9 เท่านั้นที่สามารถใช้ได้
แบบที่ 4
.ตัวอย่างที่สี่>h2+ul>li:not(:nth-child(4n+1))>article {
border-left: dotted 1px #7C7C7C;
}
ul>li:not(:nth-child(4n+1))
หมายความว่า li ทุกตัว ที่ไม่ใช่ (:not(x)) ในที่นี้ ค่าที่อยู่ใน :not() นั้น ผมนำ :nth-child(4n+1) ไปใส่
4n+1 นั้นหมายความว่า li ทั้งหมด 4 ตัว ให้นับจาก ตัวแรกไป ซึ่งจะตรงข้ามกับ 4n-1 นั่นจะหมายความว่า ให้นับจากตัวสุดท้าย ย้อนกลับมา
เมื่อนำมาใส่กับ :not() แล้วจึงหมายความว่า li ทั้ง 4 ตัว (ย้ำว่า ทั้ง 4 ตัวนะครับ) ที่ไม่ใช่ ตัวที่1
ตอนนี้ ตระกูล IE มีแค่ IE9 เท่านั้นที่สามารถใช้ได้
คลิ๊กไปดูตัวอย่างการเขียน CSS เพื่อสั่งงาน Child Element อีกครั้งครับ
สำหรับการนำไปใช้งานแล้ว ก็ อยู่ที่แต่ละคนนะครับ จะนำไปประยุกต์ใช้งานกันยังไงได้บ้าง
มีความสุขกับการใช้ชีวิตครับ
One Response to การเขียน CSS Selectors เพื่อสั่งงาน HTML Child Element