I got a document that is built like the following code:
<div id="menubox_container_box_body">
<div class="categories">...</div>
<div class="categories">
<div class="cat_icon">...</div>
<div class="cat_link">
<div class="cat_link_container">...</div>
<div class="cat_icon">...</div>
<div class="cat_sub_link">
<div class="cat_link_container">...</div>
</div>
<div class="cat_icon">...</div>
<div class="cat_sub_link">
<div class="cat_link_container">...</div>
</div>
</div>
Now I am trying to select the a in the first cat_link_container with this command:
#menubox_categories_box_body .categories:nth-child(2) .cat_link .cat_link_container:nth-child(1){
margin-bottom: 20px;
}
What it does is giving ALL the cat_link_container elements (even the one's in the cat_sub_link div) a margin bottom. But I selected to only take the FIRST cat_link_container in cat_link and give it a margin-bottom. Someone has an idea what the problem could be?
To select only the element with class='cat_link_container' under div class='cat_link' and not the elements with same class under its descendants, you need to make use of the > (children) selector like in the below code sample:
#menubox_container_box_body .categories:nth-child(2) .cat_link > .cat_link_container:nth-child(1){
color: red;
font-size: 24px;
}
<div id="menubox_container_box_body">
<div class="categories">...</div>
<div class="categories">
<div class="cat_icon">...</div>
<div class="cat_link">
<div class="cat_link_container">...</div>
<div class="cat_icon">...</div>
<div class="cat_sub_link">
<div class="cat_link_container">...</div>
</div>
<div class="cat_icon">...</div>
<div class="cat_sub_link">
<div class="cat_link_container">...</div>
</div>
</div>
</div>
</div>
Explanation:
Your original selector would be interpreted as follows:
#menubox_container_box_body .categories:nth-child(2) .cat_link .cat_link_container:nth-child(1)
Find the element with id='menubox_container_box_body'.
Under this element, find all descendant elements (children, grand-children etc) which are the 2nd child of its parent and also has class='categories'.
Under all the elements obtained in the previous point, find the element with class='cat_link'
Traverse all elements which are fetched in above point, find all descendant elements which are the 1st child of its own parent and also has class='cat_link_container'.
<div id="menubox_container_box_body"> <!-- 1st point in explanation -->
<div class="categories">...</div>
<div class="categories"> <!-- 2nd point in explanation -->
<div class="cat_icon">...</div>
<div class="cat_link"> <!-- 3rd point in explanation -->
<div class="cat_link_container">...</div> <!-- descendant, first-child of its parent and so selected -->
<div class="cat_icon">...</div>
<div class="cat_sub_link">
<div class="cat_link_container">...</div> <!-- descendant of the element referenced by 3rd point, first-child of its own parent and so selected -->
</div>
<div class="cat_icon">...</div>
<div class="cat_sub_link">
<div class="cat_link_container">...</div> <!-- descendant of the element referenced by 3rd point, first-child of its own parent and so selected -->
</div>
</div>
</div>
</div>
The revised selector that I have provided in answer will be interpreted as follows:
#menubox_container_box_body .categories:nth-child(2) .cat_link > .cat_link_container:nth-child(1)
Find the element with id='menubox_container_box_body'.
Under this element, find all descendant elements (children, grand-children etc) which are the 2nd child of its parent and also has class='categories'.
Under all the elements obtained in the previous point, find the element with class='cat_link'
Traverse all elements which are fetched in above point, find the element which is the 1st child of its the element referred to by point 3 and also has class='cat_link_container'. Note how it checks only for direct child and not descendants.
<div id="menubox_container_box_body"> <!-- 1st point in explanation -->
<div class="categories">...</div>
<div class="categories"> <!-- 2nd point in explanation -->
<div class="cat_icon">...</div>
<div class="cat_link"> <!-- 3rd point in explanation -->
<div class="cat_link_container">...</div> <!-- direct child, first-child of its parent and so selected -->
<div class="cat_icon">...</div>
<div class="cat_sub_link">
<div class="cat_link_container">...</div> <!-- not direct link and hence not selected -->
</div>
<div class="cat_icon">...</div>
<div class="cat_sub_link">
<div class="cat_link_container">...</div> <!-- not direct link and hence not selected -->
</div>
</div>
</div>
</div>
Related
I have the following situations:
<div class="content">
<div class="background">
...
</div>
</div>
<div class="indicators"></div>
<div class="overlay">...</div>
<div class="border speaking">
<div class="content">
<div class="background">
...
</div>
</div>
<div class="indicators"></div>
<div class="overlay">...</div>
<div class="border">
I would like to select the background div in the former example, but not the latter. The only difference between the two is the presence of the speaking class on the final div.
I tried .content:not( ~ .border:not(.speaking) ) > .background, but this did not work. I am on Firefox Developer Edition, and as such do not currently have access to :has.
Thanks in advance!
Suppose I have a block of code that looks like this.
<div class="lv1">
<div class="lv2">
<div class="img">
</div>
<div id="text-on-image"> // <-- I want to grab this div element.
</div>
</div>
<div class="lv2">
</div>
</div>
Now I have $(this).eq(0) which refers to the root div element.
<div class="lv1"> //<-- $(this).eq(0) is here.
<div class="lv2">
<div class="img">
</div>
<div id="text-on-image">
</div>
</div>
<div class="lv2">
</div>
</div>
$(this).eq(0).children().eq(0) now refers to first div of lv2 class div.
<div class="lv1">
<div class="lv2"> // <-- $(this).eq(0).children().eq(0) is here
<div class="img">
</div>
<div id="text-on-image">
</div>
</div>
<div class="lv2">
</div>
</div>
$(this).eq(0).children().eq(0).children().eq(1) now refers to the correct div I want.
<div class="lv1">
<div class="lv2">
<div class="img">
</div>
<div id="text-on-image"> // <-- $(this).eq(0).children().eq(0).children().eq(1) is here
</div>
</div>
<div class="lv2">
</div>
</div>
Notice how the selecting child node became very messy for my code.
"$(this).eq(0).children().eq(0).children().eq(1)"
Is there a better way to go about doing the same work?
Use:
$("#parent").find(".children") for all children (deep traverse)
or:
$("#parent").children(".children") for immediate children
Since you use an ID, and an ID must be unique - simply use $("#text-on-image")
Otherwise, use the .find() Method.
If you used id, you can select it right away.
$("#text-on-image")
id must be unique, so if you use class, you can use ".find()"
$(".lv1").find(".text-on-image")
If no id or class is specified, selectors can be used.
$(".lv1 > .lv2 > div:nth-child(2)")
I have certain divs like this
<div>
<div class="parent">
<div class="child">child1</div>
<div class="child">child2</div>
<div class="child">child3</div>
<div class="child">child4</div>
<div class="child">child5</div>
</div>
</div>
How to add a div as a child to parent div after all the child class divs..
Use JQuery's Append Method
$('.parent').append('<div class="child">child6</div>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="parent">
<div class="child">child1</div>
<div class="child">child2</div>
<div class="child">child3</div>
<div class="child">child4</div>
<div class="child">child5</div>
</div>
</div>
Use Jquery appendAfter method https://api.jquery.com/insertAfter/ to insert after the last div of class child in div of class parent
$('.parent').find('.child').last().appendAfter($('<div></div>'))
You will have to adapat it if there are more than one div with class parent.
I have a nested HTML element structure where I need to apply css styles for some condition.
Apply styles to class starts with "a-" in the .a-comp element
Ignore styles to .a-col class and its child elements which have "a-*" class
The code below works for the above scenario. But it doesn't work for other child elements which have "a-*" class.
How can I achieve that?
.a-comp :not(.a-col) [class^="a-"],
.a-comp :not(.a-col) [class*="a-"] {
color: red;
}
<div class="a-comp">
<div class="a-one">
<div class="a-col">
<div class="a-text">
Text1
</div>
</div>
</div>
<div class="a-row">
<div class="a-text">
Text 2
</div>
</div>
</div>
View on JSFiddle
Your selector matches .a-* elements that have an .a-comp ancestor, with some intermediate element that is not .a-col. However, both of your examples match that selector.
The first one has .a-one as a descendant of .a-comp and ancestor of a-text. The second one has .a-row as a descendant of .a-comp and ancestor of a-text.
One solution might be to set the appropriate children of .a-col elements not to be red.
.a-comp [class^="a-"] {
color: red;
}
.a-comp .a-col [class^="a-"] {
color: black;
}
<div class="a-comp">
<div class="a-row">
<div class="a-two">
<div class="a-text">
In a ROW
</div>
</div>
</div>
<div class="a-one">
<div class="a-col">
<div class="a-text">
In a COL
</div>
</div>
</div>
<div class="a-row">
<div class="a-text">
In a ROW
</div>
</div>
<div class="a-one">
<div class="a-something">
<div class="a-text">
In something else
</div>
</div>
</div>
</div>
I need to target each last <div> before each <h3>. Is there a programatic way this can be done in css?
For other reasons, I can not / don't want to target <h3> instead.
<div id="main">
<h3>Title</h3>
<div class="post">…</div>
<div class="post"><!-- Target this div--></div>
<h3>Title</h3>
<div class="post">…</div>
<div class="post">…</div>
<div class="post">…</div>
<div class="post"><!-- Target this div--></div>
<h3>Title</h3>
<div class="post">…</div>
<div class="post">…</div>
<div class="post"><!-- Target this div--></div>
</div>
Actually this isn't possible.
If you are able to wrap the blocks into parent tags you can get each last child by CSS selectors #main .post:last-child:
<div id="main">
<div> <!-- wrap with "h3" WORKS -->
<h3>Title</h3>
<div class="post">…</div>
<div class="post"><!-- Target this div--></div>
</div>
<h3>Title</h3>
<div> <!-- wrap without "h3" also WORKS -->
<div class="post">…</div>
<div class="post">…</div>
<div class="post"><!-- Target this div--></div>
</div>
</div>
Note: The :last-child selector is not supported in IE8 and earlier versions.
What do you mean with: "For other reasons, I can not / don't want to target instead."?
jQuery workaround will work exactly like you want it with your original markup:
var $Main = jQuery('#main');
$Main.find('h3').prev().add( $Main.find(':last') ) //.text('<!-- Target this div-->');
At some point in the future, when selectors level 4 are implemented:
#main div:not(:has(+ div))