Is there a way to have :first-child regardless of nesting? - css

I have some HTML where I would like just the first h1 anywhere within .main to have specific styling. The first h1 might not be directly under .main and other h1s could be anywhere further down with any level of nesting.
The example code shows a few possible HTML structures, but it could be anything.
EDIT: I am wondering if there is a generic solution that excludes other h1s from the :first-child styling, rather than creating additional rules to "remove" the styling from the :first-child rule. Other h1s are not necessarily nested with divs and the css will need to work for many different HTML structures. The example below is a specific and very simplified version of what might be produced in real life. I have added some other example HTML structures in the code.
h1 {
color: black;
}
.main h1:first-child {
color: red;
}
<div class='main'>
<h1>First h1 - goal is to be red</h1>
<h1>Second h1 - goal is to be black</h1>
<div>
<h1>Third h1 - goal is to be black</h1>
</div>
</div>
<hr>
<div class='main'>
<div>
<h1>First h1 - goal is to be red</h1>
<h1>Second h1 - goal is to be black</h1>
</div>
<div>
<h1>Third h1 - goal is to be black</h1>
</div>
</div>
<hr>
<div class='main'>
<div>
<div>
<div>
<h1>First h1 - goal is to be red</h1>
</div>
<h1>Second h1 - goal is to be black</h1>
</div>
</div>
<h1>Third h1 - goal is to be black</h1>
</div>
<hr>
<div class='main'>
<div>
<div>
<div>
<h1>First h1 - goal is to be red</h1>
</div>
<h1>Second h1 - goal is to be black</h1>
</div>
</div>
<div>
<div>
<h1>Third h1 - goal is to be black</h1>
</div>
</div>
</div>

Is this what you wanted?
h1 {
color: black;
}
#main h1:first-child {
color: red;
}
#main div h1:first-child {
color: black;
}
<div id='main'>
<h1>First Child - goal is to be red</h1>
<h1>Second Child - goal is to be black</h1>
<div>
<h1>Subdiv first child - goal is to be black</h1>
</div>
</div>

Related

CSS select direct children, but not if inside another nested child

So, if this is the HTML of an element:
<div class="parent">
<div class="ignore-me">
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p class="child">paint me green</p>
<p class="child">paint me blue</p>
</div>
How can I :
Select the children .child but not the ones inside the
div.ignore-me?
Select them separately, based on their index order.
I tried to use a mix of > and :nth-child(n) like this:
.parent > .child:nth-child(1)
But, it doesn't work!
Can this be done only CSS?
.parent > .child:nth-child(1) {
background: green;
}
.parent > .child:nth-child(2) {
background: blue;
}
<div class="parent">
<div class="ignore-me">
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p class="child">paint me green</p>
<p class="child">paint me blue</p>
</div>
Use div.parent > p.p
> is the child combinator. It matches only those elements matched by the second selector that are the direct children of elements matched by the first.
div.parent > p.p {
color:green;
}
<div class="parent">
<div class="ignore-me">
<p class="p">don't select me</p>
<p class="p">don't select me</p>
<p class="p">don't select me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p class="p">select me</p>
<p class="p">select me too</p>
</div>
The accepted answer can be further simplified to div.parent > p, because > already only selects direct children.
div.parent > p {
color:green;
}
<div class="parent">
<div class="ignore-me">
<p>don't select me</p>
<p>don't select me</p>
<p>don't select me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p>select me</p>
<p>select me too</p>
</div>
Regarding
Select them separately, based on their index order.
you can use :nth-child, but be aware that :nth-child also counts <div class="ignore-me"> as a child of <div class="parent">. So your first <p class="child"> is the second child. You can then use even and odd to alternate between the children.
div.parent > p {
color:green;
}
div.parent > p:nth-child(odd) {
color:blue;
}
<div class="parent">
<div class="ignore-me">
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p class="child">paint me green</p>
<p class="child">paint me blue</p>
<p class="child">paint me green</p>
<p class="child">paint me blue</p>
</div>
Selecting direct nth p tag inside "parent" class
div.parent>p.child:nth-child(2) {
background: green;
}
div.parent>p.child:nth-child(3) {
background: blue;
}
div.parent>p.child:nth-child(4) {
background: green;
}
we can slect odd and event children
div.parent>p.child:nth-child(odd) {
background: green;
}
div.parent>p.child:nth-child(even) {
background: red;
}

css/sass :not(:first-of-type) not working, is hiding all elements of type

I have a sass block that i have tried several different ways:
I've tried this:
.progress-body {
display: none;
&:first-of-type {
display: block;
}
}
and this:
.progress-body {
&:not(:first-of-type) {
display: none;
}
}
and this:
.progress-body:not(:first-of-type) {
display: none;
}
when applied to HTML that looks like this:
<div class="panel">
<div class="panel-heading">
</div>
<div class="panel-body progress-body">
<div class="row">
<div class="col-md-12">
<p class="lead">Step 1: Choose your template...</p>
</div>
</div>
</div>
<div class="panel-body progress-body">
<div class="row">
<div class="col-md-12">
<p class="lead">Step 2: Compose your email...</p>
</div>
</div>
</div>
</div>
the result is that it hides all the elements with the progress-body class. This is normally pretty straight forward CSS so no idea what is wrong here...
In this case progress-body is not the first-of-type, this would technically be .panel-heading since the first-of-type refers to the type element selector (div) and not the class.
The :first-of-type CSS pseudo-class represents the first element of
its type among a group of sibling elements.
Ref: :first-of-type - CSS | MDN
Consider wrapping your .progress-body elements in a containing element, you will achieve the expected behaviour, since .progress-body would be the first of its type with the class name .progress-body.
Code Snippet Demonstration:
.progress-body:not(:first-of-type) {
display: none;
}
<div class="panel">
<div class="panel-heading">
</div>
<div class="panel-outer-body">
<div class="panel-body progress-body">
<div class="row">
<div class="col-md-12">
<p class="lead">Step 1: Choose your template...</p>
</div>
</div>
</div>
<div class="panel-body progress-body">
<div class="row">
<div class="col-md-12">
<p class="lead">Step 2: Compose your email...</p>
</div>
</div>
</div>
</div>
</div>
If you can't wrap as UncaughtTypeError wrote in his answer, youcan use (general) sibling selectors.
.progress-body + .progress-body {display: none;}
or
.progress-body ~ .progress-body {display: none;}
I expect the first is block by default, if you didn't change it elsewhere.

CSS Grab All Class Name Except For Last

I want to grab all the class name ('my-class') and change it's color to red EXCEPT for the last one
Apparently I've been googling and there's no such thing as :last-of-class or whatever. I'm having trouble trying to find a work around without using JS.
div1 and div2 are both dynamic! If div2 doesn't exist, then div1 should have the first p element red and the second not.
Please note I left a 'p' tag at the top because I don't want that being part of my selector. I just need the 'my-class' specifically.
or is there a selector I can write to grab all "p"s inside of my-container which include nested P's
<p>Some text</p>
<div class="my-container">
<div class="div1">
<p class="my-class"></p>
<p class="my-class"></p>
</div>
<div class="div2">
<p class="my-class"></p>
<p class="my-class"></p>
<p class="my-class"></p>
<p class="my-class"></p> <!-- This tag should not be red-->
</div>
</div>
I can also use sass so feel free to include that in if need be.
I don't know of any SINGLE rule that would do this, but a simple workaround would be to use 2 separate rules in conjunction:
.my-class {
color: red;
}
.div-2 .my-class:last-child {
color: // whatever you want the default to be
}
note that the order is important, setting the last child's color should be done after setting everything first
You can use the workaround below.
use div:last-child . that will select the last div in the container and if there is only one, it will select it and so...the last p from the last div will be of other color ( in this example )
.my-container div p.my-class {
color:red;
}
.my-container div:last-child p.my-class:last-child {
color:blue;
}
<p>Some text</p>
<div class="my-container">
<div class="div1">
<p class="my-class">a</p>
<p class="my-class">a</p>
</div>
<div class="div2">
<p class="my-class">a</p>
<p class="my-class">a</p>
<p class="my-class">a</p>
<p class="my-class">b</p> <!-- This tag should not be red-->
</div>
</div>
This will get the behavior you're looking for without any forced reflow:
.my-class:not(:last-child) {
color: red;
}
<p>Some text</p>
<div class="my-container">
<div class="div1">
<p class="my-class">a</p>
<p class="my-class">b</p>
</div>
<div class="div2">
<p class="my-class">c</p>
<p class="my-class">d</p>
<p class="my-class">e</p>
<p class="my-class">f</p> <!-- This tag should not be red-->
</div>
</div>

CSS: Change child on parent hover (only single child)

I can change child on parent hover like this:
.parent:hover .child{ ... }
Problem is, that this will change all childs in document.
(I'm using parent 10x on the page => it will change childs in all these parent)
Is there a CSS way, how to change only child of the parent, that I'm currently hovering over?
Example:
<div class="parent">
<p class="child"></p>
</div>
<div class="parent">
<p class="child"></p>
</div>
<div class="parent">
<p class="child"></p>
</div>
If I hover over first .parent, I want change on its .child. But my mentioned solution will affect all childs.
You'll want to directly select the child using the ">" or the "adjacent sibling combinator"
.parent:hover > .child{
background: red;
}
<div class="parent">
<p class="child">child one</p>
</div>
<div class="parent">
<p class="child">child two</p>
</div>
<div class="parent">
<p class="child">child three</p>
</div>

How to select a second div following any dom element?

how to give a float left attribute to the second div following the h3 ?
<div class="view-content">
<h3>
<div>
<h3>
<div>
<h3>
<div>
<div> this one !
<h3>
<div>
</div>
You can chain adjacent sibling selectors:
h3 + div + div {
float: left;
background: yellow;
}
h3 + div {
display: inline-block;
}
<div class="view-content">
<h3></h3>
<div>not this</div>
<h3></h3>
<div>nor this</div>
<h3></h3>
<div>or this</div>
<div>but this one !</div>
<h3></h3>
<div>not this</div>
</div>
.view-content div:nth-of-type(2) //Mistaken
{
float:left;
}
it ll solve your problem. Thanks for pointing me the errors

Resources