アクティブな子の親の複雑な CSS セレクター [重複]
-
09-06-2019 - |
質問
この質問にはすでに答えがあります:
- CSSの親セレクターはありますか? 28 件の回答
クラス内の子要素のクラスに基づいて親要素を選択する方法はありますか?素敵なメニュープラグインによるHTML出力に関連する私に関連する例 http://drupal.org. 。出力は次のようにレンダリングされます。
<ul class="menu">
<li>
<a class="active">Active Page</a>
</li>
<li>
<a>Some Other Page</a>
</li>
</ul>
私の質問は、アクティブなクラスを持つアンカーを含むリスト項目にスタイルを適用できるかどうかです。もちろん、リスト項目がアクティブとしてマークされている方が望ましいのですが、生成されるコードを制御することはできません。JavaScript (JQuery が思い浮かびます) を使用してこの種のことを実行できますが、CSS セレクターを使用してこれを実行する方法があるかどうか疑問に思っていました。
明確にしておきたいのは、アンカーではなくリスト項目にスタイルを適用したいということです。
解決
残念ながら、CSS でそれを行う方法はありません。
ただし、JavaScript を使用する場合はそれほど難しくありません。
// JavaScript code:
document.getElementsByClassName("active")[0].parentNode;
// jQuery code:
$('.active').parent().get(0); // This would be the <a>'s parent <li>.
他のヒント
セレクターは上昇できません
CSS には、特定の基準を満たす要素の親または祖先を選択する方法がありません。より高度なセレクター スキーム (XPath など) を使用すると、より洗練されたスタイルシートが可能になります。ただし、CSS ワーキング グループが親セレクターの提案を拒否した主な理由は、ブラウザーのパフォーマンスと増分レンダリングの問題に関連しています。
そして、将来 SO を検索する人にとって、これは祖先セレクターとも呼ばれる可能性があります。
アップデート:
の セレクター レベル 4 仕様 選択内容のどの部分を対象にするかを選択できます。
セレクターの主題は、セレクター内の複合セレクターの1つにドル記号($)を準備することにより、明示的に識別できます。セレクターが表す要素構造はドル記号の有無にかかわらず同じですが、このようにして被験者がその構造の主題を表す化合物セレクターを変えることができることを示します。
例 1:
たとえば、次のセレクターは、順序付けられたリストのリストアイテムliユニークな子を表します。
OL > LI:only-child
ただし、次のものは、ユニークな子供を持つ順序付けられたリストを表しています。その子供はliです。
$OL > LI:only-child
これら2つのセレクターで表される構造は同じですが、セレクターの主題はそうではありません。
ただし、これはどのブラウザーでも、jQuery のセレクターとしても使用できません (現在、2011 年 11 月)。
またまたパーティーに遅れましたが、jQuery を使用するともう少し簡潔に表現することができます。私の場合、それを見つける必要がありました <ul>
の親タグ <span>
子に含まれるタグ <li>
. 。jQueryには :has
セレクターを使用すると、含まれる子によって親を識別できるようになります (@Afrowave のコメント参照に従って更新されました: https://api.jquery.com/has-selector/):
$("ul").has("#someId")
を選択します ul
id を持つ子要素を持つ要素 いくつかのID. 。または、元の質問に答えるには、次のようなものがうまくいくはずです (未テスト)。
$("li").has(".active")
「親」セレクター
現時点では、CSS (CSS3 でも) には要素の親を選択するオプションがありません。しかし、 CSS4, 、現在の W3C ドラフトで最も重要なニュースは、親セレクターのサポートです。
$ul li:hover{
background: #fff;
}
上記を使用すると、リスト要素にカーソルを置くと、白い背景が追加されて順序なしリスト全体が強調表示されます。
公式ドキュメント: https://www.w3.org/TR/2011/WD-selectors4-20110929/#overview (最後の行)。
の最初の草案 セレクター レベル 4 を明示的に設定する方法の概要を説明します。 主題 セレクターの。これにより、OP がセレクターを使用してリスト要素をスタイル設定できるようになります。 $li > a.active
から セレクターのサブジェクトの決定:
たとえば、次のセレクターは、順序付きリスト OL の一意の子リスト項目 LI を表します。
OL > LI:only-child
ただし、次のリストは、一意の子を持つ順序付きリスト OL を表しており、その子は LI です。
$OL > LI:only-child
これら 2 つのセレクターによって表される構造は同じですが、セレクターの主題は異なります。
編集:草案仕様がどれほど「草案」であるかを考えると、 セレクター レベル 4 に関する CSSWG のページ.
CSS4セレクターによる将来の答え
新しい CSS 仕様には実験的なものが含まれています :has
これを実行できる可能性のある疑似セレクター。
li:has(a:active) {
/* ... */
}
の ブラウザのサポート 現時点では基本的には存在しませんが、検討中です。 公式スペック.
2012 年の答えは 2012 年に間違っており、2018 年にはさらに間違っています。
CSS が ASCEND できないのは事実ですが、別の要素の親要素を取得できないのは間違いです。繰り返しますが、
HTML サンプルコードを使用すると、li を指定せずに li を取得できます。
ul * a {
property:value;
}
この例では、ul はある要素の親であり、その要素はアンカーの親です。このメソッドを使用する欠点は、アンカーを含む子要素を持つ ul がある場合、指定されたスタイルを継承することです。
いずれにしても親要素を指定する必要があるため、子セレクターを使用することもできます。
ul>li a {
property:value;
}
この例では、アンカーは ul の子でなければならない li の子孫でなければなりません。つまり、アンカーは ul 宣言に続くツリー内になければなりません。これはもう少し具体的で、アンカーを含み、かつ ul の子であるリスト項目のみを取得します。
それで、あなたの質問にコードで答えます。
ul.menu > li a.active {
property:value;
}
これにより、menu クラスの ul と、active クラスのアンカーのみを含む子リスト項目が取得されます。
Drupalでも同じ問題がありました。CSS の制限を考慮すると、これを機能させる方法は、メニュー HTML の生成時に親要素に「アクティブ」クラスを追加することです。これについては、次の場所で良い議論が行われています http://drupal.org/node/219804, その結果、この機能は nicemenus モジュールのバージョン 6.x ~ 2.x に組み込まれました。これはまだ開発中であるため、パッチを 6.x-1.3 にバックポートしました。 http://drupal.org/node/465738 これにより、モジュールの実稼働対応バージョンを引き続き使用できるようになります。
多くの人がこう答えました jQuery
親ですが、それにさらに付け加えるために、ナビゲーションにクラスを追加するために使用するコードの簡単なスニペットを共有したいと思いました。これにより、スタイルを追加できるようになります li
サブメニューのみがあり、サブメニューはありません li
それは違います。
$("li ul").parent().addClass('has-sub');
実際、元の投稿者と同じ問題に遭遇しました。を使用するだけの簡単な解決策があります .parent()
jQueryセレクター。私の問題は、私が使用していた .parent
の代わりに .parent()
. 。愚かな間違いはわかっています。
イベントをバインドします(この場合、タブがモーダルにあるため、それらをバインドする必要がありました) .live
基本の代わりに .click
.
$('#testTab1 .tabLink').live('click', function() {
$('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
$(this).parent().addClass("current"); //Add "current" class to selected tab
$('#modal div#testTab1 .tabContent').hide();
$(this).next('.tabContent').fadeIn();
return false;
})
$('#testTab2 .tabLink').live('click', function() {
$('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
$(this).parent().addClass("current"); //Add "current" class to selected tab
$('#modal div#testTab2 .tabContent').hide();
$(this).next('.tabContent').fadeIn();
return false;
})
ここに HTML があります。
<div id="tabView1" style="display:none;">
<!-- start: the code for tabView 1 -->
<div id="testTab1" style="width:1080px; height:640px; position:relative;">
<h1 class="Bold_Gray_45px">Modal Header</h1>
<div class="tabBleed"></div>
<ul class="tabs">
<li class="current"> <a href="#" class="tabLink" id="link1">Tab Title Link</a>
<div class="tabContent" id="tabContent1-1">
<div class="modalCol">
<p>Your Tab Content</p>
<p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
</div>
<div class="tabsImg"> </div>
</div>
</li>
<li> <a href="#" class="tabLink" id="link2">Tab Title Link</a>
<div class="tabContent" id="tabContent1-2">
<div class="modalCol">
<p>Your Tab Content</p>
<p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
</div>
<div class="tabsImg"> </div>
</div>
</li>
</ul>
</div>
</div>
もちろん、LI を増やしてそのパターンを繰り返すこともできます。
純粋な CSS ソリューションである可能性のある別の考えが今頭に浮かびました。アクティブなクラスを絶対位置ブロックとして表示し、親 li を隠すようにそのスタイルを設定します。
a.active {
position:absolute;
display:block;
width:100%;
height:100%;
top:0em;
left:0em;
background-color: whatever;
border: whatever;
}
/* will also need to make sure the parent li is a positioned element so... */
ul.menu li {
position:relative;
}
jqueryを使わずにjavascriptを使いたい人のために...
親を選択するのは簡単です。あなたには必要だ getElementsByClass
Drupal プラグインを取得してアクティブなアイテムにクラスではなく ID を割り当てることができない限り、ある種の関数となります。私が提供した関数は、SO の他の天才から譲り受けたものです。これはうまく機能しますが、デバッグするときは、この関数は単一のノードだけではなく、常にノードの配列を返すことに注意してください。
active_li = getElementsByClass("active","a");
active_li[0].parentNode.style.whatever="whatever";
function getElementsByClass(node,searchClass,tag) {
var classElements = new Array();
var els = node.getElementsByTagName(tag); // use "*" for all elements
var elsLen = els.length;
var pattern = new RegExp("\\b"+searchClass+"\\b");
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}