CSS: How to select elements by referencing the parent, not the child - css

Let's say I have several <p> elements inside a <div> like this:
HTML
<div>
<p></p>
<p></p>
<p></p> <!-- I want to select the "last" element, <p> or not <p> -->
</div>
Now, say I want to style the last element, <p> or not <p>. One way to do that is to use the last-child selector on the <p>'s like this:
CSS
<style>
p:last-child {
/* Awesome styles go here */
}
</style>
Question
How do I style the last element (<p> or not <p>) by referencing <div> but NOT <p>?
Live Code Example
p:last-child {
color: red;
font-weight: bold
}
<div>
<p>Foo</p>
<p>Bar</p>
<p>Baz</p> <!-- I want to select the "last" element, <p> or not <p> -->
</div>

You can use > in your selector to describe direct children:
div > p:last-child {
}
This CSS will affect only the p tags which are the last child of div tag.
If, for some reason, you don't want to reference p at all, you can use * selector:
div > *:last-child {
}
It will affect the last child of the div whatever it is.
For example:
div > *:last-child {
font-weight: bold;
color: red;
}
<div>
<p>1</p>
<p>2</p>
<p>3</p>
</div>
<div>
1
2
3
</div>
<div>
<span>1</span>
<i>2</i>
<i>3</i>
</div>

Related

Get nth-of-type to NOT target children of children?

I'm trying to target an <h1> element within a <div> using the CSS first-of-type property, but I noticed that not only does this target the first child of this <div> that is of type <h1>, but it also targets the children of children that are of type <h1>, which seems less useful to me. Is there any way that children of children can be excluded from this?
In the example below, I have an <h1> that's an immediate child of a <div> called #everything. I try targeting that <h1> in the CSS, but this results in targeting both the correct <h1> as well as another <h1> within a child <div>.
#everything h1:first-of-type{
color: red;
}
<div id="everything">
<h1>hello</h1>
<div id="something">
<h1>goodbye</h1>
</div>
</div>
Is this what you wanted?
#everything>h1:first-of-type{
color: red;
}
<div id="everything">
<h1>hello</h1>
<div id="something">
<h1>goodbye</h1>
</div>
</div>
Update your css code with this.
#everything > h1{
color: red;
}
One more option:
#everything:first-child > h1 {
color: red;
}
For this option #everything:first-child you need to specify the child h1 or it's class/id.

restrict inner div to use main div css style class

<style type="text/css">
.life-wrapper
{
font-family:lato;
font-size:15px;
font-weight:bold;
}
</style>
<div class="life-wrapper">
<div>
First Inner
<div id="second">
Second Inner
<label>Test Second Inner</label>
</div>
</div>
</div>
Here, I have the child div as "second". Here I want to restrict div "second" in such a way that it should not be displayed as parent div design.Here, I don't want to add any new css class for the inner div. I only need to restrict inner div to use main div css class.
Cascading Style Sheets are just that, cascading. So the child elements will inherit from the parents, and so on. The only way to work around it, is to make your "First Inner" text not to be a parent of the #second element.
As easy as wrapping it into a <span>First Inner</span> and setting the style on that: .life-wrapper span
<style type="text/css">
.life-wrapper span {
font-family:lato;
font-size:15px;
font-weight:bold;
}
</style>
<div class="life-wrapper">
<div>
<span>First Inner</span>
<div id="second">
Second Inner
<label>Test Second Inner</label>
</div>
</div>
</div>

How do I style a div but only if it has an H1 as its first child?

Is there a way that I can add text-align:center to all div.wpb_wrapper which have h1 as the first child? One of the reasons I need this is that there are multiple div.wpb_wrapper that have the same parent, but not all have <h1> as the first child.
In the example below I only want to style the second div.
<div class="wpb_wrapper">
<h2>Other text</h2>
<p>Other text</p>
</div>
<div class="wpb_wrapper">
<h1>Text</h1>
<h2>Other text</h2>
<p>Other text</p>
</div>
EDIT: I can't apply text-align center to h1 because it is has display: inline-block; already applied. That's why I need to style the parent.
You cannot access the parent in CSS as of now. But you can do something like this:
Alternate Solution
As there's no CSS Parent Selector, we can apply text-align: center for all the elements that are siblings and the <h1> itself this way:
.wpb_wrapper > h1:first-child,
.wpb_wrapper > h1:first-child ~ * {
text-align: center;
}
This will apply text-align: center to all the siblings. This way, the <h2> and <p> tags will be aligned center.
Let's try here:
.wpb_wrapper > h1:first-child,
.wpb_wrapper > h1:first-child ~ * {
text-align: center;
}
<div class="wpb_wrapper">
<h2>Other text</h2>
<p>Other text</p>
</div>
<div class="wpb_wrapper">
<h1>Text</h1>
<h2>Other text</h2>
<p>Other text</p>
</div>
According to the OP:
I want to style the second div only. I do not want to center the text in the first div. I only want to center text in the div when it has an H1 as the first child. And I can't apply text-align center to h1 because it is has display: inline-block;.
So the only way would be:
.wpb_wrapper > h1:first-child ~ * {
text-align: center;
}
Or using JavaScript or jQuery and using the .closest() this way:
$(".wbp-wrapper > h1:first-child").each(function() {
$(this).closest(".wbp-wrapper").css("text-align", "center");
});
Unfortunately you can't do that with CSS only.
If you are already using jQuery you could do this:
Javascript:
$('.wbp-wrapper > h1:first-child').each(function(){
$(this).closest('.wbp-wrapper').addClass('centered');
});
CSS:
.centered {
text-align: center;
}

How to use CSS to specified a div tag in my page

I have a html page like this. I want to know is if it is possible for me to apply this style 'bottom: 5.0rem' ONLY to the div tag of the parent of below, but not to the div tag of the parent of the p? And I wan to know if i can do that without putting 'style=bottom: 5.0rem;' as the attribute of the
<div class="section">
<a href="...">
<div id="first">
<img/>
<div> <--- but not here
<p> some text </p>
</div/
</div>
</a>
<div id="first">
<div> <---- only to here
<a> anchor </a>
<div>
</div>
</div>
I have tried:
.section div#first {
bottom: 5.0rem;
}
But that apply the changes to both DIV tag.
In your specific scenario, you can use the direct descendant selector
CSS
.section > div#first div {
bottom: 5.0rem;
}
SASS
.section {
> div#first {
div {
bottom: 5.0rem;
}
}
}
This means the div inside the anchor will not be targeted because it is not a direct descendant of the section.
Firstly, IDs should be unique on a page. If you need to have multiple, use a class. Once you've done that, you can simply do
.section > .first > div {}
Or nest using ampersand
.section {
& > .first {
& > div {}
}
}

How can I use hover in a child without the parent's hover being activated?

My code can add divs as child or sibling, I've created two classes and two :hover for each class but when I put the mouse on a child the parent hover is activated as well.
.Group {
background-color: white;
}
.Group2 {
background-color: white;
}
.Group:hover {
background-color: yellow;
}
.Group2:hover {
background-color: red;
}
<div class="Group">
root
<div class="Group">1st child
<div class="Group2">2nd child
<div class="Group">3rd child</div>
</div>
</div>
<div class="Group">1st child</div>
</div>
If you hover over a child element, you're also hovering over the parent, there's no way around that.
What you could do is set a different or additional class on the 1st child elements that don't have further children.
Highlighting background colors in nested blocks when hovering
If you are trying to activate the background colors of the nested div blocks, I think you might be looking for the following.
For the HTML, use distinct class names to identify each layer of nested div blocks:
<div class="Group">root
<div class="Group1">1st child
<div class="Group2">2nd child
<div class="Group3">3rd child</div>
</div>
</div>
<div class="Group1">1st child</div>
</div>
and the CSS:
.Group, .Group1, .Group2, .Group3 {
background-color:transparent;
}
.Group:hover {
background-color:yellow;
}
.Group1:hover {
background-color:pink;
}
.Group2:hover {
background-color:red;
}
.Group3:hover {
background-color:orange;
}
Demo fiddle: http://jsfiddle.net/audetwebdesign/Scr9G/
As you mouse over each nested div successively, the background color changes in sequence.
If you are trying to target a nested element with :hover without the effect bubbling up through the parent/ancestor blocks, you will need to use JavaScript/jQuery to create the selection rules that you need.
Quirky Hack Using <p> Tags
The following construction exhibits the behavior that the OP would like to see:
<p class="Group">root
<p class="Group">1st child
<p class="Group2">2nd child
<p class="Group">3rd child</p>
</p>
</p>
<p class="Group">1st child</p>
</p>
and the CSS is as before:
.Group {
background-color:white;
}
.Group2 {
background-color:white;
}
.Group:hover {
background-color:yellow;
}
.Group2:hover {
background-color:red;
}
Second demo fiddle: http://jsfiddle.net/audetwebdesign/cf2mn/
In this case, the OP was trying to nest <p> tags, which actually do not work like nesting other block elements like <div>.
When using <p> tags, the closing </p> tag is optional if followed by other flow elements like p, div, ul and so on.
In this case, the HTML snippet show above is equivalent to:
<p class="Group">root</p>
<p class="Group">1st child</p>
<p class="Group2">2nd child</p>
<p class="Group">3rd child</p>
<p class="Group">1st child</p>
which means that all the p tabs are siblings and there are no parent-child relationships, which is why the CSS appears to be working as the OP desired.
If div tags had been used instead of p tags, the resulting DOM would have exhibited the parent-child relationships and the CSS would have shown the original behavior that the OP did not want.
Using the p tags may give the desired effect for the CSS, but it works only because the DOM elements are siblings instead of parent-child. (In addition, the nested p tags will not validate.)
It is worth noting that:
CSS 2.1 does not define if the parent of an element that is ':active' or ':hover' is also in that state.
so it is better not to rely on the state of the parent element when apply a pseudo-element on a child element.
References:
About :hover: http://www.w3.org/TR/CSS2/selector.html#dynamic-pseudo-classes
About optional closing of p tag: http://www.w3.org/TR/html-markup/p.html#p
There's no way to prevent parent elements to get background color.. rather use this code
<div class="root">
Main Root
<div class="group">
First One
</div>
<div class="group2">
Second One
</div>
<div class="group">
Third One
</div>
.group:hover {
background: yellow;
}
.group2:hover {
background: red;
}
SEE THE DEMO HERE
Give separate ids to the divs and when a child div is hovered over, change its background image color and remove the background color of the parent all at the same time. I guess that is the only way around this
The simplest and best way is probably to use any other element, li for instance.
css:
.Group, .Group2, .Group3
{
background:white;
display: block;
list-style: none;
}
.parent
{
margin: 0;
display: block;
padding: 0;
}
.Group:hover
{
background: yellow;
}
.Group2:hover
{
background: red;
}
.Group3:hover
{
background: yellow;
}
html:
<ul class="parent" >
<li class="Group" >root
<li class="Group">1st child
<li class="Group2">2nd child
<li class="Group3">3rd child</li>
</li >
</li >
<li class="Group">1st child</li >
</li>
</ul>
You should add sub-element for content and use element+element pseudo selector.
.group-content:hover {
background-color: yellow;
}
.group-content:hover + .group {
background-color: red;
}
<div class="group">
<div class="group-content">1st child</div>
<div class="group">
<div class="group-content">2nd child</div>
<div class="group">
<div class="group-content">3nd child</div>
</div>
</div>
</div>
<div class="group">
<div class="group-content">1st child</div>
</div>

Resources