How to color first strong element within P tag one color and the rest another color? - css

I'm trying to get :first-of-type to work for the <strong> HTML element but it won't work.
There can be numerous (random number and placement, but within p tags) <strong> elements but I want the first one to have different text color than the rest.
Here I would expect Hello 1 to be blue and Hello 2 + Hello 3 to be yellow. But they're all blue.
.yolo p strong { color:yellow; }
.yolo p strong:first-of-type { color:blue; }
<div class="yolo">
<p>bla bla</p>
<p><strong>Hello 1</strong></p>
<p>bla bla</p>
<p><strong>Hello 2</strong></p>
<p>bla bla</p>
<p>bla bla</p>
<p><strong>Hello 3</strong></p>
</div>
JS fiddle
Any ideas?
Solution doesn't have to include :first-of-type as long as the HTML remains unchanged.

As mentioned, each <strong> element is the first of its element type in its own parent <p>, therefore both elements match the :first-of-type pseudo-class.
Unfortunately, in this case, you may be stuck. Since the first <strong> element may not necessarily appear in the first <p> element as shown in your markup, you won't be able to use something like .yolo p:first-of-type strong to target the first <strong>. Neither is there a way using CSS to target just the first element in such a structure, since the existing structural pseudo-classes only match the nth element among its siblings, and there is no parent selector so you can't write a selector finding "the first <p> element that contains a <strong> element".
Since your markup is produced by a CMS, you will have to either
tell the CMS to apply a class name either to the first paragraph containing a <strong> element or to the first <strong> element, or
use JavaScript to apply the class name if the behavior of the CMS cannot be modified
then target this class.

From css-tricks:
The :first-of-type selector in CSS allows you to target the first occurence of an element within its container. It is defined in the CSS Selectors Level 3 spec as a “structural pseudo-class”, meaning it is used to style content based on its relationship with parent and sibling content.
This means that this will work:
<div class="yolo">
<p><strong>Strong 1</strong>
<br>
<strong>Strong 2</strong></p>
</div>
But this wont:
<div class="yolo">
<p><strong>Strong 1</strong></p>
<p><strong>Strong 2</strong></p>
</div>
Because in the second example each of the <strong> is the first in its <p> container. But in the first example, the two <strong> tags are both in the same <p> container, so Strong 1 goes blue, being the first one in the paragraph, and Strong 2 goes yellow, not being the the first in the paragraph.

Related

NOT first element with a given class

I have some code like this:
<span class="item multifilter-wrapper multifilter">
<span class="item multifilter multifilter-item">
<div></div>
</span>
<span class="item multifilter multifilter-item">
<div></div>
</span>
<span class="item multifilter multifilter-item hasdata">
<div>HELLO</div>
</span>
</span>
Any multifilter-item span could have content, if it has content I add the hasdata class, as in the last item.
I would like to add a separator in between 2 multifilter-item spans in case there is more than one with data, so I have this BEFORE rule:
.multifilter-wrapper .hasdata:not(:first-child)::before{
content: '|';
}
However it is adding the content in the example above with just 1 hasdata span.
Any ideas why?
without having to modify your markup, you can use the general sibling selector: ~ (http://www.w3.org/TR/css3-selectors/)
http://jsfiddle.net/ossx1v1k/
.multifilter-wrapper .hasdata ~ .hasdata::before{
content: '|';
}
please note that I've removed the div tags from inside the span tags in my jsfiddle example, because as Paulie_D remarked, it's invalid markup to have block elements inside inline ones.
This is because .has-data is not the the first child, so it matches as expected.
I think you are confused as to what :first-child does. It checks if it is the first child element for it's parent (which it is not as you have 2 other ones before it). It does not check if it's the first child that is also a .hasdata class.
Basically the logic is:
class is hasdata
AND is not the first child element
To which it matches these rules, which is why the content separator is added.
There is no way to identify classes that are the first child with a specific class name in only CSS, you cannot write a rule for "is not the first hasdata class". I suggest you modify the html to have something like notfirsthasdata to identify elements that are not the first ones with content.
There is first-of-type which is the type of logic you want, however I believe this only matches with the element type (in your case span) and not the class name.

Can I combine selectors like +,~, and >? [duplicate]

For instance, div > p can be used to select all <p> elements that are direct children of a <div> element. Is it valid to use div > p > span to select a <span> elements that has a <p> parent and a <div> grandparent?
What about other operators in CSS selectors? Is it valid to use '+' in div + p + span or ',' in div, p, span?
How about combining different selectors? Like div + p > span?
Note that Selectors doesn't use the term "operator". The > and + symbols are more accurately known as combinators, while the comma is merely a symbol used to group selectors into a list, and doesn't belong in the same category as the > and + combinators.
As of Selectors level 4, combinators define a relationship between two elements, so they are indeed binary. And you can indeed use > or + multiple times in succession to refer to grandparents or other adjacent siblings. For example, div > p > span represents the following HTML fragment:
<div>
<p>
<span></span>
</p>
</div>
And div + p + span represents the following fragment:
<div></div>
<p></p>
<span></span>
You can also mix and match combinators to represent even more complex structures. For example, div + p > span represents a <span> whose parent is a <p> which in turn directly follows a <div>, as given by the following fragment:
<div></div>
<p>
<span></span>
</p>
Switching the combinators around, div > p + span represents a <span> that directly follows a <p> which in turn is a child of a <div>:
<div>
<p></p>
<span></span>
</div>
Notice how this implies that both the <span> and the <p> are children of the same <div>.
Keep in mind though that every complex selector targets the rightmost element (known as the subject of the selector). Unfortunately, this coupled with combinators being binary means that not all structures can be represented. See my answer to this question for an extremely in-depth explanation of both of these concepts and why such a limitation arises as a result.
You can also use , multiple times to group as many selectors together as you like, but again this is separate from the notion of combinators. The difference is that combinators link elements together to form a complex selector representing a singular cohesive structure, whereas the comma groups multiple complex selectors into a single CSS rule for the sake of convenience.

Why are duplicate ID's an error in HTML5 checkup?

I have the following code in HTML:
<span>
<a href="#">
<span class="caption">
<p id="first">Text1</p>
<p id="desc">click to read</p>
</span>
<img class="img_link" src="img/thing1.jpg" width="218" height="181"
alt="thing1"/>
</a>
</span>
<span>
<a href="#">
<span class="caption">
<p id="first">Text2</p>
<p id="desc">click to read</p>
</span>
<img class="img_link" src="img/thing2.jpg" width="218" height="181"
alt="thing2"/>
</a>
</span>
This code is used for making an overlayed text transition for images in CSS, but if I want to validate this HTML code, it says I have a duplicate ID (here "first" and "desc") but I honestly wouldn't know how I can simplify this. I need to resize "first" with font-size, and "desc" too.
For example: the paragraph with id "first" has to be 14px, and the paragraph with "desc" has to be 12px.
Only those <"p"> (without the quote) elements can not be a child element in the "span" element.
I wouldn't know how to solve this, do you guys have a solution?
Thanks for the answers, I've already changed the ID's to a class.
Still, I wouldn't know how to resize class "first" and "desc" in two different font sizes, because it's apparently "not done" to put a block element in an inline element
EDIT 3: Solved! Using div's is the best solution, I'm using this for school (kind of a project) for making a gallery. With float: left; I can place those images next to eachother.
Thanks for the tips!
You've made several mistakes:
id attribute is of type #ID which by the HTML/SGML standard is defined to be unique, if you want to show duplicates you should use class attribute (this is part of why there's getElementsByClassName returning a list but getElementById returning only a single item in the JavaScript DOM API)
span is inline element, while p is a block element, HTML does not allow block element inside inline element. You should replace your span with div. You can use display: inline or display: inline-block if you want it to appear like inline level elements. Example of inline elements include: a, span, etc; example of block elements include: div, p, ul, li, etc.
That is due to the element type.
<p> tag is block level element
<span> tag is a inline element
Therefore encapsulating a block level element inside an inline level element is incorrect.
Because you can use classes.
Change:
1.
id="first" -- into --> class="first"
id="desc" -- into --> class="desc"
2.
You cannot put another tags into a span tag except <i>, <b>, <strong>, and <br /> ...
With <br/ > you can have 2 lines in your span tag
Just change it to:
<p class="first">
and
<p class="desc">
EDIT:
You best remove the spans completely. You don't need them. If you feel you need them to wrap block-level elements, you can do that with divs

Selecting terminal elements

Is there a way to select elements that are not parents of any dom (of the type written as <...>)? I know that individual characters may count as dom, but ignoring that, I want to select the terminal nodes. In the following, <div id=2> would be such element but <div id=1> would not.
<div id=1>
<div id=2>
Hello World
</div>
</div>
Unfortunately, this isn't possible with a CSS selector. You need to find another way around it depending on what you're trying to achieve.
For the record, the :empty pseudo-class won't work here because it only matches an element that doesn't have any text or element children, not even whitespace. Since your second-level div contains text, it is not :empty.

In HTML, should block level elements always wrap <a> tags?

In HTML, should block level elements always wrap <a> tags? What if it's necessary for the tag to wrap the block level element to ensure the correct styles are applied? For example can this
<h3>Your Header</h3>
be this
<h3>Your Header</h3>
NB: I'm going for the latter approach to ensure the correct styles are applied (I'm working with legacy code that is just not worth re-working for this one element), but while doing this I was interested to know what the community's views are.
And yes I have read this question In HTML which way round should a and h1 be nested? but I'm not sure if a different or more flexible rule applies for <h3> tags.
Taking in the comments below and looking again at the code, I have two possible solutions:
Wrap the <h3> elements with <a> elements (ok in HTML5)
Add .class a to the CSS so that it inherits parent div styles as follows:
HTML
<div class="class">
<h3>Your Header</h3>
</div>
CSS
.class, .class a {
width:296px;
height:46px;
overflow:hidden;
color:#FE5815;
}
In this context, it is absolutely allowed for the a element to contain the h3 element, at least according to HTML5.
An a element is known as a "transparent" element: it may contain whatever its parent element may contain. The only criterion is that it may not contain any other "interactive" content, e.g. other a elements, button elements, iframe elements. In this case, presuming that the first version is allowed, the second version is also allowed under HTML5.
This is the page in the HTML5 spec that specifies this. It takes a little interpretation to understand, unfortunately...
Note that there is one case in HTML5 where
<h3>Your Header</h3>
would be valid, but
<h3>Your Header</h3>
would not, and that's when the parent of the <h3> element is an <hgroup> element.
The <hgroup> element can only have <h?> children, so while the transparent content model of the <a> element allows an <h3> to be its child, the <a> element remains invalid as a child of <hgroup>.
In this case
<hgroup>
<h3>
Your Header
</h3>
</hgroup>
and
<a href="/">
<hgroup>
<h3>Your Header</h3>
</hgroup>
</a>
are the only valid arrangements.
Both are ok
<h3>Your Header</h3>
<h3>Your Header</h3>
But I will use 1st one if I don't care whatever there is in the anchor and I just want it to look like <h3>
And I will use 2nd one if I am concerned about a particular part of anchor needs <h3>. For
example below I need the 2nd one.
check normal text <h3>check large text</h3>
In HTML 4.01 and XHTML, an h3 tag may contain a a tag, but not the other way around.
In HTML5, both ways are valid. If an a tag contains an h3 tag though, the a tag must NOT be nested in an element that cannot contain an h3 element.

Resources