Đây là một trong những ví dụ nổi tiếng nhất về các tác giả hiểu lầm cách thức hoạt động của
/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
0. Được giới thiệu trong CSS2, lớp giả ____1010 đại diện cho đứa con đầu lòng của cha mẹ. Đó là nó. Có một quan niệm sai lầm rất phổ biến rằng nó chọn bất kỳ phần tử con nào là người đầu tiên phù hợp với các điều kiện được chỉ định bởi phần còn lại của bộ chọn hợp chất. Do cách các bộ chọn hoạt động [xem ở đây để giải thích], điều đó chỉ đơn giản là không đúng.the very first child of its parent. That's it. There's a very common misconception that it picks up whichever child element is the first to match the conditions specified by the rest of the compound selector.
Due to the way selectors work [see here for an explanation], that is simply not true.Các bộ chọn Cấp 3 giới thiệu một lớp giả
/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
2, đại diện cho yếu tố đầu tiên trong số các anh chị em thuộc loại phần tử của nó. Câu trả lời này giải thích, với hình minh họa, sự khác biệt giữa ____10 và /*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
2. Tuy nhiên, như với /*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
0, nó không xem xét bất kỳ điều kiện hoặc thuộc tính nào khác. Trong HTML, loại phần tử được biểu diễn bằng tên thẻ. Trong câu hỏi, loại đó là /*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
6.Thật không may, không có lớp giả tương tự
/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
7 để phù hợp với yếu tố con đầu tiên của một lớp nhất định. Vào thời điểm câu trả lời này được đăng lần đầu tiên, FPWD mới được xuất bản của Bộ chọn cấp 4 đã giới thiệu một lớp giả /*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
8, được thiết kế xung quanh cơ học chọn hiện tại như tôi đã đề cập trong đoạn đầu tiên bằng cách thêm một đối số danh sách chọn, qua đó bạn có thể cung cấp Phần còn lại của bộ chọn hợp chất để có được hành vi lọc mong muốn. Trong những năm gần đây, chức năng này đã được đặt vào chính /*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
9, với danh sách bộ chọn xuất hiện dưới dạng đối số thứ hai tùy chọn, để đơn giản hóa mọi thứ cũng như ngăn chặn ấn tượng sai mà /*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
8 phù hợp trên toàn bộ tài liệu [xem ghi chú cuối cùng bên dưới].Mặc dù chúng tôi đang chờ hỗ trợ trình duyệt chéo [nghiêm túc, đã gần 10 năm và chỉ có một triển khai duy nhất trong 5 năm qua], một cách giải quyết mà Lea Verou và tôi đã phát triển độc lập [cô ấy đã làm điều đó trước tiên!] Để áp dụng các kiểu mong muốn của bạn cho tất cả các yếu tố của bạn với lớp đó:
/*
* Select all .red children of .home, including the first one,
* and give them a border.
*/
.home > .red {
border: 1px solid red;
}
... Sau đó, "hoàn tác" các kiểu cho các phần tử với lớp đến sau cái đầu tiên, sử dụng bộ kết hợp anh chị em chung
.home > .red {
border: 1px solid red;
}
.home > .red ~ .red {
border: none;
}
1 trong một quy tắc ghi đè:/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
Bây giờ chỉ có yếu tố đầu tiên với
.home > .red {
border: 1px solid red;
}
.home > .red ~ .red {
border: none;
}
2 sẽ có biên giới.Đây là một minh họa về cách áp dụng các quy tắc:
.home > .red {
border: 1px solid red;
}
.home > .red ~ .red {
border: none;
}
blah
first
second
third
fourth
Không có quy tắc nào được áp dụng; Không có biên giới được hiển thị. Yếu tố này không có lớp
3, vì vậy nó đã bị bỏ qua..home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
This element does not have the class
3, so it's skipped..home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
Chỉ có quy tắc đầu tiên được áp dụng; Một đường viền màu đỏ được hiển thị. Yếu tố này có lớp
3, nhưng nó không đi trước bất kỳ yếu tố nào với lớp.home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
3 trong cha mẹ của nó. Do đó, quy tắc thứ hai không được áp dụng, chỉ có nguyên tố thứ nhất và phần tử giữ đường viền của nó..home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
This element has the class
3, but it's not preceded by any elements with the class.home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
3 in its parent. Thus the second rule is not applied, only the first, and the element keeps its border..home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
Cả hai quy tắc đều được áp dụng; Không có biên giới được hiển thị. Yếu tố này có lớp
3. Nó cũng được đi trước bởi ít nhất một yếu tố khác với lớp.home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
3. Do đó, cả hai quy tắc đều được áp dụng và tuyên bố.home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
8 thứ hai ghi đè lên thứ nhất, do đó "hoàn tác" nó, có thể nói..home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
This element has the class
3. It is also preceded by at least one other element with the class.home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
3. Thus both rules are applied, and the second.home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
8 declaration overrides the first, thereby "undoing" it, so to speak..home > .red { border: 1px solid red; } .home > .red ~ .red { border: none; }
Như một phần thưởng, mặc dù nó được giới thiệu trong Bộ chọn 3, nhưng tổ hợp anh chị em chung thực sự được IE7 và mới hơn, không giống như
/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
2 và
blah
first
second
third
fourth
0 chỉ được IE9 trở đi hỗ trợ. Nếu bạn cần hỗ trợ trình duyệt tốt, bạn sẽ gặp may.Trên thực tế, thực tế là bộ kết hợp anh chị em là thành phần quan trọng duy nhất trong kỹ thuật này và nó có sự hỗ trợ của trình duyệt tuyệt vời như vậy, làm cho kỹ thuật này rất linh hoạt - bạn có thể điều chỉnh nó để lọc các yếu tố bởi những thứ khác, bên cạnh các bộ chọn lớp:
Bạn có thể sử dụng điều này để làm việc xung quanh
2 trong IE7 và IE8, chỉ bằng cách cung cấp một bộ chọn loại thay vì bộ chọn lớp [một lần nữa, nhiều hơn về việc sử dụng không chính xác trong câu hỏi trong phần sau]:/* * Select all but the first .red child of .home, * and remove the border from the previous rule. */ .home > .red ~ .red { border: none; }
article > p { /* Apply styles to article > p:first-of-type, which may or may not be :first-child */ } article > p ~ p { /* Undo the above styles for every subsequent article > p */ }
Bạn có thể lọc theo bộ chọn thuộc tính hoặc bất kỳ bộ chọn đơn giản nào khác thay vì các lớp.
Bạn cũng có thể kết hợp kỹ thuật ghi đè này với các yếu tố giả mặc dù các yếu tố giả về mặt kỹ thuật không phải là bộ chọn đơn giản.
Lưu ý rằng để điều này hoạt động, bạn sẽ cần biết trước các kiểu mặc định sẽ là gì cho các yếu tố anh chị em khác của bạn để bạn có thể ghi đè quy tắc đầu tiên. Ngoài ra, vì điều này liên quan đến việc ghi đè các quy tắc trong CSS, bạn không thể đạt được điều tương tự với một bộ chọn duy nhất để sử dụng với API bộ chọn hoặc trình định vị CSS của Selenium.
Trên một lưu ý cuối cùng, hãy nhớ rằng câu trả lời này giả định rằng câu hỏi đang tìm kiếm bất kỳ số lượng yếu tố con đầu lòng nào có một lớp nhất định. Không có một giải pháp CSS giả cũng không phải là giải pháp CSS chung cho trận đấu thứ n của bộ chọn phức tạp trên toàn bộ tài liệu-liệu một giải pháp có tồn tại hay không phụ thuộc nhiều vào cấu trúc tài liệu. JQuery cung cấp
blah
first
second
third
fourth
2,
blah
first
second
third
fourth
3,
blah
first
second
third
fourth
4 và nhiều hơn nữa cho mục đích này, nhưng lưu ý rằng chúng hoạt động rất khác với /*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
9 et al. Sử dụng API của Bộ chọn, bạn có thể sử dụng
blah
first
second
third
fourth
6 để có được trận đấu đầu tiên:var first = document.querySelector['.home > .red'];
Hoặc sử dụng
blah
first
second
third
fourth
7 với trình chỉ mục để chọn bất kỳ trận đấu cụ thể nào:var redElements = document.querySelectorAll['.home > .red'];
var first = redElements[0];
var second = redElements[1];
// etc
Mặc dù giải pháp
blah
first
second
third
fourth
8 trong câu trả lời được chấp nhận ban đầu của Philip Daubmeier Works [ban đầu được viết bởi Martyn nhưng bị xóa kể từ đó], nhưng nó không hoạt động theo cách bạn mong đợi.Ví dụ: nếu bạn chỉ muốn chọn
/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
6 ở đây:
... Sau đó, bạn không thể sử dụng
article > p {
/* Apply styles to article > p:first-of-type, which may or may not be :first-child */
}
article > p ~ p {
/* Undo the above styles for every subsequent article > p */
}
0 [tương đương với
blah
first
second
third
fourth
8], bởi vì mỗi phần tử là loại đầu tiên [và duy nhất] một trong loại [/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
6 và article > p {
/* Apply styles to article > p:first-of-type, which may or may not be :first-child */
}
article > p ~ p {
/* Undo the above styles for every subsequent article > p */
}
3 tương ứng], vì vậy cả hai sẽ được bộ chọn khớp.Khi yếu tố đầu tiên của một lớp nhất định cũng là loại đầu tiên của loại, lớp giả sẽ hoạt động, nhưng điều này chỉ xảy ra bởi sự trùng hợp. Hành vi này được thể hiện trong câu trả lời của Philip. Thời điểm bạn dán trong một phần tử cùng loại trước phần tử này, bộ chọn sẽ thất bại. Lấy đánh dấu từ câu hỏi:this happens only by coincidence. This behavior is demonstrated in Philip's answer. The moment you stick in an element of the same type before this element, the selector will fail. Taking the markup from the question:
blah
first
second
third
fourth
Áp dụng một quy tắc với
article > p {
/* Apply styles to article > p:first-of-type, which may or may not be :first-child */
}
article > p ~ p {
/* Undo the above styles for every subsequent article > p */
}
0 sẽ hoạt động, nhưng một khi bạn thêm một /*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
6 khác mà không có lớp:
blah
dummy
first
second
third
fourth
... Bộ chọn sẽ ngay lập tức thất bại, vì phần tử
article > p {
/* Apply styles to article > p:first-of-type, which may or may not be :first-child */
}
article > p ~ p {
/* Undo the above styles for every subsequent article > p */
}
6 đầu tiên hiện là phần tử /*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
6 thứ hai.