Different behavior for pseudo-class with space and without space - css

This issue is related to CSS pseudo-class. I refer to :last-child just for example, I suppose it happens to all other pseudo-class too.
Given I have following simple HTML:
<body>
<p>Paragraph1</p>
<p>Paragraph2</p>
</body>
I add following CSS:
body:last-child{
color:red;
}
<body>
<p>Paragraph1</p>
<p>Paragraph2</p>
</body>
Without space both paragraphs will be marked as red
When I will set space between .body and :last-child, only second paragraph will be marked as red - that happens in Google Chrome, I see snippet tool doesn't mark any paragraph with red.
body: last-child{
color:red;
}
<body>
<p>Paragraph1</p>
<p>Paragraph2</p>
</body>
Question: Could anyone help me understand why this happens? Maybe anything to read more on behaviour with space and without space for pseudo-class?

It's last paragraph not last body.
So, just do this:
body p:last-child{
color: red;
}
Space separates the next level of elements for css selector to work.

pseudo-element should always work without Space in between of element and colon .eg
body p:last-child{ color:red; }

1. Without spacing
body:last-child {
color: red;
}
<body>
<p>Paragraph1</p>
<p>Paragraph2</p>
</body>
In the above code, all the p elements are red because color: red is applied to the body and is applied to the child elements as well. body:last-child, here :last-child is w.r.t to the parent and does not mean last child of body element.
2. With spacing
body: last-child{
color:red;
}
The above is invalid syntax and does not apply styling. You can validate your CSS: W3C CSS Validator
3. Solution:
body p:last-child { /* Select the paragraph which is last inside body */
color: red;
}
Avoid using this in SO snippets as the child selectors will be difficult to style. <link> and <script> is added/appended to the markup and disrupts the child selector.

With body:last-child, you target the last body (and there is only one). So everything within the body will be colored red.
The body: last-child doesn't work, because it is invalid.
What you are looking for is body p:last-child.

Related

How to edit :After-Content() when hovering? [duplicate]

How can I write :hover and :visited condition for a:before?
I'm trying a:before:hover, but it's not working.
This depends on what you're actually trying to do.
If you simply wish to apply styles to a :before pseudo-element when the a element matches a pseudo-class, you need to write a:hover:before or a:visited:before instead. Notice the pseudo-element comes after the pseudo-class (and in fact, at the very end of the entire selector). Notice also that they are two different things; calling them both "pseudo-selectors" is going to confuse you once you run into syntax problems such as this one.
If you're writing CSS3, you can denote a pseudo-element with double colons to make this distinction clearer. Hence, a:hover::before and a:visited::before. But if you're developing for legacy browsers such as IE8 and older, then you can get away with using single colons just fine.
This specific order of pseudo-classes and pseudo-elements is stated in the spec:
One pseudo-element may be appended to the last sequence of simple selectors in a selector.
A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.
A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.
A pseudo-class is a simple selector. A pseudo-element, however, is not, even though it resembles a simple selector.
However, for user-action pseudo-classes such as :hover1, if you need this effect to apply only when the user interacts with the pseudo-element itself but not the a element, then this is not possible other than through some obscure layout-dependent workaround. As implied by the text, standard CSS pseudo-elements cannot currently have pseudo-classes. In that case, you will need to apply :hover to an actual child element instead of a pseudo-element.
1 Of course, this does not apply to link pseudo-classes such as :visited as in the question, since pseudo-elements aren't links.
Write a:hover::before instead of a::before:hover: example.
To change a menu link's text on mouseover (different language text on hover), here is the
jsfiddle example
HTML:
<a align="center" href="#"><span>kannada</span></a>
CSS:
span {
font-size: 12px;
}
a {
color: green;
}
a:hover span {
display: none;
}
a:hover:before {
color: red;
font-size: 24px;
content: "ಕನ್ನಡ";
}
Try to use .card-listing:hover::after, hover, and after using ::. It will work.
Or you can set pointer-events:none to your a element and pointer-event:all to your a:before element, and then add hover CSS to a element:
a{
pointer-events: none;
}
a:before{
pointer-events: all
}
a:hover:before{
background: blue;
}
BoltClock's answer is correct. The only thing I want to append is that if you want to only select the pseudo element, put in a span.
For example:
<li><span data-icon='u'></span> List Element </li>
instead of:
<li> data-icon='u' List Element</li>
This way you can simply say
ul [data-icon]:hover::before {color: #f7f7f7;}
which will only highlight the pseudo element, not the entire li element.
You can also restrict your action to just one class using the right pointed bracket (">"), as I have done in this code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
span {
font-size: 12px;
}
a {
color: green;
}
.test1>a:hover span {
display: none;
}
.test1>a:hover:before {
color: red;
content: "Apple";
}
</style>
</head>
<body>
<div class="test1">
<span>Google</span>
</div>
<div class="test2">
<span>Apple</span>
</div>
</body>
</html>
Note: The hover:before switch works only on the .test1 class

CSS :not selector without combining

I am trying to figure out how :not selector works. First of all I try this code
<!DOCTYPE html>
<html>
<head>
<style>
p {
color: #000000;
}
:not(p) {
color: #ff0000;
}
</style>
</head>
<body>
<h1>This is a heading</h1>
<p class="example">This is a paragraph.</p>
<p>This is another paragraph.</p>
<div>This is some text in a div element.</div>
</body>
</html>
It works as ı expect the paragraphs aren't styled and the text in the div and the heading are red. After that I am changing the part in the style tags to this:
<style>
:not(p) {
color: #ff0000;
}
</style>
This time it doesn't work as I expected. Although I want all the elements that are not paragraphs to be red all of them are displayed as red.
Furthermore I am changing the code between the style tags to this:
<style>
:not(p.example) {
color: #ff0000;
}
</style>
This time I am expecting the elements doesn't fit to "p.example" (h1, div and the second paragraph) to be red but none of the elements are affected.
What do I miss? Shouldn't the examples shown above select all the elements those don't fit to the argument selector? Is there a rule about not using the :not selector alone (e.g not as p:not or h1:not)?
Neither of the previous answers is entirely correct.
In your second case, merely specifying
:not(p)
colors everything red because it colors the body, and color is inherited.
You to NOT have to specify, as one answer claims,
body :not(p) {
color: #ff0000;
}
That is almost exactly equivalent to :not(p) (which means *:not(p)). Nor do you have to specify any other parent such as .main as another answer claims.
The third example fails because the argument to :not is not a simple selector. The syntax you gave seems to be trying to do is to select everything that is not a p with the example class. As another respondent pointed out, what you probably meant was everything that is a p but without the example class, for which p:not(.example) is correct.
To select elements which are not A and not B (in other words not (A or B), just do
:not(A):not(B)
For example,
:not(h1):not(p)
which in this example will apply to the body and the div. A more realistic example would be to select p's other than those with either of two classes:
p:not(.class1):not(.class2)
The selector :not(p) matches all elements except p elements. This includes the body element. When your only style sheet is :not(p) { color: #ff0000; }, you thus set all content color red, since the p elements inherit color from their parents (here p) when no color is set on them directly.
If you want to set the color of content to red except for p elements and their descendants, you thus need to be more explicit. A simple way, assuming that this all you want to color, is to set the overall color to red and then override it for p elements, letting inner elements inherit color:
body { color: red }
p { color: black }
The reason why :not(p.example) does not work at all is that the operand of :not must be a simple selector, namely a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class, but not any combination of these; and p.example isn’t simple.
You could use the combined selector :not(p):not(.example), which matches any element except p elements in class example. And this is probably what you want. But the rule won’t work the way want, since here, too, the selector matches the body element, among other things, and its color gets inherited by the only element that has not got color specified for it directly. So even in this case, you would need to think otherwise, setting e.g.
body { color: red }
p.example { color: black }
After #abhitalks comments/feedback. In your first example is nothing wrong, just is related to only inherited properties which will not work. color is inherited, but border is not:
Take a look here Full property table
:not(p) {
color: #f00;
border: 1px solid gray;
}
<h1>This is a heading</h1>
<p class="example">This is a paragraph.</p>
<p>This is another paragraph.</p>
<div>This is some text in a div element.</div>
In you second example:
Selectors level 3 does not allow anything more than a single simple
selector within a :not() pseudo-class.
You can change it to:
body :not(.example) {
color: #ff0000;
}
<h1>This is a heading</h1>
<p class="example">This is a paragraph.</p>
<p>This is another paragraph.</p>
<div>This is some text in a div element.</div>
When you use :not selector, you should mentioned some parent. Based on that parent only it will work. Otherwise it will select all the elements only.
<div class="main">
<h1>This is a heading</h1>
<p class="example">This is a paragraph.</p>
<p>This is another paragraph.</p>
<div>This is some text in a div element.</div>
</div>
CSS:
.main :not(p) {
color: #ff0000;
}
Also if you don't want to select particular element using :not selector you need to use like below.
p:not(.example)
{
color:green;
}
FIDDLE DEMO

How to use a CSS :first-letter pseudo-element in a <div> paragraph

I'm trying to use a CSS :first-letter pseudo-element in a web page to enlarge and colorize the first letter of a paragraph (W), the only thing is that it's in a DIV tag and it's not displaying correctly. I have been to W3C schools and looked at the following here at Stackoverflow (css selector: first paragraph's first letter inside a div and css first-letter exclude other tags), but these don't seem to resolve my problem (more than likely I don't have the CSS setup correctly is my guess). Any help will be appreciated. Thanks.
Here is the CSS I'm using:
div homepara:first-letter {
font-size: 36px;
color: darkblue;
}
Here is the HTML I'm using:
<div class="homepara">Welcome to This Test Page.
</div>
Try this: div.homepara:first-letter. When you want to address a div with a class add a . between then.
Example
Your CSS selector isn't written correctly. Should be:
div.homepara:first-letter {
font-size: 36px;
color: darkblue;
}
div.homepara:first-letter
you just missed a '.' before the class name and there should not be space between the .classname and the div
i.e.. div.classname
DEMO

nth-child doesn't work when the tag SPAN is on

Here is my code
<span></span>
<div class='box'>title</div>
<style>div.box:nth-child(1) { color: red; }</style>
It works when I delete the span tag or any other tag which is over the box, but not when I leave it as is. Why is it so?
Use :nth-of-type .
Basically :nth-child counts ALL the siblings. Regardless of type of element. However :nth-of-type takes into account the element selected.
Because the div is now the second child. Use :nth-of-type(n) instead.
<style>
div.box:nth-of-type(1) { color: red; }
</style>
That will select the first div

How can I write a ':hover' condition for 'a:before' and 'a:after'?

How can I write :hover and :visited condition for a:before?
I'm trying a:before:hover, but it's not working.
This depends on what you're actually trying to do.
If you simply wish to apply styles to a :before pseudo-element when the a element matches a pseudo-class, you need to write a:hover:before or a:visited:before instead. Notice the pseudo-element comes after the pseudo-class (and in fact, at the very end of the entire selector). Notice also that they are two different things; calling them both "pseudo-selectors" is going to confuse you once you run into syntax problems such as this one.
If you're writing CSS3, you can denote a pseudo-element with double colons to make this distinction clearer. Hence, a:hover::before and a:visited::before. But if you're developing for legacy browsers such as IE8 and older, then you can get away with using single colons just fine.
This specific order of pseudo-classes and pseudo-elements is stated in the spec:
One pseudo-element may be appended to the last sequence of simple selectors in a selector.
A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.
A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.
A pseudo-class is a simple selector. A pseudo-element, however, is not, even though it resembles a simple selector.
However, for user-action pseudo-classes such as :hover1, if you need this effect to apply only when the user interacts with the pseudo-element itself but not the a element, then this is not possible other than through some obscure layout-dependent workaround. As implied by the text, standard CSS pseudo-elements cannot currently have pseudo-classes. In that case, you will need to apply :hover to an actual child element instead of a pseudo-element.
1 Of course, this does not apply to link pseudo-classes such as :visited as in the question, since pseudo-elements aren't links.
Write a:hover::before instead of a::before:hover: example.
To change a menu link's text on mouseover (different language text on hover), here is the
jsfiddle example
HTML:
<a align="center" href="#"><span>kannada</span></a>
CSS:
span {
font-size: 12px;
}
a {
color: green;
}
a:hover span {
display: none;
}
a:hover:before {
color: red;
font-size: 24px;
content: "ಕನ್ನಡ";
}
Try to use .card-listing:hover::after, hover, and after using ::. It will work.
Or you can set pointer-events:none to your a element and pointer-event:all to your a:before element, and then add hover CSS to a element:
a{
pointer-events: none;
}
a:before{
pointer-events: all
}
a:hover:before{
background: blue;
}
BoltClock's answer is correct. The only thing I want to append is that if you want to only select the pseudo element, put in a span.
For example:
<li><span data-icon='u'></span> List Element </li>
instead of:
<li> data-icon='u' List Element</li>
This way you can simply say
ul [data-icon]:hover::before {color: #f7f7f7;}
which will only highlight the pseudo element, not the entire li element.
You can also restrict your action to just one class using the right pointed bracket (">"), as I have done in this code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
span {
font-size: 12px;
}
a {
color: green;
}
.test1>a:hover span {
display: none;
}
.test1>a:hover:before {
color: red;
content: "Apple";
}
</style>
</head>
<body>
<div class="test1">
<span>Google</span>
</div>
<div class="test2">
<span>Apple</span>
</div>
</body>
</html>
Note: The hover:before switch works only on the .test1 class

Resources