Why doesn't my :first-child css rule get applied? - html

<!-- HTML -->
<section class="row slide">
<div class="span4">
<h1>
<span>Some</span>
<br />
<span>Title</span>
</h1>
</div>
</section>
<section class="row slide">
<div class="span4">
<h1>
<em>Some emphasis</em>
<br />
<span>Some</span>
<br />
<span>Title</span>
</h1>
</div>
</section>
<section class="row slide">
<div class="span4">
<h1>
<em>Some other emphasis</em>
<br />
<span>Some</span>
<br />
<span>Title</span>
</h1>
</div>
</section>
/* CSS */
section h1 span:first-child{
color:#FF0033;
}
I'm trying to target the first <span> in every <h1> tag that's in a <section> container but as soon as the <span> is not the first child element (like the <em>) then it's not applying the rule.

:first-child selects the first child. Use :first-of-type for your purpose:
section h1 span:first-of-type {
color: #FF0033;
}

:first-child does not reference the element to be the first child of that type, but generally to be the first child of its parent! Citing MDN on this:
The :first-child CSS pseudo-class represents any element that is the first child element of its parent.
What you need is the :first-of-type selector (MDN link) as follows:
section h1 span:first-of-type{
color:#FF0033;
}
Example fiddle.

Related

Getting hover to work on a nested element

Bootstrap DIVs are stopping the CSS :hover from working. I think this is a selector issue?
This doesn't work:
div#testimonial1 {
display: none;
}
span:hover+div div#testimonial1 {
display: block;
}
<h2 style="text-align:center">Testimonials</h2>
<div class="col-sm-12 col-md-4 arrow_box" style="padding-top:20px">
<div class="col-xs-12 testimonial1h">
<span style="line-height:75px;font-size:16px;verticle-align:middle"><img src="https://upload.wikimedia.org/wikipedia/commons/a/ab/Logo_TV_2015.png" width="75" height="75" alt="" /> Name Here</span>
</div>
</div>
<div class="col-sm-12 col-md-8">
<div id="testimonial1">
<p style="text-align: center">"Blah blah blah"</p>
<h3 style="text-align: center">Name Here</h3>
</div>
</div>
Yet this does:
div#testimonial1 {
display: none;
}
span:hover+div div#testimonial1 {
display: block;
}
<h2 style="text-align:center">Testimonials</h2>
<span class="button" style="line-height:75px;font-size:16px;verticle-align:middle"><img src="https://upload.wikimedia.org/wikipedia/commons/a/ab/Logo_TV_2015.png" width="75" height="75" alt="" /> Name Here</span>
<div class="col-sm-12 col-md-8">
<div id="testimonial1">
<p style="text-align: center">"Blah blah blah"</p>
<h3 style="text-align: center">Name Here</h3>
</div>
</div>
I have tried selectors like span.button etc but I can't seem to get the right selector to target the span for a hover effect?
In your first example, the span is nested in a div and in the second example, it isn't. the + selector is an adjacent sibling selector. Meaning it selects the next element it's adjacent to. There is no adjacent element to the span in your first example.
To get your first example to work, you need to set the :hover pseudo class on the element that is adjacent to the div div#testimonial1 you want to show, which would be the div that precedes it. Like this.
div#testimonial1 {
display: none;
}
.arrow_box:hover + div div#testimonial1 {
display: block;
}
<h2 style="text-align:center">Testimonials</h2>
<div class="col-sm-12 col-md-4 arrow_box" style="padding-top:20px">
<div class="col-xs-12 testimonial1h">
<span style="line-height:75px;font-size:16px;verticle-align:middle"><img src="https://upload.wikimedia.org/wikipedia/commons/a/ab/Logo_TV_2015.png" width="75" height="75" alt="" /> Name Here</span>
</div>
</div>
<div class="col-sm-12 col-md-8">
<div id="testimonial1">
<p style="text-align: center">"Blah blah blah"</p>
<h3 style="text-align: center">Name Here</h3>
</div>
</div>
In the first code block, the span is an only child of a div (.testimonial1h). (I think you mean .testimonial1.)
In the second code block, the span is not a child of a div, but a sibling of a div.
The adjacent sibling combinator (+) (also known as the next-sibling selector) targets an element that is immediately preceded by another element.
That's not going to work in the first code block, because the span has no siblings.
It works in the second code block because div#testimonial1 is a descendant of a div (you have div div#testimonial1), and that div is immediately preceded by a span sibling.
If you want the first code block to work (i.e., target an element when a sibling's child is hovered), that's not going to work with CSS. See here for details: Is there a CSS parent selector?
You are comparing apples to oranges because your first code snippet the html DOM structure is different from the second yet your are applying the same CSS which is not going to work.
On your first one you have two divs as the parents of the span. And on your second one the span is a direct child of the body.
Try this HTML structure, it should work.
<h2 style="text-align:center">Testimonials</h2>
<span class="col-sm-12 col-md-4 arrow_box" style="line-height:75px;font-size:16px;verticle-align:middle"><img src="https://upload.wikimedia.org/wikipedia/commons/a/ab/Logo_TV_2015.png" width="75" height="75" alt="" /> Name Here</span>
<div class="col-sm-12 col-md-8">
<div id="testimonial1">
<p style="text-align: center">"Blah blah blah"</p>
<h3 style="text-align: center">Name Here</h3>
</div>
</div>
It is indeed a selector issue. The plus sign is an adjacent sibling selector but in your first example span has no siblings. In your second example it is followed by a div so the selector works as expected.

CSS Selector - how to select the first and last div

I am having trouble selecting the first and last div for the following html markup:
<div class="layout__side">
<div class="portlet-dropzone">
<div id="id1">
<span></span>
<div class="portlet-body">
<div class="portlet-borderless-container">
<div class="portlet-body">
<article id="id2">
<div class="inner">
<header>yoyoyoyoyoyoy</header>
</div>
</article>
</div>
</div>
</div>
</div><!--end id1 div-->
<div id="id3">
<span></span>
<div class="portlet-body">
<div class="portlet-borderless-container">
<div class="portlet-body">
<article id="id4">
<div class="inner">
<header>yoyoyoyoyoyoy</header>
</div>
</article>
</div>
</div>
</div>
</div><!--end id3 div-->
<div id="id5">
<span></span>
<div class="portlet-body">
<div class="portlet-borderless-container">
<div class="portlet-body">
<article id="id6">
<div class="inner">
<header>yoyoyoyoyoyoy</header>
</div>
</article>
</div>
</div>
</div>
</div><!--end id5 div-->
<div id="id7">
<span></span>
<div class="portlet-body">
<div class="portlet-borderless-container">
<div class="portlet-body">
<article id="id8">
<div class="inner">
<header>yoyoyoyoyoyoy</header>
</div>
</article>
</div>
</div>
</div>
</div><!--end id7 div-->
<div id="id9">
<span></span>
<div class="portlet-body">
<div class="portlet-borderless-container">
<div class="portlet-body">
<article id="id10">
<div class="inner">
<header>yoyoyoyoyoyoy</header>
</div>
</article>
</div>
</div>
</div>
</div><!--end id9 div-->
<div id="id11">
<span></span>
<div class="portlet-body">
<div class="portlet-borderless-container">
<div class="portlet-body">
<article id="id12">
<div class="inner">
<header>yoyoyoyoyoyoy</header>
</div>
</article>
</div>
</div>
</div>
</div><!--end id11 div-->
</div><!--end portlet-dropzone-->
</div><!--end layout__side-->
I am trying to select and style only the id1 div header without explicitly selecting it using the div id. I tried using the div:first-child selector, but all of the divs are being selected! This is what I tried, along with using nth-child(1)
.layout__side .portlet-dropzone div:first-child header{
padding: 10px;
border: 1px solid red;
}
The problem is that you're selecting all div descendant elements that are a first child.
In other words, the descendant div elements .portlet-borderless-container, .portlet-body, and .inner are selected (since they are descendants of .portlet-dropzone and they are the first child relative to their parent element). Since all the div elements are selected, each header element is thereby selected and styled.
You need to select the direct child div element instead (by using the direct child combinator, >). In doing so, only the div element that is a direct child of .portlet-dropzone will be selected if it is the first child.
Example Here
.layout__side .portlet-dropzone > div:first-child header {
padding: 10px;
border: 1px solid red;
}
As your title suggests, if you also want to select the last one:
Updated Example
.layout__side .portlet-dropzone > div:first-child header,
.layout__side .portlet-dropzone > div:last-child header {
padding: 10px;
border: 1px solid red;
}
It's also worth pointing out that there are :first-of-type and :last-of-type pseudo classes which will select the first/last element by type (unlike :first-child/:last-child which will select based on the index only rather than the type).
Updated Example
.layout__side .portlet-dropzone > div:first-of-type header,
.layout__side .portlet-dropzone > div:last-of-type header {
padding: 10px;
border: 1px solid red;
}
This may be useful if there are elements of varying types and you only want to target the div elements. For instance, if there was a random h1 element before the first div, like in the example above, the first div would still be selected.

How to use Adjacent sibling selectors in css

here is my HTML code:
<div id="main">
<h1>
<div class="details-of-family-members">Details of Family Members</div>
</h1>
<div class="wrap data">
<h1> Hello</h1>
</div>
</div>
Here is my CSS to hide .wrap.data div based on div of class .details-of-family-members which is inside h1.
In CSS3 there isn't a option to select the parent based on the child.
We got this sittuation: h1 is sibling of .wrap.data, not details-of-family-members.
Therefore, you should add the class details-of-family-members to h1 tag. And then you can:
.details-of-family-members + .wrap.data {
display:none;
}
.details-of-family-members + .wrap.data{
display:none;
}
<div id="main">
<h1 class="details-of-family-members">
<div>Details of Family Members</div>
</h1>
<div class="wrap data">
<h1> Hello</h1>
</div>
</div>
Try this and you cannot target parent node based on child by css
#main h1:hover + .wrap.data {display:none;}

img:first-child not working for my first image

I've tried #logos img:first-child{} to try and format my top img a little different from the rest but it just doesn't work. Can anyone help me figure out why?
<div id="logos" name="logos">
<div class="container">
<div class="row">
<br>
<h1 class="centered">SHOWS</h1>
<img src="img/kenshows400x300.jpg" class="img-responsive" alt="Ken Cooper" width="400px" height="300px">
<hr>
</div><!-- end row -->
<div class="row">
<div class="col-lg-6">
<img src="img/shows/jkllogo450x300.jpg" class="img-responsive" alt="Jimmy Kimmel Live" width="450px" height="300px">
</div>
<div class="col-lg-6">
<img src="img/shows/latelateshowlogo450x300.jpg" class="img-responsive" alt="Late Late Show" width="450px" height="300px">
</div>
</div><!-- end row -->
</div>
</div>
The first-child pseudo-selector selects any element which is the first child of its parent. In your example, in the first .row div, the h1 "SHOWS" is the first element and your img is the second element. So it doesn't get selected. In contrast, in the other div, both img tags are the first child of their parent, so they do get selected.
In other words, img:first-child doesn't select the first img tag, it selects the img tag which is the first child of its parent. If it has a previous sibling, then first-child doesn't apply.
We can fix your code by instead putting the first-child on .row so that the img in the first row div is selected, which also happens to be the first image.
#logos .row:first-child img {
border: 1px solid blue;
}
<div id="logos" name="logos">
<div class="container">
<div class="row">
<br>
<h1 class="centered">SHOWS</h1>
<img src="img/kenshows400x300.jpg" class="img-responsive" alt="Ken Cooper" width="400px" height="300px">
<hr>
</div> <!-- end row -->
<div class="row">
<div class="col-lg-6">
<img src="img/shows/jkllogo450x300.jpg" class="img-responsive" alt="Jimmy Kimmel Live" width="450px" height="300px">
</div>
<div class="col-lg-6">
<img src="img/shows/latelateshowlogo450x300.jpg" class="img-responsive" alt="Late Late Show" width="450px" height="300px">
</div>
</div> <!-- end row -->
</div>
</div>
:first-child / :last-child required any list in one section, but in your code img wrapped with div so try to add :first-child on just parent div, see below sample code
#logos .row:first-child img{}
Try this:-
#logos .row:first-child img{
}
Another option could be first-of-type
try #logos img:first-of-type{}

Target last div in the group

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