ใช้สไตล์ CSS กับองค์ประกอบขึ้นอยู่กับองค์ประกอบย่อย


203

เป็นไปได้หรือไม่ที่จะกำหนดสไตล์ CSS สำหรับองค์ประกอบที่จะใช้เฉพาะเมื่อองค์ประกอบที่ตรงกันมีองค์ประกอบเฉพาะ (เป็นรายการลูกโดยตรง)

ฉันคิดว่านี่เป็นคำอธิบายที่ดีที่สุดโดยใช้ตัวอย่าง

หมายเหตุ : ฉันกำลังพยายามจัดองค์ประกอบองค์ประกอบหลักขึ้นอยู่กับองค์ประกอบลูกที่มี

<style>
  /* note this is invalid syntax. I'm using the non-existing
   ":containing" pseudo-class to show what I want to achieve. */
  div:containing div.a { border: solid 3px red; }
  div:containing div.b { border: solid 3px blue; }
</style>

<!-- the following div should have a red border because
     if contains a div with class="a" -->
<div>
  <div class="a"></div>
</div>

<!-- the following div should have a blue border -->
<div>
  <div class="b"></div>
</div>

หมายเหตุ 2 : ฉันรู้ว่าฉันสามารถทำสิ่งนี้ได้โดยใช้ javascript แต่ฉันก็สงสัยว่ามันเป็นไปได้หรือไม่โดยใช้คุณสมบัติ CSS (สำหรับฉัน) ที่ไม่รู้จัก


1
คุณอาจต้องการอัปเดตคำถามให้ระบุด้วยการกระพริบข้อความที่เป็นตัวหนาซึ่งคุณกำลังพยายามกำหนดสไตล์ของผู้ปกครองไม่ใช่ลูก ๆ ฉันรู้ว่าข้อมูลอยู่ในคำถาม แต่ถ้าคุณไม่ต้องการคำตอบที่ไม่ถูกต้องมันอาจคุ้มค่ากับความพยายาม
Seth Petry-Johnson

ขอบคุณ @ เซท ฉันพยายามปรับปรุงชื่อคำถามและข้อความ โปรดแก้ไขคำถามหากคุณคิดว่ายังไม่ชัดเจน
M4N

3
มีความเป็นไปได้ที่ซ้ำกันของตัวเลือก CSS parent มีอะไรบ้าง?
James Donnelly

นี่เป็นตัวอย่างที่สมบูรณ์แบบว่าทำไมการสนับสนุนประเภทนี้ใน CSS จึงเป็นอุดมคติ: ol < li:nth-child(n+10) { margin-left: 2rem; } ol < li:nth-child(n+100) { margin-left: 3rem; } ol < li:nth-child(n+1000) { margin-left: 4rem; }ในโลกอุดมคตินี้จะเพิ่มระยะขอบของการolพึ่งพาจำนวนliเด็กที่อยู่ในนั้นเพื่อที่ระยะขอบซ้ายจะกว้างเท่า จำเป็นต้องเป็น
Jonmark Weber

คำตอบ:


124

เท่าที่ฉันทราบการจัดองค์ประกอบองค์ประกอบหลักตามองค์ประกอบย่อยนั้นไม่ใช่คุณลักษณะที่มีอยู่ของ CSS คุณอาจต้องเขียนสคริปต์สำหรับสิ่งนี้

มันจะยอดเยี่ยมถ้าคุณสามารถทำสิ่งที่ชอบdiv[div.a]หรือdiv:containing[div.a]ตามที่คุณพูด แต่มันเป็นไปไม่ได้

คุณอาจต้องการที่จะต้องพิจารณามองหาที่jQuery ตัวเลือกมันทำงานได้ดีกับประเภท 'ที่มี' คุณสามารถเลือก div ตามเนื้อหาย่อยจากนั้นใช้คลาส CSS กับพาเรนต์ทั้งหมดในหนึ่งบรรทัด

หากคุณใช้ jQuery มีบางสิ่งในสายของสิ่งนี้อาจใช้ได้ (ยังไม่ทดลอง แต่มีทฤษฎีอยู่):

$('div:has(div.a)').css('border', '1px solid red');

หรือ

$('div:has(div.a)').addClass('redBorder');

รวมกับคลาส CSS:

.redBorder
{
    border: 1px solid red;
}

นี่คือเอกสารสำหรับjQuery "ได้" ตัวเลือก


15
หมายเหตุด้านข้าง: เพื่อประสิทธิภาพที่ดีขึ้นหน้าเอกสาร jQuery สำหรับ:hasตัวเลือกแนะนำให้ใช้.has()วิธีการ ( api.jquery.com/has ) => นำไปใช้กับคำถามปัจจุบันที่จะให้ตัวอย่างเช่น$('div').has('div.a').css('border', '1px solid red');
Frosty Z

สำหรับสิ่งนี้ในการทำงานอย่างใดอย่างหนึ่งจะต้องใช้ผู้สังเกตการณ์การกลายพันธุ์เพื่อตรวจสอบว่าเด็กเปลี่ยนเป็นรัฐ ...
Legends

สิ่งนี้ไม่ตอบคำถามที่แท้จริงซึ่งมี "มีวิธีทำด้วย CSS" หรือไม่ มันระบุอย่างชัดเจนว่า: "ฉันรู้ว่าฉันสามารถทำสิ่งนี้ได้โดยใช้จาวาสคริปต์ แต่ฉันแค่สงสัยว่ามันเป็นไปได้หรือไม่โดยใช้คุณสมบัติ CSS ที่ไม่รู้จัก (สำหรับฉัน)"
SunshinyDoyle

developer.mozilla.org/en-US/docs/Web/CSS/:hasฉันคิดว่า:hasตัวเลือกนี้สามารถใช้งานได้ แต่มันเป็นแบบร่างและไม่มีเบราว์เซอร์ที่รองรับ
AliF50

62

โดยทั่วไปไม่มี ต่อไปนี้จะเป็นสิ่งที่คุณตามมาในทางทฤษฎี:

div.a < div { border: solid 3px red; }

น่าเสียดายที่มันไม่มีอยู่จริง

มีการเขียนไม่กี่รายการตามแนว "ทำไมถึงไม่นรก" คนที่มีเนื้อดีโดย Shaun Inman นั้นค่อนข้างดี:

http://www.shauninman.com/archive/2008/05/05/css_qualified_selectors


34
แค่อัปเดต 8 ปีต่อมา: ยังไม่มีวิธีการสนับสนุนสำหรับตัวเลือกนี้
Kraang Prime

1
มีร่างการทำงานสำหรับคุณลักษณะนี้ในรูปแบบของ:has()คลาสหลอก แต่เราจะใช้มันใน CSS4 เท่านั้น ณ ตอนนี้ (ปลายปี 2562) JS ยังคงเป็นวิธีเดียวที่จะบรรลุการทำงานนี้
zepp.lee

ฉันเชื่อว่านี่จะไม่เปิดใช้งานรูปแบบ css แต่ยังคงต้องใช้จาวาสคริปต์เพื่อใช้ตัวเลือก ถ้าสิ่งนี้มีการเปลี่ยนแปลง?
Justin Wignall

3
9 ปีและพวกเขาคิดว่าคุณสมบัตินี้ไม่มีความจำเป็นหรือไม่?
Loi Nguyen Huynh

1

ด้านบนของคำตอบของ @ kp:

ฉันกำลังจัดการกับสิ่งนี้และในกรณีของฉันฉันต้องแสดงองค์ประกอบลูกและแก้ไขความสูงของวัตถุแม่ตามลำดับ (การปรับขนาดอัตโนมัติไม่ทำงานในส่วนหัว bootstrap ด้วยเหตุผลบางอย่างที่ฉันไม่มีเวลาแก้ไขปัญหา) .

แต่แทนที่จะใช้ javascript เพื่อปรับเปลี่ยนพาเรนต์ฉันคิดว่าฉันจะเพิ่มคลาส CSS ลงในพาเรนต์แบบไดนามิกและแสดงแบบย่อยตามลำดับ สิ่งนี้จะรักษาการตัดสินใจในตรรกะและไม่ขึ้นกับสถานะ CSS

TL; DR; ใช้aและbสไตล์กับผู้ปกครอง<div>ไม่ใช่เด็ก (แน่นอนว่าไม่ใช่ทุกคนจะสามารถทำสิ่งนี้ได้เช่นองค์ประกอบเชิงมุมในการตัดสินใจของตัวเอง)

<style>
  .parent            { height: 50px; }
  .parent div        { display: none; }
  .with-children     { height: 100px; }
  .with-children div { display: block; }
</style>

<div class="parent">
  <div>child</div>
</div>

<script>
  // to show the children
  $('.parent').addClass('with-children');
</script>

0

ในกรณีของฉันฉันต้องเปลี่ยนการเติมเซลล์ขององค์ประกอบที่มีช่องทำเครื่องหมายอินพุตสำหรับตารางที่แสดงผลแบบไดนามิกด้วย DataTables:

<td class="dt-center">
    <input class="a" name="constCheck" type="checkbox" checked="">
</td>

หลังจากติดตั้งโค้ดบรรทัดต่อไปนี้ภายในฟังก์ชั่นinitCompleteฉันสามารถสร้างช่องว่างที่ถูกต้องซึ่งแก้ไขแถวจากการแสดงด้วยความสูงขนาดใหญ่ผิดปกติ

 $('tbody td:has(input.a)').css('padding', '0px');

ตอนนี้คุณจะเห็นว่าสไตล์ที่ถูกต้องถูกนำไปใช้กับองค์ประกอบหลัก:

<td class=" dt-center" style="padding: 0px;">
    <input class="a" name="constCheck" type="checkbox" checked="">
</td>

โดยพื้นฐานแล้วคำตอบนี้เป็นส่วนเสริมของคำตอบของ @ KP แต่ยิ่งความร่วมมือในการดำเนินการนี้ยิ่งดี ในการสรุปฉันหวังว่าสิ่งนี้จะช่วยให้คนอื่นเพราะมันใช้งานได้! สุดท้ายนี้ขอขอบคุณ @KP สำหรับการนำฉันไปในทิศทางที่ถูกต้อง!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.