CSS สามารถตรวจจับจำนวนของลูก ๆ ที่องค์ประกอบมีได้หรือไม่?


304

ฉันอาจตอบคำถามของฉันเอง แต่ฉันอยากรู้อยากเห็นอย่างมาก

ฉันรู้ว่า CSS สามารถเลือกเด็กแต่ละคนของผู้ปกครอง แต่มีการสนับสนุนในการกำหนดรูปแบบเด็กของภาชนะถ้าผู้ปกครองที่มีจำนวนเด็ก

ตัวอย่างเช่น

container:children(8) {
  // style the parent this way if there are 8 children
}

ฉันรู้ว่ามันฟังดูแปลก แต่ผู้จัดการของฉันขอให้ฉันตรวจสอบมันไม่พบอะไรด้วยตัวเองฉันเลยตัดสินใจหันไปหา SO ก่อนที่จะจบการค้นหา


2
การสืบค้นปริมาณ SCSS Mixin: codepen.io/jakob-e/pen/wgGpeP
Jakob E

คำตอบ:


695

ชี้แจง:

เนื่องจากมีการใช้ถ้อยคำก่อนหน้าในคำถามเดิมประชาชน SO จึงมีความกังวลว่าคำตอบนี้อาจทำให้เข้าใจผิด โปรดทราบว่าใน CSS3 ไม่สามารถใช้สไตล์กับโหนดพาเรนต์ตามจำนวนลูกที่มี อย่างไรก็ตามสไตล์สามารถนำไปใช้กับโหนดลูกขึ้นอยู่กับจำนวนของพี่น้องพวกเขามี


คำตอบเดิม:

เหลือเชื่อตอนนี้เป็นไปได้อย่างหมดจดใน CSS3

/* one item */
li:first-child:nth-last-child(1) {
/* -or- li:only-child { */
    width: 100%;
}

/* two items */
li:first-child:nth-last-child(2),
li:first-child:nth-last-child(2) ~ li {
    width: 50%;
}

/* three items */
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
    width: 33.3333%;
}

/* four items */
li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li {
    width: 25%;
}

เคล็ดลับคือการเลือกลูกคนแรกเมื่อมันยังเป็นลูกที่ n- จาก - ล่าสุด สิ่งนี้จะเลือกอย่างมีประสิทธิภาพตามจำนวนพี่น้อง

เครดิตสำหรับเทคนิคนี้ไปที่AndréLuís (ค้นพบ) & Lea Verou (ปรับปรุง)

คุณไม่รัก CSS3 หรือเปล่า 😄

ตัวอย่าง CodePen:

แหล่งที่มา:


7
มีประโยชน์มาก ฉันเขียน SASS mixin ที่ใช้เทคนิคนี้: codepen.io/anon/pen/pJeLdE?editors=110
SimpleJ

1
@IanSteffy ฉันเพิ่งทดสอบสิ่งนี้บน Chrome 45.0.2454.85 (64 บิต) และใช้งานได้ดี ...
Matthemattics

2
ถ้ามันทำงานได้ใน codepen แต่ไม่ใช่กับโครงการของฉันมันเป็นความผิดของฉันแน่นอนที่สุด ความผิดฉันเอง. คำตอบนี้ถูกต้อง! ถูกต้องฉันพูด!
Ian S

3
อาจเป็นการดีที่จะเพิ่มว่าทำไมสิ่งนี้ถึงได้ผลสำหรับคนที่ไม่คุ้นเคยกับตัวเลือกหลอกหลายคน (เช่นฉันจนถึงตอนนี้) สิ่งที่เกิดขึ้นที่นี่คือการเลือกเด็กที่อยู่ในเวลาเดียวกันเด็ก x จากจุดเริ่มต้น / บนและเด็ก y จากจุดสิ้นสุด และนี่จะเลือกอะไรบางอย่างถ้ามีเด็ก ๆ x + y ทุกคน
เลโกลัส

7
หมายเหตุว่าแทนที่จะคุณยังสามารถใช้:first-child:nth-last-child(1) :only-child
Adam Reis

40

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

:only-child

นี่:only-childเป็นหนึ่งในตัวเลือกการนับที่แท้จริงไม่กี่ตัวในแง่ที่ว่าจะใช้เฉพาะเมื่อมีลูกหนึ่งคนขององค์ประกอบหลัก ใช้ตัวอย่างในอุดมคติของคุณมันทำหน้าที่เหมือนchildren(1)อาจจะ

:nth-child

:nth-childเลือกจริงอาจได้รับคุณที่คุณต้องการไปขึ้นอยู่กับสิ่งที่คุณต้องการจริงๆที่จะทำ หากคุณต้องการจัดองค์ประกอบทั้งหมดหากมีเด็ก 8 คนคุณโชคไม่ดี อย่างไรก็ตามหากคุณต้องการใช้สไตล์กับองค์ประกอบที่ 8 และใหม่กว่าลองสิ่งนี้:

p:nth-child( n + 8 ){
    /* add styles to make it pretty */
}

น่าเสียดายที่สิ่งเหล่านี้อาจไม่ใช่โซลูชันที่คุณต้องการ ในท้ายที่สุดคุณอาจต้องใช้ตัวช่วยสร้าง Javascript เพื่อใช้สไตล์ตามจำนวน - แม้ว่าคุณจะใช้สิ่งเหล่านี้คุณจะต้องดูความเข้ากันได้ของเบราว์เซอร์อย่างละเอียดก่อนที่จะใช้งานจริง โซลูชัน CSS

W3 CSS3 ข้อมูลจำเพาะเกี่ยวกับคลาส pseudo

แก้ไขฉันอ่านคำถามของคุณแตกต่างกันเล็กน้อย - มีวิธีอื่นอีกสองวิธีในการจัดรูปแบบผู้ปกครองไม่ใช่เด็ก ให้ฉันโยนตัวเลือกอื่น ๆ สองสามอย่างในแบบของคุณ:

:empty และ :not

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

div:not(:empty) {
    /* We know it has stuff in it! */
}

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


มันน่าสังเกตว่าคำถามเดิมได้รับการแก้ไขแล้วเรนเดอร์เริ่มต้นว่า "ไม่" ทำให้เข้าใจผิดเล็กน้อย (แค่ fyi 😛)
Matthemattics

18

หมายเหตุ: วิธีนี้จะคืนค่าชุดของความยาวที่แน่นอนไม่ใช่องค์ประกอบหลักตามที่คุณถาม หวังว่ามันจะมีประโยชน์

Andre Luis มาพร้อมกับวิธีการ: http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/แต่น่าเสียดายที่มันใช้ได้ใน IE9 ขึ้นไปเท่านั้น

โดยพื้นฐานแล้วคุณจะรวม: nth-child () กับคลาสหลอกอื่น ๆ ที่จัดการกับตำแหน่งขององค์ประกอบ วิธีการนี้จะช่วยให้คุณสามารถระบุองค์ประกอบจากชุดขององค์ประกอบที่มีความยาวที่เฉพาะเจาะจง

ตัวอย่างเช่น:nth-child(1):nth-last-child(3)ตรงกับองค์ประกอบแรกในชุดในขณะที่ยังเป็นองค์ประกอบที่ 3 จากจุดสิ้นสุดของชุด สิ่งนี้ทำสองสิ่ง: รับประกันว่าชุดจะมีสามองค์ประกอบเท่านั้นและเรามีหนึ่งในสามรายการแรก :nth-child(2):nth-last-child(2)เพื่อระบุองค์ประกอบที่สองของชุดองค์ประกอบที่สามที่เราต้องการใช้


ตัวอย่างที่ 1 - เลือกองค์ประกอบรายการทั้งหมดถ้าชุดมีองค์ประกอบสามอย่าง:

li:nth-child(1):nth-last-child(3),
li:nth-child(2):nth-last-child(2),
li:nth-child(3):nth-last-child(1) {
    width: 33.3333%;
}

ตัวอย่างที่ 1 ทางเลือกจาก Lea Verou:

li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
    width: 33.3333%;
}


ตัวอย่างที่ 2 - กำหนดเป้าหมายองค์ประกอบสุดท้ายของชุดด้วยองค์ประกอบรายการสามรายการ:

li:nth-child(3):last-child {
    /* I'm the last of three */
}

ตัวอย่างที่ 2 ทางเลือก:

li:nth-child(3):nth-last-child(1) {
    /* I'm the last of three */
}


ตัวอย่าง 3 - องค์ประกอบที่สองเป้าหมายของชุดที่มีองค์ประกอบรายการสี่:

li:nth-child(2):nth-last-child(3) {
    /* I'm the second of four */
}

1
อีกครั้งนี่คือจำนวนพี่น้องไม่ใช่เด็ก
TMS

@TMS ดูการแก้ไขคำตอบที่ยอมรับ - คำถามของ OP นั้นถูกแปลอย่างเชื่องช้า
ifugu

วิธีนี้เหมาะสำหรับเมื่อแต่ละองค์ประกอบจะต้องมีสไตล์แตกต่างกันไปตามตำแหน่งในรายการเช่นเพื่อให้ได้การแปลงแบบวงกลม: li:nth-child(3):nth-last-child(1) { transform: rotate(120deg); } li:nth-child(2):nth-last-child(2) { transform: rotate(240deg); }และอื่น ๆ ...
Greg Smith

11

เมื่อใช้วิธีการแก้ปัญหาของ Matt ฉันใช้การใช้เข็มทิศ / SCSS ต่อไปนี้

@for $i from 1 through 20 {
    li:first-child:nth-last-child( #{$i} ),
    li:first-child:nth-last-child( #{$i} ) ~ li {
      width: calc(100% / #{$i} - 10px);
    }
  }

สิ่งนี้ช่วยให้คุณสามารถขยายจำนวนรายการได้อย่างรวดเร็ว


4
แทนที่จะนี้คุณได้อย่างง่ายดายสามารถใช้ flexbox ...
Michał Miszczyszyn

6

ใช่เราสามารถทำได้โดยใช้ลูกคนที่ชอบ

div:nth-child(n + 8) {
    background: red;
}

สิ่งนี้จะทำให้ลูก div ที่ 8 เป็นต้นไปกลายเป็นสีแดง หวังว่านี่จะช่วย ...

นอกจากนี้หากใครบางคนเคยพูดว่า "เฮ้พวกเขาไม่สามารถทำได้ด้วยสไตล์โดยใช้ CSS ใช้ JS !!!" สงสัยพวกเขาทันที CSS มีความยืดหยุ่นอย่างมากในปัจจุบัน

ตัวอย่าง :: http://jsfiddle.net/uWrLE/1/

ในตัวอย่างเด็ก 7 คนแรกเป็นสีน้ำเงินจากนั้น 8 คนเป็นต้นไปจะเป็นสีแดง ...


1
บางทีเพิ่มบันทึกเกี่ยวกับการขาดการสนับสนุนโชคร้าย?
benesch

2
ฉันไม่คิดว่านี่เป็นสิ่งที่ Brodie ขอมา - สิ่งนี้จะจัดสไตล์เด็กตามจำนวนที่กำหนด แต่ไม่สามารถเลือกองค์ประกอบ / บรรพบุรุษที่มีอยู่ตามจำนวนของเด็ก ๆ
เบ็นฮัลล์

นี่เป็นข้อมูลที่ค่อนข้างดี แต่ขอบคุณอลัน แต่ผึ้งถูกต้องฉันพยายามพูดว่า "ถ้าองค์ประกอบมีเด็กจำนวนมากที่เรามีรูปแบบนี้" ถ้าฉันไม่ผิดวิธีการของคุณจะทำให้เด็กคนที่ 8 อยู่ แต่ 7 แรกจะเหงาและเปลือยเปล่า
Brodie

@primatology - เบราว์เซอร์เดียวที่ไม่รองรับ nth-child คือ IE <9 คนอื่น ๆ ทั้งหมดได้รับการสนับสนุนเป็นสองรุ่นขึ้นไป
Rob

-1 สิ่งนี้จะไม่ทำให้ลูก divสีแดงสิ่งนี้จะทำให้ div สีแดงตามจำนวนของมันภายในพี่น้อง ! ไม่เกี่ยวข้องกับลูกของ div แต่อย่างใด!
TMS

5

หากคุณกำลังจะทำมันด้วย CSS บริสุทธิ์ (โดยใช้ scss) แต่คุณมีองค์ประกอบ / คลาสที่แตกต่างกันภายในคลาสพาเรนต์เดียวกันคุณสามารถใช้เวอร์ชันนี้ได้ !!

  &:first-of-type:nth-last-of-type(1) {
    max-width: 100%;
  }

  @for $i from 2 through 10 {
    &:first-of-type:nth-last-of-type(#{$i}),
    &:first-of-type:nth-last-of-type(#{$i}) ~ & {
      max-width: (100% / #{$i});
    }
  }

-1

ไม่ไม่มีอะไรใน CSS อย่างไรก็ตามคุณสามารถใช้ JavaScript เพื่อคำนวณจำนวนลูกและใช้สไตล์ได้


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