CSS có thể phát hiện số lượng con mà một phần tử có không?


304

Có lẽ tôi đang trả lời câu hỏi của riêng mình, nhưng tôi cực kỳ tò mò.

Tôi biết rằng CSS có thể chọn từng con của một cha mẹ, nhưng có hỗ trợ để tạo kiểu cho các con của một container không, nếu bố mẹ của nó có một số lượng con nhất định.

ví dụ

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

Tôi biết điều này nghe có vẻ kỳ lạ, nhưng người quản lý của tôi đã yêu cầu tôi kiểm tra, tôi không tìm thấy bất cứ điều gì một mình nên tôi quyết định chuyển sang SO trước khi kết thúc tìm kiếm.


2
Số lượng truy vấn SCSS Mixin: codepen.io/jakob-e/pen/wgGpeP
Jakob E

Câu trả lời:


695

Làm rõ:

Do một cụm từ trước đó trong câu hỏi ban đầu, một số công dân SO đã đưa ra quan ngại rằng câu trả lời này có thể gây hiểu nhầm. Lưu ý rằng, trong CSS3, các kiểu không thể được áp dụng cho nút cha dựa trên số lượng con mà nó có. Tuy nhiên, kiểu có thể được áp dụng cho các nút con dựa trên số anh chị em họ có.


Câu trả lời gốc:

Thật đáng kinh ngạc, điều này bây giờ hoàn toàn có thể có trong 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%;
}

Bí quyết là chọn đứa trẻ đầu tiên khi nó cũng là đứa trẻ thứ n. Điều này lựa chọn hiệu quả dựa trên số lượng anh chị em.

Tín dụng cho kỹ thuật này được chuyển đến André Luís (được phát hiện) & Lea Verou (tinh chế).

Không phải bạn chỉ thích CSS3 sao? 😄

Ví dụ về CodePen:

Nguồn:


7
Rất tiện dụng. Tôi đã viết một mixin SASS sử dụng kỹ thuật này: codepen.io/anon/pen/pJeLdE?editors=110
SimpleJ

1
@IanSteffy Tôi mới thử nghiệm điều này trên Chrome 45.0.2454,85 ​​(64-bit) và nó hoạt động tốt?
Matthemattics

2
Nếu nó hoạt động trong codepen nhưng không phải với dự án của tôi thì đó chắc chắn là lỗi của tôi. Lỗi của tôi. Câu trả lời này là chính xác! Đúng rồi, tôi nói!
Ian S

3
Có thể tốt hơn để thêm lý do tại sao điều này hoạt động, cho những người không quen với nhiều bộ chọn giả (như tôi cho đến bây giờ;). Điều đang xảy ra ở đây là việc này chọn đứa trẻ đồng thời là con x từ đầu / đầu và con y từ cuối. Và vì vậy, điều này chỉ chọn một cái gì đó nếu có chính xác con x + y.
Legolas

7
Lưu ý rằng thay vì :first-child:nth-last-child(1)bạn cũng có thể sử dụng :only-child.
Adam Reis

40

Không, không thực sự. Có một vài công cụ chọn có thể giúp bạn gần gũi hơn, nhưng có lẽ sẽ không hoạt động trong ví dụ của bạn và không có khả năng tương thích trình duyệt tốt nhất.

:only-child

Đây :only-childlà một trong số ít các bộ chọn đếm thực sự theo nghĩa là nó chỉ được áp dụng khi có một phần tử con của phần tử. Sử dụng ví dụ lý tưởng hóa của bạn, nó hoạt động như children(1)có thể sẽ.

:nth-child

Công :nth-childcụ chọn thực sự có thể đưa bạn đến nơi bạn muốn đến tùy thuộc vào những gì bạn thực sự muốn làm. Nếu bạn muốn tạo kiểu cho tất cả các yếu tố nếu có 8 đứa trẻ, bạn sẽ không gặp may. Tuy nhiên, nếu bạn muốn áp dụng kiểu cho các phần tử thứ 8 trở đi, hãy thử điều này:

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

Thật không may, đây có lẽ không phải là giải pháp bạn đang tìm kiếm. Cuối cùng, có lẽ bạn sẽ cần sử dụng một số thuật sĩ Javascript để áp dụng các kiểu dựa trên số đếm - ngay cả khi bạn đã sử dụng một trong số các kiểu này, bạn cần phải xem xét kỹ khả năng tương thích của trình duyệt trước khi sử dụng thuần túy Giải pháp CSS.

W3 CSS3 Spec trên các lớp giả

EDIT Tôi đọc câu hỏi của bạn một chút khác nhau - có một vài cách khác để tạo kiểu cho cha mẹ , không phải cho trẻ em. Hãy để tôi ném một vài bộ chọn khác theo cách của bạn:

:empty:not

Phong cách này yếu tố không có con. Bản thân nó không hữu ích, nhưng khi được ghép nối với :notbộ chọn, bạn chỉ có thể tạo kiểu cho các thành phần có con:

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

Bạn không thể đếm được có bao nhiêu trẻ em có sẵn CSS thuần túy ở đây, nhưng đây là một công cụ chọn thú vị khác cho phép bạn làm những điều tuyệt vời.


Đáng chú ý là câu hỏi ban đầu đã được chỉnh sửa, khiến "Không" ban đầu hơi sai lệch (chỉ fyi)
Matthemattics

18

LƯU Ý: Giải pháp này sẽ trả về các phần tử con có độ dài nhất định, không phải phần tử cha như bạn đã yêu cầu. Hy vọng, nó vẫn hữu ích.

Andre Luis đã đưa ra một phương pháp: http://lea.verou.me/2011/01/stomme-children-basing-on-their-number-with-css3/ Thật không may, nó chỉ hoạt động trong IE9 trở lên.

Về cơ bản, bạn kết hợp: nth-child () với các lớp giả khác liên quan đến vị trí của một phần tử. Cách tiếp cận này cho phép bạn chỉ định các phần tử từ các bộ phần tử với độ dài cụ thể .

Chẳng hạn, :nth-child(1):nth-last-child(3)khớp với phần tử đầu tiên trong một tập hợp đồng thời là phần tử thứ 3 từ cuối tập hợp. Điều này thực hiện hai điều: đảm bảo rằng tập hợp chỉ có ba yếu tố và chúng ta có yếu tố đầu tiên trong ba yếu tố. Để chỉ định phần tử thứ hai của bộ ba phần tử, chúng tôi sẽ sử dụng :nth-child(2):nth-last-child(2).


Ví dụ 1 - Chọn tất cả các thành phần danh sách nếu bộ có ba thành phần:

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%;
}

Ví dụ 1 thay thế từ Lea Verou:

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


Ví dụ 2 - mục tiêu phần tử cuối cùng của tập hợp với ba phần tử danh sách:

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

Ví dụ 2 thay thế:

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


Ví dụ 3 - phần tử thứ hai đích của tập hợp với bốn phần tử danh sách:

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

1
một lần nữa, đây là số anh chị em, không phải trẻ em
TMS

@TMS thấy chỉnh sửa câu trả lời được chấp nhận - câu hỏi của OP đã được đặt ra một cách vụng về
ifugu

Cách tiếp cận này là hoàn hảo khi mỗi yếu tố cần được tạo kiểu khác nhau dựa trên vị trí của nó trong danh sách, ví dụ để có được các phép biến đổi tròn: li:nth-child(3):nth-last-child(1) { transform: rotate(120deg); } li:nth-child(2):nth-last-child(2) { transform: rotate(240deg); }v.v ...
Greg Smith

11

Làm việc với giải pháp của Matt, tôi đã sử dụng triển khai La bàn / SCSS sau đây.

@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);
    }
  }

Điều này cho phép bạn nhanh chóng mở rộng số lượng mặt hàng.


4
Thay vì điều này, bạn có thể dễ dàng sử dụng Flexbox
Michał Miszczyszyn

6

vâng, chúng tôi có thể làm điều này bằng cách sử dụng nth-child như vậy

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

Điều này sẽ làm cho div thứ 8 trở đi trở thành màu đỏ. Hi vọng điêu nay co ich...

Ngoài ra, nếu ai đó từng nói "này, họ không thể thực hiện được bằng cách sử dụng css, hãy sử dụng JS !!!" nghi ngờ họ ngay lập tức. CSS cực kỳ linh hoạt hiện nay

Thí dụ :: http://jsfiddle.net/uWrLE/1/

Trong ví dụ, 7 đứa trẻ đầu tiên có màu xanh lam, sau đó 8 đứa có màu đỏ ...


1
Có lẽ thêm một lưu ý về sự thiếu hỗ trợ đáng tiếc ?
benesch

2
Tôi không nghĩ rằng đây chính xác là những gì Brodie đang hỏi - điều này sẽ tạo kiểu cho trẻ em sau một số tiền nhất định, nhưng không thể chọn yếu tố tổ tiên / chứa dựa trên số lượng con của nó.
Ben Hull

Đây thực sự là một số thông tin khá tốt, cảm ơn alan nhưng ong đã đúng, tôi đã cố gắng nói "nếu một yếu tố có nhiều trẻ em theo kiểu này" Nếu tôi không nhầm thì phương pháp của bạn sẽ tạo kiểu cho đứa trẻ thứ 8, nhưng 7 đầu tiên sẽ cô đơn và trần trụi.
Brodie

@primatology - Trình duyệt duy nhất không hỗ trợ con thứ n là IE <9. Tất cả những người khác đã hỗ trợ nó hai phiên bản trở lên.
Cướp

-1 Điều này sẽ không làm cho div con màu đỏ, điều này sẽ làm cho div màu đỏ dựa trên số của nó trong anh chị em của nó ! Không liên quan đến con của div theo bất kỳ cách nào!
TMS

5

Nếu bạn định làm điều đó bằng CSS thuần túy (sử dụng scss) nhưng bạn có các thành phần / lớp khác nhau trong cùng một lớp cha, bạn có thể sử dụng phiên bản này !!

  &: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

Không, không có gì như thế này trong CSS. Tuy nhiên, bạn có thể sử dụng JavaScript để tính số lượng trẻ em và áp dụng các kiểu.


1
@ Lzignah Bạn có thể giải thích tại sao nó không đúng?
Gabriel Santos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.