Áp dụng các kiểu CSS cho một phần tử tùy thuộc vào các phần tử con của nó


203

Có thể xác định kiểu CSS cho một phần tử, chỉ được áp dụng nếu phần tử phù hợp chứa một phần tử cụ thể (dưới dạng mục con trực tiếp)?

Tôi nghĩ rằng điều này được giải thích tốt nhất bằng cách sử dụng một ví dụ.

Lưu ý : Tôi đang cố gắng tạo kiểu cho phần tử cha , tùy thuộc vào phần tử con nào chứa.

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

Lưu ý 2 : Tôi biết tôi có thể đạt được điều này bằng cách sử dụng javascript, nhưng tôi chỉ tự hỏi liệu điều này có khả thi khi sử dụng một số tính năng CSS không xác định (với tôi) không.


1
Bạn có thể muốn cập nhật câu hỏi thành trạng thái, có lẽ với dòng chữ in đậm nhấp nháy, rằng bạn đang cố gắng tạo kiểu cho div PARENT chứ không phải con của nó. Tôi biết rằng thông tin nằm trong chính câu hỏi, nhưng trừ khi bạn muốn nhận được rất nhiều câu trả lời không chính xác thì có lẽ nó đáng để bạn nỗ lực.
Seth Petry-Johnson

Cảm ơn @Seth. Tôi đã cố gắng cải thiện tiêu đề câu hỏi và văn bản. Vui lòng chỉnh sửa câu hỏi nếu bạn nghĩ nó vẫn chưa rõ ràng.
M4N


Đây là ví dụ hoàn hảo về lý do tại sao loại hỗ trợ này trong CSS sẽ lý tưởng: 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; }Trong một thế giới lý tưởng, điều này sẽ làm tăng biên độ olphụ thuộc vào số lượng litrẻ em được chứa để lề bên trái chỉ rộng bằng nó cần thiết để được
Jonmark Weber 8/12/2015

Câu trả lời:


124

Theo như tôi biết, việc tạo kiểu cho phần tử cha dựa trên phần tử con không phải là một tính năng có sẵn của CSS. Bạn có thể sẽ cần kịch bản cho việc này.

Thật tuyệt vời nếu bạn có thể làm điều gì đó như div[div.a]hoặc div:containing[div.a]như bạn đã nói, nhưng điều này là không thể.

Bạn có thể muốn xem xét nhìn vào jQuery . Bộ chọn của nó hoạt động rất tốt với các loại 'chứa'. Bạn có thể chọn div, dựa trên nội dung con của nó và sau đó áp dụng lớp CSS cho tất cả cha mẹ trong một dòng.

Nếu bạn sử dụng jQuery, một cái gì đó dọc theo dòng này có thể hoạt động (chưa được kiểm tra nhưng lý thuyết là có):

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

hoặc là

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

kết hợp với lớp CSS:

.redBorder
{
    border: 1px solid red;
}

Đây là tài liệu cho bộ chọn "có" jQuery .


15
Lưu ý bên lề: để có hiệu suất tốt hơn, trang tài liệu jQuery cho :hasbộ chọn khuyên nên sử dụng .has()phương thức ( api.jquery.com/has ) => áp dụng cho câu hỏi hiện tại, ví dụ$('div').has('div.a').css('border', '1px solid red');
Frosty Z

Để làm việc này, người ta sẽ phải sử dụng trình quan sát đột biến, để kiểm tra xem đứa trẻ có thay đổi trạng thái không ...
Huyền thoại

Điều này không thực sự trả lời cho câu hỏi "Có cách nào để làm điều này với CSS". Nó nêu rõ: "Tôi biết tôi có thể đạt được điều này bằng cách sử dụng javascript, nhưng tôi chỉ tự hỏi liệu điều này có khả thi khi sử dụng một số tính năng CSS không xác định (với tôi) không."
SunshinyDoyle

developer.mozilla.org/en-US/docs/Web/CSS/:has , tôi nghĩ rằng :hasbộ chọn này có thể hoạt động nhưng nó ở phiên bản nháp và không có trình duyệt nào hỗ trợ nó.
AliF50 ngày

62

Về cơ bản, không. Sau đây sẽ là những gì bạn đã theo sau trong lý thuyết:

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

Thật không may, nó không tồn tại.

Có một vài bài viết dọc theo dòng chữ "tại sao không phải là địa ngục". Shaun Inman cũng là một người rất giỏi:

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


34
chỉ là bản cập nhật 8 năm sau: vẫn không có hỗ trợ cho phương pháp chọn này.
Kraang Prime

1
Có một bản nháp hoạt động cho tính năng này dưới dạng một :has()lớp giả, nhưng chúng ta sẽ chỉ sử dụng nó trong CSS4. Đến bây giờ (cuối năm 2019), JS vẫn là cách duy nhất để đạt được chức năng này.
zepp.lee

Tôi tin rằng điều này sẽ không kích hoạt kiểu css, nó vẫn sẽ cần javascript để sử dụng bộ chọn. Trừ khi điều này đã thay đổi?
Justin Wignall

3
9 năm và họ có nghĩ rằng tính năng này là không cần thiết?
Lợi Nguyễn Huỳnh

1

Trên đầu câu trả lời của @ kp:

Tôi đang xử lý vấn đề này và trong trường hợp của tôi, tôi phải hiển thị phần tử con và sửa chiều cao của đối tượng cha mẹ cho phù hợp (tự động kích thước không hoạt động trong tiêu đề bootstrap vì một số lý do tôi không có thời gian để gỡ lỗi) .

Nhưng thay vì sử dụng javascript để sửa đổi cha mẹ, tôi nghĩ rằng tôi sẽ tự động thêm một lớp CSS cho cha mẹ và CSS hiển thị một cách có chọn lọc các con tương ứng. Điều này sẽ duy trì các quyết định theo logic và không dựa trên trạng thái CSS.

tl; dr; áp dụng abphong cách cho cha mẹ <div>, không phải đứa trẻ (tất nhiên, không phải ai cũng có thể làm điều này. tức là các thành phần Angular đưa ra quyết định của riêng mình).

<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

Trong trường hợp của tôi, tôi đã phải thay đổi phần đệm của một phần tử có chứa hộp kiểm đầu vào cho một bảng được kết xuất động với DataTables:

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

Sau khi triển khai mã dòng sau trong hàm initComplete, tôi có thể tạo ra phần đệm chính xác, giúp cố định các hàng không được hiển thị với chiều cao lớn bất thường

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

Bây giờ, bạn có thể thấy rằng các kiểu chính xác đang được áp dụng cho phần tử cha:

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

Về cơ bản, câu trả lời này là phần mở rộng của câu trả lời của @ KP, nhưng càng hợp tác thực hiện điều này thì càng tốt. Tóm lại, tôi hy vọng điều này sẽ giúp người khác vì nó hoạt động! Cuối cùng, cảm ơn bạn rất nhiều @KP đã dẫn dắt tôi đi đúng hướng!

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.