Applying style on children does not work in Tailwind - tailwind-css

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

Related

Targeting itemprop in CSS?

I have the following two sections of code generated by a Wordpress theme.
This first section of code is generated for a WP Page:
<div class="postinner">
<div itemprop="name">
<h1 class="pagetitle">My Title</h1>
</div>
<p>First line of text</p>
<p>Second line of text</p>
</div>
This second section of code is generated for a WP Post:
<div class="postinner">
<article itemtype="http://schema.org/Article" itemscope="" role="article">
<div itemprop="headline">
<h1 class="pagetitle">Hello World!</h1>
</div>
</article>
</div>
I cannot figure out the CSS selector to specifically target and center the text of the H1 tag within the "itemprop DIV" for the 1st section of code.
Also, I would also like to target and style the H1 tag in the WP Post with a different text color but again, cannot figure out CSS selector.
You could try using CSS Attribute Selectors, such as:
div[itemprop="name"] h1 {
color: red;
}
and:
div[itemprop="headline"] h1 {
color: yellow;
}
example: http://jsfiddle.net/bEUk8/
The [att=val] selector (as suggested by Stuart Kershaw’s) works if the itemprop attribute has only this token as value.
But the itemprop attribute can have multiple tokens as value, in which case the [att=val] wouldn’t match anymore.
So you might want to use the [att~=val] selector, which matches in both cases: if it’s the only token or if it’s one of multiple tokens.
Example
Although both span elements have the name token as value of itemprop, only the first one is matched by the CSS rule with the [itemprop="name"] selector:
[itemprop="name"] {font-size:200%;}
[itemprop~="name"] {color:red;}
<div itemscope>
<span itemprop="name">'name'</span>
<span itemprop="name headline">'name' and 'headline'</span>
</div>

Is it possible to target elements based on sibling ancestors?

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/

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>

CSS-descendent selector

I would like to know difference between these two lines:
p.intro a{color=# ff99ff;}
p .intro a{color=# ff99ff;}
In first example there is no space between p and .intro, while in second example there is space between them.
I want an explanation with examples.
The first is the class given to the p item.
<p class="intro">
Item
</p>
The second is the class given to the p tag's child.
<p>
<span class="intro">
Item
</span>
</p>
First rule is for
<p class="intro">some</p>
Second is for
<p><span class="intro">some</span></p>
OK, first p.intro a { color: #ff99ff; }
<p class="intro">This <a>link</a> is colored #ff99ff.</p>
<p>But <a>this one</a> is not.</p>
Any a tag within a p that has the intro class gets colored.
Then p .intro a { color: #ff99ff; }
<p class="intro">This <a>link</a> is colored normally.</p>
<p>And so is <a>this one</a>, but <span class="intro"><a>this one</a> is colored #ff99ff.</span></p>
<div>Also, <span class="intro"><a>this link</a></span> doesn't get colored either.</div>
Here, only a tags that are within anything that has the intro class, which is itself within some p, gets colored.
The first will affect all a tags that are descendants of p tags that have the class intro.
The second will affect all a tags that are both descendants of an element (any) with the class intro AND, at the same time, descendants of a p tag.
p.intro a
This finds all <a> that are decenents of <p class="intro">.
p .intro a
This finds all <a> that are decenents of any element with the class intro that are decendants of a <p>.
The first case will select all A tags there are nested somewhere below a P tag with class "intro".
<p class="intro"><div><a>This is selected</a></div></p>
The second case will select all A tags that are nested somewhere below any sort of DOM element with a class of "intro" which in turn is nested somewhere in the a P tag.
<p><div><div class="intro"><div><a>This is selected</a></div></div></div></p>
Note that the nested element do not have to be directly below the preceding elements in the selector. They just need to be nested somewhere within the preceding items in the selector.
p.intro a{
color=# ff99ff;
}
This will effect for <a> that are inside
example:
<p class="intro">
one
</p>
and
p .intro a{
color=# ff99ff;
}
This will effect for <a> that are inside the class intro which is inside <p>
example:
<p>
<span class="intro">
one
</span>
</p>

What's the difference between CSS classes .foo.bar (without space) and .foo .bar (with space)

Would you please explain me the difference between these two CSS classes syntax:
.element .symbol {}
and
.element.large .symbol {}
I don't understand the difference between the two. The first line indicates two different classes to which are applied the same styles. But about the second, what's the meaning of '.large' which is written attached to '.element'?
.element .symbol
means .symbol inside .element
.element.symbol
means .element that has the class symbol as well.
So,
.element.large .symbol
means .symbol inside .element that has the class large as well.
I think you got a slight misunderstanding what the first one means.
.element .symbol {}
Means that those CSS settings are applied to any HTML element with the class .symbol that is inside an element with the class .element.
<div class="element">
<div class="symbol" />
</div>
In this example your first CSS entry would affect the <div> tag in the middle.
Your second example means that the first class requires two classes to be affected. Other than that it's equal to the first one.
<div class="element large">
<div class="symbol" />
</div>
So if the HTML looks like this, the CSS values will be applied to the inner <div> tag as well.
If you want to set CSS tags that apply for multiple classes separately then you need to split them up using a comma. So it looks like this:
.element, .symbol {}
Edit: By request the link to the documentation of the CSS selectors.
Using
.element.large
refers to an element with both classes:
<div class="element large"></div>
rather than a descendant of an element:
.element .large
meaning that in:
<div class="element">
<div class="large"></div>
</div>
only
<div class="large"></div>
is 'receiving' the styles.
Basically, being separated by a space implies two elements with a descendant relationship.
You would use .element .symbol this where you have an element inside of another element. For example:
<div class="element">
<i class="symbol"></i>
</div>
If down the road you wanted to differentiate some divs, you could add an additional class to target only those that differ, and target it with .element.large .symbol. So, for example:
<div class="element large">
<i class="symbol"></i>
</div>
In your second example, the first part of the selector is simply an element with two classes, as in <span class="element large"> or <span class="large element">.
In general, each part of a selector applies to one HTML element.
table[border].clname means a table with a border attribute and a class of clname, while table [border] .clname means an element with class clname, in an element with a border attribute, in a table.
(Edit: well, I say "one HTML element", but of course you can have more than one table that this applies to. You understand.)
Without whitespace, you are simply more specific with the selector. Because classes can appear several times in the html dom. But two or more classes in one element is rarer and therefore more precise.
Selectors with a whitespace (.a1 .b2) say search for the class a1 and see if there is a child or child-child element with the class b2 in this element.
An even higher degree of accuracy can be achieved with the >selector (.a1 .b2 > span). This states that only span elements should be taken into account which are direct children of the class .b2 located within an element with the class a1.
.a1 .b1 {
color: green;
}
.a1.a2 .b1 {
color: red;
}
.a1.a2 .b2 {
font-style: italic;
font-weight: bold;
}
.a1.a2 .b2 > span {
color: orange;
}
<div class="a1">
<div class="b1">Hello France</div>
<div class="b1">Hello Spain</div>
<div class="b2">Hello Sweden</div>
</div>
<hr/>
<div class="a1 a2">
<div class="b1">Bye France</div>
<div class="b1">Bye Spain</div>
<div class="b2">
Bye
<span>World</span>
</div>
</div>

Resources