Is it possible to target elements based on sibling ancestors? - css

I would like to use CSS to target an element that is a "cousin" of a specific element — in other words, where they are both descendants of sibling elements.
I can target an element based on its "uncle" or a sibling of an ancestor, like this:
HTML:
<div>
<h2 data-section="name">Name</h2>
<p class="hint">Full name of the employee</p>
<p>
<span class="value1">Joe Tester</span>
</p>
</div>
<div>
<h2 data-section="details">Occupation</h2>
<p class="hint">Job role or title</p>
<p>
<span class="value1">Software Engineer</span>
</p>
</div>
CSS:
/*
* element that
* has a class of value1
* and is a descendent of a p
* that is next to an h2
* with attribute data-section=name
*/
h2[data-section="name"]~p .value1 {
color: #F92759;
}
Result:
But what if the data-section="name" element is wrapped in another element? Is it still possible to make the following HTML the same as the image above?
<div>
<div>
<h2 data-section="name">Name</h2>
</div>
<p class="hint">Full name of the employee</p>
<p>
<span class="value2">Joe Tester</span>
</p>
</div>
The practical application: Targeting a node in a page (inside body tag) that has a particular meta element.
Example JSFiddle here: http://jsfiddle.net/nchaves/tefpY/

There isn't a css-only solution for this. You can, however, accomplish this using jQuery:
<script>
$("[data-section='name']").parent().parent().addClass('myclass');
</script>
<style>
.myclass .value2 { color: #F92759; }
</style>
JS Fiddle here: http://jsfiddle.net/tefpY/1/

Related

Applying style on children does not work in Tailwind

Let's say I have this markup:
<div class="">
<p>First text</p>
<p>
<span>Hi</span>
<span class="bold">Bye</span>
</p>
</div>
If I use text-red-400 on the parent element, I see that all of the children become red.
However, when I use [&>.bold]:text-red-400, the span element that has bold class won't be changed.
What is wrong here?
Because > CSS selector is direct children only selector
The child combinator (>) is placed between two CSS selectors. It matches only those elements matched by the second selector that are the direct children of elements matched by the first.
Utility [&>.bold]:text-red-400 basically is equivalent of
.utility > .bold {
color: red;
}
Every direct child with .bold class will be red
<div class="[&>.bold]:text-red-400">
<p class="bold">I'm red</p>
<p>
<span>Hi</span>
<span class="bold">I'm not</span>
</p>
</div>
If you wish to target every .bold element just remove > selector and replace it with underscore _
<div class="[&_.bold]:text-red-400">
<p class="bold">I'm red</p>
<p>
<span>Hi</span>
<span class="bold">Me too</span>
</p>
</div>
DEMO
So if you want to change the text color for only the span element with bold class then you need to specify the position of the child element as well. You can try the following code:
[&>*:nth-child(2)]:text-red-500.
This is mentioned in the tailwind documentation a well for more help: tailwind doc

How to select all a elements from a p class?

How can I select all a elements inside a p element that have a specific class name?
<div>
<p class="myClass">
This is
<div>
random
</div>
</p>
</div>
Remove the div inside the p tag:
<div>
<p class="myClass">
random
</p>
</div>
Then if you want to select all the a tags inside a p tag which you gave a class. You can do the following:
.myClass a {
}
May be you aren't able to target anchor tag(s) due to that div. Do you need that div before the anchor tag? Please refer to the code snippet below:
.myClass a {
color: green;
}
<div>
<p class="myClass">
This is
random
</p>
</div>
div *[href]
{
// css rules...
}
<div>
<p class="myClass"> This is
<div>
random
</div>
</p>
</div>
you can give a specific class name to a and call it like:
<a class="myA's" href="#">random</a>
CSS
a.myA's{
#do something
}
And in your case it should be:
.myClass > a{
#doSmthg
}
<p> can only contain inline elements,See here.
so,remove div inside p:
p.myClass a {
color: red;
}
<div>
<p class="myClass">
This is<br>
random
</p>
</div>
You need to change the <p> to <div> then use this
.myClass > div a { ... }`
or remove <div> inside the <p> and try this
p.myClass a { ... }

Checking if data attribute is set at parent div css / less and using it for the child divs as well

I have div tag for which a data-type attribute is associated. I want to apply different styles depending on data-type is set or no.
<div data-type="type1">Hello, World!</div>
Can I check if this attribute data-type is set or no in css/less ? This question is solved with this.
But, if I apply this data-type attribute only to the parent div, can I use this attribute for all the child div tags as well.
For instance,
<div data-type=`type1`>
<div id="newDiv"> </div>
</div>
In my CSS, I want to apply different styles for #newDiv depending on whatever type (data-type) is set to its parent. I don't want to specify the data-type attribute to the child div as well. How do we do this in CSS ?
You can use :not([data-type]) to select any element that does not have the attribute data-type set regardless of the values used.
Basic working example:
div:not([data-type]) {
color: red;
}
<div data-type="type1">Hello, World!</div>
<div>Hello, World!</div>
Alternatively, you can do the opposite and use [data-type] to select anything with the data-type attribute set regardless of the value
Working example:
div[data-type] {
color: red;
}
<div data-type="type1">Hello, World!</div>
<div>Hello, World!</div>
If you want to target a child div whose parent div has the data-type attribute set the you can use something like this:
div[data-type]>h1 {
color: red;
}
<div data-type="type1">Hello, World!
<h1> How are you?!</h1>
</div>
<hr>
<div>Hello, World!
<h1> How are you?!</h1>
</div>
This also can be reveresed based on your selector preference to target the child elements of parent elements which do not have the data-type attribute set.
div:not([data-type])>h1 {
color: red;
}
<div data-type="type1">Hello, World!
<h1> How are you?!</h1>
</div>
<hr>
<div>Hello, World!
<h1> How are you?!</h1>
</div>
If you have more complex structures you can make use of the wildcard * selector to build selectors that match very broad patterns. The letters represent the depth of the tree on which the element resides with aaa being a direct child and bbb being a grandchild...etc
Basic Example:
[data-type] * h1,
[data-type] h1 {
color: red;
}
<div data-type="type1">
<h1> aaa</h1>
</div>
<hr>
<div>
<h1> aaa</h1>
</div>
<hr>
<div id="test" data-type="type1">
<div>
<h1> bbb</h1>
<div>
<h1> ccc</h1>
</div>
</div>
<h1 class="wow"> aaa</h1>
<div>
<h1 class="wow"> bbb</h1>
</div>
</div>
<hr>
<div id="test">
<h1 class="wow"> aaa</h1>
<div>
<div>
<h1> ddd</h1>
</div>
<h1 class="wow"> ccc</h1>
</div>
</div>
If you find a pattern in your data-type value, yes, you can:
/* 1. Attribute value starts with "type" */
div[data-type^="type"] {
/* Styles */
}
/* 2. Attribute value contains "type" */
div[data-type*="type"] {
/* Styles */
}
Works for: type1, typex, typeaskdasd, etc...
Works for: abctypexyz, typexyz, etc...

Select only the second child of an element with CSS

I have something like this:
<div id="someID">
<div class="text">
-----other html tags
</div>
<div class="text">
-----other html tags
</div>
<div class="text">
-----other html tags
</div>
</div>
And some CSS for the text div. It is possible to set different CSS for the second div with the class of text?
You can easily do with with nth-child:
#someID .text:nth-child(2) {
background:red;
}
Demo: http://jsfiddle.net/P6FKf/
You can use the pseudo selector nth-child i.e div.text:nth-child(2)

Styling tags within tags confusion

I am having a rather difficult time understanding this type of css selector show below, or at least how to apply.
p .intro a { color: yellow }
p .intro a { color: yellow }
It would style any (reading from right to left)
a tag
which is a descendant of any tag with a class (dot is a class selector) intro
which is a descendant of p tag
Example (note that the elements are not direct children, but descendants):
<p>
<span>
<span class="intro">
<span>
I am yellow
</span>
</span>
</span>
</p>
(fiddle)
This selector would match HTML similar to this:
<p>
<span class="intro">
I am yellow
</span>
</p>
Basically, a a tag inside of a tag with a class of intro inside of a p tag. They don't have to be direct children.
Your jsFiddle example fails because of symantics. Peep this: Nesting block level elements inside the <p> tag... right or wrong?
So what you can do is change your markup to, for example:
<p>
<span class="intro">
I AM yellow
</span>
</p>
or
<div>
<div class="intro">
I AM yellow
</div>
</div>

Resources