What are the pseudo-elements and pseudo-classes in CSS? [duplicate] - css

Things like a:link or div::after...
Information on the difference seems scarce.

The CSS 3 selector recommendation is pretty clear about both, but I'll try to show the differences anyway.
Pseudo-classes
Official description
The pseudo-class concept is introduced to permit selection based on information that lies outside of the document tree or that cannot be expressed using the other simple selectors.
A pseudo-class always consists of a "colon" (:) followed by the name of the pseudo-class and optionally by a value between parentheses.
Pseudo-classes are allowed in all sequences of simple selectors contained in a selector. Pseudo-classes are allowed anywhere in sequences of simple selectors, after the leading type selector or universal selector (possibly omitted). Pseudo-class names are case-insensitive. Some pseudo-classes are mutually exclusive, while others can be applied simultaneously to the same element. Pseudo-classes may be dynamic, in the sense that an element may acquire or lose a pseudo-class while a user interacts with the document.
Source
What does this mean?
The important nature of pseudo-classes is stated in the very first sentence: "the pseudo-class concept [...] permit selection". It enables the author of an stylesheet to differ between elements based on information that "lies outside of the document tree", for example the current status of a link (:active,:visited). Those aren't saved anywhere in the DOM, and there exists no DOM interface to access these options.
On the other hand, :target could be accessed via DOM manipulation (you could use window.location.hash in order to find the object with JavaScript), but this "cannot be expressed using the other simple selectors".
So basically a pseudo-class will refine the set of selected elements as any other simple selector in a sequence of simple selectors. Note that all simple selectors in a sequence of simple selectors will be evaluated at the same time. For a complete list of pseudo-class check the CSS3 selector recommendation.
Example
The following example will color all even rows gray (#ccc), all uneven rows which aren't dividable by 5 white and every other row magenta.
table tr:nth-child(2n) td{
background-color: #ccc;
}
table tr:nth-child(2n+1) td{
background-color: #fff;
}
table tr:nth-child(2n+1):nth-child(5n) td{
background-color: #f0f;
}
Pseudo-elements
Official description
Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element's content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).
A pseudo-element is made of two colons (::) followed by the name of the pseudo-element.
This :: notation is introduced by the current document in order to establish a discrimination between pseudo-classes and pseudo-elements. For compatibility with existing style sheets, user agents must also accept the previous one-colon notation for pseudo-elements introduced in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and :after). This compatibility is not allowed for the new pseudo-elements introduced in this specification.
Only one pseudo-element may appear per selector, and if present it must appear after the sequence of simple selectors that represents the subjects of the selector.
Note: A future version of this specification may allow multiple pseudo-elements per selector.
Source
What does this mean?
The most important part here is that "pseudo-elements allow authors to refer to [..] otherwise inaccessible information" and that they "may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).". The biggest difference is that they actually create a new virtual element on which rules and even pseudo-class selectors can be applied to. They don't filter elements, they basically filter content (::first-line,::first-letter) and wrap it in a virtual container, which the author can style however he want (well, almost).
For example the ::first-line pseudo-element cannot be reconstructed with JavaScript, as it heavily depends on the current used font, the fonts size, the elements width, floating elements (and probably the time of the day). Well, that's not entirely true: one could still calculate all those values and extract the first line, however doing so is a very cumbersome activity.
I guess the biggest difference is that "only one pseudo-element may appear per selector". The note says that this could be subject to change, but as of 2012 I don't believe we see any different behavior in the future (it's still in CSS4).
Example
The following example will add a language-tag to every quote on a given page using the pseudo-class :lang and the pseudo-element ::after:
q:lang(de)::after{
content: " (German) ";
}
q:lang(en)::after{
content: " (English) ";
}
q:lang(fr)::after{
content: " (French) ";
}
q:not(:lang(fr)):not(:lang(de)):not(:lang(en))::after{
content: " (Unrecognized language) ";
}
TL;DR
Pseudo-classes act as simple selectors in a sequence of selectors and thereby classify elements on non-presentational characteristics, pseudo-elements create new virtual elements.
References
W3C
Selectors Level 3
4. Selector syntax
6.6 Pseudo-classes
7. Pseudo-elements
CSS 2.1 Specification (outdated but still informative)
5.2 Selector syntax:
A simple selector is either a type selector or universal selector followed immediately by zero or more attribute selectors, ID selectors, or pseudo-classes, in any order. The simple selector matches if all of its components match.
5.10 Pseudo-elements and pseudo-classes

A pseudo-class filters existing elements.
a:link means all <a>s that are :link.
A pseudo-element is a new fake element.
div::after means non-existing elements after <div>s.
::selection is another example of a pseudo-element.
It doesn't mean all elements that are selected; it means the range of content that is selected, which may span portions of multiple elements.

Short description that helped me to understand the difference:
Pseudo-classes describe a special state.
Pseudo-elements match virtual elements.

From the Sitepoint docs:
A pseudo-class is similar to a class in HTML, but it’s not specified explicitly in the markup. Some pseudo-classes are dynamic—they’re applied as a result of user interaction with the document. - http://reference.sitepoint.com/css/pseudoclasses. These would be things like :hover, :active, :visited.
Pseudo-elements match virtual elements that don’t exist explicitly in the document tree. Pseudo-elements can be dynamic, inasmuch as the virtual elements they represent can change, for example, when the width of the browser window is altered. They can also represent content that’s generated by CSS rules. - http://reference.sitepoint.com/css/pseudoelements. These would be things like ::before, ::after, ::first-letter.

Below is the simple answer:
We use pseudo-class when we need to apply css based on the state of an element. Such as:
Apply css on hover of anchor element (:hover)
Apply css when gets focus on an html element (:focus). etc.
We use pseudo-element when we need to apply css to the specific parts of an elements or a newly inserted content. Such as:
Apply the css to first letter or first line of an element (::first-letter)
Insert content before, or after, the content of an element (::before, ::after)
Below is the example of both:
<html>
<head>
<style>
p::first-letter { /* pseudo-element */
color: #ff0000;
}
a:hover { /* pseudo-class */
color: red;
}
</style>
</head>
<body>
<a href="#" >This is a link</a>
<p>This is a paragraph.</p>
</body>
</html>

A conceptual answer:
A pseudo-element refers to things that are part of the document, but you just don't know it yet. For example the first letter. Before you only had text. Now you have a first letter that you can target. It is a new concept, but was always part of the document. This also includes things like ::before; while there isn't actual content there, the concept of something before something else was always there -- now you are specifying it.
A pseudo-class is state of something in the DOM. Just like a class is a tag you associate with an element, a pseudo-class is a class that gets associated by the browser or DOM or whatever, usually as a response to a change in state. When a user visits a link -- that link can take on the state of 'visited'. You can imagine the browser applying the class 'visited' to the Anchor element. :visited would then be how you select for that pseudo-class.

Pseudo-Class
A pseudo-class is way of selecting certain parts of a HTML document, based in principle not on the HTML document tree itself and its elements or on characteristics like name, attributes or contents, but on other phantom conditions like language encoding or the dynamic state of an element.
The original pseudo-class defined dynamic states of an element that are entered and exited over time, or through user intervention. CSS2 expanded on this concept to include virtual conceptual document components or inferred portions of the document tree e.g. first-child. Pseudo-classes operate as if phantom classes were added to various elements.
RESTRICTIONS: Unlike pseudo-elements, pseudo-classes can appear anywhere in selector chain.
Example pseudo-class code:
a:link /* This selects any "a" element whose target has not been visited.*/
{
padding : 4px;
text-decoration : none;
width : 10%;
color : #000000; /* black text color */
background-color : #99FF99; /* set to a pastel green */
border-top : 2px solid #ccffcc; /* highlight color */
border-left : 2px solid #ccffcc; /* highlight color */
border-bottom : 2px solid #003300; /* shadow color */
border-right : 2px solid #003300; /* shadow color */
}
a:visited /* This selects any "a" element whose target has been visited.*/
{ padding : 4px;
text-decoration : none;
color : #000000; /* black text color */
background-color : #ccccff; /* set to a lavender */
border-top : 2px solid #ffffff; /* highlight color */
border-left : 2px solid #ffffff; /* highlight color */
border-bottom : 2px solid #333366; /* shadow color *
border-right : 2px solid #333366; /* shadow color */
}
a:hover /* This selects any "a" element which is in a hover state. This is a state during pointer movement within the rendering region of an element. The user designates an element but does not activate it. */
{
color : #000000; /* black text color */
background-color : #99cc99; /* desaturated color */
border-top : 2px solid #003300; /* shadow color */
border-left : 2px solid #003300; /* shadow color */
border-bottom : 2px solid #ccffcc; /* highlight color */
border-right : 2px solid #ccffcc; /* highlight color */
}
a:focus /* This selects any "a" element which currently has focus. Focus is a state during which an element accepts keyboard input or other forms of text input. */
{
padding : 4px;
text-decoration : none;
width : 10%;
color : #000000; /* black text color */
background-color : #ffff99; /* set to a pastel yellow */
border-top : 2px solid #ffffcc; /* highlight color */
border-left : 2px solid #ffffcc; /* highlight color */
border-bottom : 2px solid #666633; /* shadow color */
border-right : 2px solid #666633; /* shadow color */
}
a:active /* This selects any "a" element which is in a state of activation. Active is a state during pointer activation (eg: press and release of a mouse) within the rendering region of an element.*/
{
padding : 4px;
text-decoration : none;
width : 10%;
color : #000000; /* black text color */
background-color : #ff99ff; /* set to a pink */
border-top : 2px solid #ffccff; /* highlight color */
border-left : 2px solid #ffccff; /* highlight color */
border-bottom : 2px solid #663366; /* shadow color */
border-right : 2px solid #663366; /* shadow color */
}
A page that demonstrates a rendering of the above pseudo-class code
Pseudo-elements
PSEUDO-ELEMENTS are used to address sub-parts of elements. They allow you to set style on a part of an element's content beyond what is specified in the documents. In other words they allow logical elements to be defined which are not actually in the document element tree. Logical elements allow implied semantic structure to be addressed in CSS selectors.
RESTRICTIONS: Pseudo-elements may only be applied to external and document-level contexts - not to in-line styles. Pseudo-elements are restricted in where they can appear in a rule. They may only appear at the end of a selector chain (after the subject of the selector). They should come after any class or ID names found in the selector. Only one pseudo-element can be specified per selector. To address multiple pseudo-elements on a single element structure, multiple style selector/declaration statements must be made.
Pseudo-elements can be used for common typographic effects such as initial caps and drop caps. They can also address generated content that is not in the source document (with the "before" and "after") An example style sheet of some pseudo-elements with properties and values added follows.
/* The following rule selects the first letter of a heading 1 and sets the font to 2em, cursive, with a green background. First-letter selects the first rendered letter/character for a block-level element. */
h1:first-letter {
font-size : 2em;
font-family : "Lucida Handwriting", "Lucida Sans", "Lucida Console", cursive;
background-color : #ccffcc;
}
/* The following rule selects the first displayed line in a paragraph and makes it bold. First-line selects the first rendered line on the output device of a block-level element. */
p:first-line {
font-weight : bold;
}
/* The following rule selects any content placed before a blockquote and inserts the phrase "Quote of the day:" in bold small caps with a green background. */
blockquote:before {
content : "Quote of the day:";
background-color : #ccffcc;
font-weight : bold;
font-variant : small-caps;
}
/* The following rule selects any content placed before a "q" element and inserts the smart open quote. */
q:before {
content : open-quote;
}
/* The following rule selects any content placed after a "q" element and inserts the smart close quote. */
q:after{
content : close-quote;
}
Sources:Link

In brief, from Pseudo-classes on MDN:
A CSS pseudo-class is a keyword added to a selector that specifies
a special state of the selected element(s). For example, :hover
can be used to apply a style when the user hovers over a button.
div:hover {
background-color: #F89B4D;
}
And, from Pseudo-elements on MDN:
A CSS pseudo-element is a keyword added to a selector that lets you
style a specific part of the selected element(s). For example,
::first-line can be used to style the first line of a paragraph.
/* The first line of every <p> element. */
p::first-line {
color: blue;
text-transform: uppercase;
}

Related

In CSS, * selector winning over !important [duplicate]

What is the level of CSS specificity received by inherited properties? I read through the W3 recommendation regarding CSS specificity and so I understand how to calculate the different specificities of css rules which are directly targeting the same element, but I see no mention there of the level of specificity given to inherited attributes.
In particular, the issue I'm encountering has to do with header elements, though I would be very interested to understand this in general.
For example, here's a snippet of HTML:
<h2>This should be black</h2>
<div class="all_red_text">
<h2>This should be red</h2>
</div>
Now if I include some CSS like this:
.all_red_text { color: red; }
I will get the result I expect. On the other hand, if I the css which I included was
h2 { color: black; }
.all_red_text { color: red; }
then all the text will be black. In the first case there is some default browser CSS which is able to be overridden by the inherited property, but then when the same property is manually specified in the second example it takes precedence over the inherited property.
Any declaration that matches element directly will get priority over the property that's inherited from the element's parent. Specificity has nothing to do with that.
CSS is applied to elements in this form:
Priority 1: inline styles
Priority 2: CSS ID styles
Priority 3: CSS class/pseudo-class styles
Priority 4: CSS element styles
Priority 5: Inherited styles
So, using your HTML structure & CSS:
h2 { color: black; }
.all_red_text { color: red; }
<h2>This should be black (and is black)</h2>
<div class="all_red_text">
(This text is indeed red.)
<h2>This should be red (actually, its parent is red - this text is black)</h2>
</div>
The .all_red_text CSS is telling the div.all_red_text element and everything inside it to have red text. The h2 CSS is telling the h2 elements directly to have black text. When the h2 is rendered, it sees "my parent element wants me to have red text, but I'm directly being told to have black text". The same idea applies to further up parents, including the HTML and browser defaults - this allows you to, for example, set the font-family on the html element and have it apply to everything on your (well formatted) web page, unless something specifically overrides it.
If you want the h2 inside div.all_ted_text to also have red text, you'd need to tell those h2 elements directly to have red text; something like this:
.all_red_text h2 { color: red; }
CSS-Tricks has a pretty nice guide on this, although they don't currently go too deep into inherited properties.
There is no such thing as specificity of inherited CSS properties. Selectors, not properties, have specificity.
In your example, both h2 elements match only one of the rules, h2 { color: black; }. Thus, the color of h2 is black (assuming there are no other style sheets that affect the rendering). Anything set on some other elements (including the parent of the second h2 element) does not affect this the least.
If the rule h2 { color: black; } is absent and there are no other rules affecting the situation, then there is no color set on either of the h2 elements. According to the definition of the color property, the value is then inherited from the parent.
Two or more selectors gets engaged into Specificity War, if and only if
they end up targetting the exact same element. However, If two selectors (targetting the same element) have equal specificity weight, then there are other factors like you said, inheritance or the styles getting over ridden in the css file.

Pseudo-class inheritance understanding

I thought that pseudo-classes inherited properties from their parent element, but in practice it seems the parent element specifically selects all its pseudo-classes, even if they're not specified.
Eg, given the HTML:
ok
and CSS:
#id-selector {
color: green;
}
a:any-link {
color: red;
}
I thought that color: green would only be inherited by the pseudo-class any-link, and thus be overriden by the a:any-link selector since this is a specific selector for the pseudo-class, and specific selectors override inherited properties even if they have a lower specificity. But the output of the above is a green link, indicating that #id-selector is specifically targeting any-link, not it being inherited.
An example of a specific selector with a lower specificity overriding an inherited property with a higher specificity:
HTML -
<div id="id-has-high-specificity">
<h1 class="class-has-low-specificity">Heading</h1>
</div>
CSS -
.class-has-low-specificity {
color: green;
}
#id-has-high-specificity {
color: red !important;
}
here the output is green, which is expected, since the heading is only inheriting from the second rule, but is being specifically selected by the first rule.
I thought this same thing applied to pseudo-classes, in that pseudo-classes inherited from their parent element. But it seems from my first example that they don't, and that rather the parent element specifically selects all its pseudo-classes, even if they're not specified.
Is it the case then that pseudo-classes don't inherit any properties from their parent element, but instead the parent element specifically sets all of its pseudo-classes whenever a rule for it is defined, even if those pseudo-classes aren't specified?
CSS ascertains which selector(s) 'win(s)' following a set of order of precedence rules.
For example, from MDN:
Selector Types The following list of selector types increases by
specificity:
Type selectors (e.g., h1) and pseudo-elements (e.g., ::before).
Class selectors (e.g., .example), attributes selectors (e.g.,
[type="radio"]) and pseudo-classes (e.g., :hover).
ID selectors (e.g., #example).
So in the example given in the question:
ok
and CSS:
#id-selector {
color: green;
}
a:any-link {
color: red;
}
The color does not turn to red because the id selector takes precedence, even though the setting for a comes after in the 'cascade'.
Here's a snippet where the color does change (for this example on a hover):
#id-selector {
color: green;
}
a#id-selector:hover {
color: lime;
}
a:hover {
color: red;
}
</style>
ok
UPDATE
From comments I'm wondering if there is some confusion about pseudo elements (and classes) - they are 'part of' the one element, they are not a child of a 'parent' element.
This snippet has a parent/child and in that case the specificity as assumed in the question works:
#id-selector {
color: green;
}
a:hover {
color: red;
}
<div id="id-selector">ok</div>

Specificity of inherited CSS properties

What is the level of CSS specificity received by inherited properties? I read through the W3 recommendation regarding CSS specificity and so I understand how to calculate the different specificities of css rules which are directly targeting the same element, but I see no mention there of the level of specificity given to inherited attributes.
In particular, the issue I'm encountering has to do with header elements, though I would be very interested to understand this in general.
For example, here's a snippet of HTML:
<h2>This should be black</h2>
<div class="all_red_text">
<h2>This should be red</h2>
</div>
Now if I include some CSS like this:
.all_red_text { color: red; }
I will get the result I expect. On the other hand, if I the css which I included was
h2 { color: black; }
.all_red_text { color: red; }
then all the text will be black. In the first case there is some default browser CSS which is able to be overridden by the inherited property, but then when the same property is manually specified in the second example it takes precedence over the inherited property.
Any declaration that matches element directly will get priority over the property that's inherited from the element's parent. Specificity has nothing to do with that.
CSS is applied to elements in this form:
Priority 1: inline styles
Priority 2: CSS ID styles
Priority 3: CSS class/pseudo-class styles
Priority 4: CSS element styles
Priority 5: Inherited styles
So, using your HTML structure & CSS:
h2 { color: black; }
.all_red_text { color: red; }
<h2>This should be black (and is black)</h2>
<div class="all_red_text">
(This text is indeed red.)
<h2>This should be red (actually, its parent is red - this text is black)</h2>
</div>
The .all_red_text CSS is telling the div.all_red_text element and everything inside it to have red text. The h2 CSS is telling the h2 elements directly to have black text. When the h2 is rendered, it sees "my parent element wants me to have red text, but I'm directly being told to have black text". The same idea applies to further up parents, including the HTML and browser defaults - this allows you to, for example, set the font-family on the html element and have it apply to everything on your (well formatted) web page, unless something specifically overrides it.
If you want the h2 inside div.all_ted_text to also have red text, you'd need to tell those h2 elements directly to have red text; something like this:
.all_red_text h2 { color: red; }
CSS-Tricks has a pretty nice guide on this, although they don't currently go too deep into inherited properties.
There is no such thing as specificity of inherited CSS properties. Selectors, not properties, have specificity.
In your example, both h2 elements match only one of the rules, h2 { color: black; }. Thus, the color of h2 is black (assuming there are no other style sheets that affect the rendering). Anything set on some other elements (including the parent of the second h2 element) does not affect this the least.
If the rule h2 { color: black; } is absent and there are no other rules affecting the situation, then there is no color set on either of the h2 elements. According to the definition of the color property, the value is then inherited from the parent.
Two or more selectors gets engaged into Specificity War, if and only if
they end up targetting the exact same element. However, If two selectors (targetting the same element) have equal specificity weight, then there are other factors like you said, inheritance or the styles getting over ridden in the css file.

What is the difference between a pseudo-class and a pseudo-element in CSS?

Things like a:link or div::after...
Information on the difference seems scarce.
The CSS 3 selector recommendation is pretty clear about both, but I'll try to show the differences anyway.
Pseudo-classes
Official description
The pseudo-class concept is introduced to permit selection based on information that lies outside of the document tree or that cannot be expressed using the other simple selectors.
A pseudo-class always consists of a "colon" (:) followed by the name of the pseudo-class and optionally by a value between parentheses.
Pseudo-classes are allowed in all sequences of simple selectors contained in a selector. Pseudo-classes are allowed anywhere in sequences of simple selectors, after the leading type selector or universal selector (possibly omitted). Pseudo-class names are case-insensitive. Some pseudo-classes are mutually exclusive, while others can be applied simultaneously to the same element. Pseudo-classes may be dynamic, in the sense that an element may acquire or lose a pseudo-class while a user interacts with the document.
Source
What does this mean?
The important nature of pseudo-classes is stated in the very first sentence: "the pseudo-class concept [...] permit selection". It enables the author of an stylesheet to differ between elements based on information that "lies outside of the document tree", for example the current status of a link (:active,:visited). Those aren't saved anywhere in the DOM, and there exists no DOM interface to access these options.
On the other hand, :target could be accessed via DOM manipulation (you could use window.location.hash in order to find the object with JavaScript), but this "cannot be expressed using the other simple selectors".
So basically a pseudo-class will refine the set of selected elements as any other simple selector in a sequence of simple selectors. Note that all simple selectors in a sequence of simple selectors will be evaluated at the same time. For a complete list of pseudo-class check the CSS3 selector recommendation.
Example
The following example will color all even rows gray (#ccc), all uneven rows which aren't dividable by 5 white and every other row magenta.
table tr:nth-child(2n) td{
background-color: #ccc;
}
table tr:nth-child(2n+1) td{
background-color: #fff;
}
table tr:nth-child(2n+1):nth-child(5n) td{
background-color: #f0f;
}
Pseudo-elements
Official description
Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element's content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).
A pseudo-element is made of two colons (::) followed by the name of the pseudo-element.
This :: notation is introduced by the current document in order to establish a discrimination between pseudo-classes and pseudo-elements. For compatibility with existing style sheets, user agents must also accept the previous one-colon notation for pseudo-elements introduced in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and :after). This compatibility is not allowed for the new pseudo-elements introduced in this specification.
Only one pseudo-element may appear per selector, and if present it must appear after the sequence of simple selectors that represents the subjects of the selector.
Note: A future version of this specification may allow multiple pseudo-elements per selector.
Source
What does this mean?
The most important part here is that "pseudo-elements allow authors to refer to [..] otherwise inaccessible information" and that they "may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).". The biggest difference is that they actually create a new virtual element on which rules and even pseudo-class selectors can be applied to. They don't filter elements, they basically filter content (::first-line,::first-letter) and wrap it in a virtual container, which the author can style however he want (well, almost).
For example the ::first-line pseudo-element cannot be reconstructed with JavaScript, as it heavily depends on the current used font, the fonts size, the elements width, floating elements (and probably the time of the day). Well, that's not entirely true: one could still calculate all those values and extract the first line, however doing so is a very cumbersome activity.
I guess the biggest difference is that "only one pseudo-element may appear per selector". The note says that this could be subject to change, but as of 2012 I don't believe we see any different behavior in the future (it's still in CSS4).
Example
The following example will add a language-tag to every quote on a given page using the pseudo-class :lang and the pseudo-element ::after:
q:lang(de)::after{
content: " (German) ";
}
q:lang(en)::after{
content: " (English) ";
}
q:lang(fr)::after{
content: " (French) ";
}
q:not(:lang(fr)):not(:lang(de)):not(:lang(en))::after{
content: " (Unrecognized language) ";
}
TL;DR
Pseudo-classes act as simple selectors in a sequence of selectors and thereby classify elements on non-presentational characteristics, pseudo-elements create new virtual elements.
References
W3C
Selectors Level 3
4. Selector syntax
6.6 Pseudo-classes
7. Pseudo-elements
CSS 2.1 Specification (outdated but still informative)
5.2 Selector syntax:
A simple selector is either a type selector or universal selector followed immediately by zero or more attribute selectors, ID selectors, or pseudo-classes, in any order. The simple selector matches if all of its components match.
5.10 Pseudo-elements and pseudo-classes
A pseudo-class filters existing elements.
a:link means all <a>s that are :link.
A pseudo-element is a new fake element.
div::after means non-existing elements after <div>s.
::selection is another example of a pseudo-element.
It doesn't mean all elements that are selected; it means the range of content that is selected, which may span portions of multiple elements.
Short description that helped me to understand the difference:
Pseudo-classes describe a special state.
Pseudo-elements match virtual elements.
From the Sitepoint docs:
A pseudo-class is similar to a class in HTML, but it’s not specified explicitly in the markup. Some pseudo-classes are dynamic—they’re applied as a result of user interaction with the document. - http://reference.sitepoint.com/css/pseudoclasses. These would be things like :hover, :active, :visited.
Pseudo-elements match virtual elements that don’t exist explicitly in the document tree. Pseudo-elements can be dynamic, inasmuch as the virtual elements they represent can change, for example, when the width of the browser window is altered. They can also represent content that’s generated by CSS rules. - http://reference.sitepoint.com/css/pseudoelements. These would be things like ::before, ::after, ::first-letter.
Below is the simple answer:
We use pseudo-class when we need to apply css based on the state of an element. Such as:
Apply css on hover of anchor element (:hover)
Apply css when gets focus on an html element (:focus). etc.
We use pseudo-element when we need to apply css to the specific parts of an elements or a newly inserted content. Such as:
Apply the css to first letter or first line of an element (::first-letter)
Insert content before, or after, the content of an element (::before, ::after)
Below is the example of both:
<html>
<head>
<style>
p::first-letter { /* pseudo-element */
color: #ff0000;
}
a:hover { /* pseudo-class */
color: red;
}
</style>
</head>
<body>
<a href="#" >This is a link</a>
<p>This is a paragraph.</p>
</body>
</html>
A conceptual answer:
A pseudo-element refers to things that are part of the document, but you just don't know it yet. For example the first letter. Before you only had text. Now you have a first letter that you can target. It is a new concept, but was always part of the document. This also includes things like ::before; while there isn't actual content there, the concept of something before something else was always there -- now you are specifying it.
A pseudo-class is state of something in the DOM. Just like a class is a tag you associate with an element, a pseudo-class is a class that gets associated by the browser or DOM or whatever, usually as a response to a change in state. When a user visits a link -- that link can take on the state of 'visited'. You can imagine the browser applying the class 'visited' to the Anchor element. :visited would then be how you select for that pseudo-class.
Pseudo-Class
A pseudo-class is way of selecting certain parts of a HTML document, based in principle not on the HTML document tree itself and its elements or on characteristics like name, attributes or contents, but on other phantom conditions like language encoding or the dynamic state of an element.
The original pseudo-class defined dynamic states of an element that are entered and exited over time, or through user intervention. CSS2 expanded on this concept to include virtual conceptual document components or inferred portions of the document tree e.g. first-child. Pseudo-classes operate as if phantom classes were added to various elements.
RESTRICTIONS: Unlike pseudo-elements, pseudo-classes can appear anywhere in selector chain.
Example pseudo-class code:
a:link /* This selects any "a" element whose target has not been visited.*/
{
padding : 4px;
text-decoration : none;
width : 10%;
color : #000000; /* black text color */
background-color : #99FF99; /* set to a pastel green */
border-top : 2px solid #ccffcc; /* highlight color */
border-left : 2px solid #ccffcc; /* highlight color */
border-bottom : 2px solid #003300; /* shadow color */
border-right : 2px solid #003300; /* shadow color */
}
a:visited /* This selects any "a" element whose target has been visited.*/
{ padding : 4px;
text-decoration : none;
color : #000000; /* black text color */
background-color : #ccccff; /* set to a lavender */
border-top : 2px solid #ffffff; /* highlight color */
border-left : 2px solid #ffffff; /* highlight color */
border-bottom : 2px solid #333366; /* shadow color *
border-right : 2px solid #333366; /* shadow color */
}
a:hover /* This selects any "a" element which is in a hover state. This is a state during pointer movement within the rendering region of an element. The user designates an element but does not activate it. */
{
color : #000000; /* black text color */
background-color : #99cc99; /* desaturated color */
border-top : 2px solid #003300; /* shadow color */
border-left : 2px solid #003300; /* shadow color */
border-bottom : 2px solid #ccffcc; /* highlight color */
border-right : 2px solid #ccffcc; /* highlight color */
}
a:focus /* This selects any "a" element which currently has focus. Focus is a state during which an element accepts keyboard input or other forms of text input. */
{
padding : 4px;
text-decoration : none;
width : 10%;
color : #000000; /* black text color */
background-color : #ffff99; /* set to a pastel yellow */
border-top : 2px solid #ffffcc; /* highlight color */
border-left : 2px solid #ffffcc; /* highlight color */
border-bottom : 2px solid #666633; /* shadow color */
border-right : 2px solid #666633; /* shadow color */
}
a:active /* This selects any "a" element which is in a state of activation. Active is a state during pointer activation (eg: press and release of a mouse) within the rendering region of an element.*/
{
padding : 4px;
text-decoration : none;
width : 10%;
color : #000000; /* black text color */
background-color : #ff99ff; /* set to a pink */
border-top : 2px solid #ffccff; /* highlight color */
border-left : 2px solid #ffccff; /* highlight color */
border-bottom : 2px solid #663366; /* shadow color */
border-right : 2px solid #663366; /* shadow color */
}
A page that demonstrates a rendering of the above pseudo-class code
Pseudo-elements
PSEUDO-ELEMENTS are used to address sub-parts of elements. They allow you to set style on a part of an element's content beyond what is specified in the documents. In other words they allow logical elements to be defined which are not actually in the document element tree. Logical elements allow implied semantic structure to be addressed in CSS selectors.
RESTRICTIONS: Pseudo-elements may only be applied to external and document-level contexts - not to in-line styles. Pseudo-elements are restricted in where they can appear in a rule. They may only appear at the end of a selector chain (after the subject of the selector). They should come after any class or ID names found in the selector. Only one pseudo-element can be specified per selector. To address multiple pseudo-elements on a single element structure, multiple style selector/declaration statements must be made.
Pseudo-elements can be used for common typographic effects such as initial caps and drop caps. They can also address generated content that is not in the source document (with the "before" and "after") An example style sheet of some pseudo-elements with properties and values added follows.
/* The following rule selects the first letter of a heading 1 and sets the font to 2em, cursive, with a green background. First-letter selects the first rendered letter/character for a block-level element. */
h1:first-letter {
font-size : 2em;
font-family : "Lucida Handwriting", "Lucida Sans", "Lucida Console", cursive;
background-color : #ccffcc;
}
/* The following rule selects the first displayed line in a paragraph and makes it bold. First-line selects the first rendered line on the output device of a block-level element. */
p:first-line {
font-weight : bold;
}
/* The following rule selects any content placed before a blockquote and inserts the phrase "Quote of the day:" in bold small caps with a green background. */
blockquote:before {
content : "Quote of the day:";
background-color : #ccffcc;
font-weight : bold;
font-variant : small-caps;
}
/* The following rule selects any content placed before a "q" element and inserts the smart open quote. */
q:before {
content : open-quote;
}
/* The following rule selects any content placed after a "q" element and inserts the smart close quote. */
q:after{
content : close-quote;
}
Sources:Link
In brief, from Pseudo-classes on MDN:
A CSS pseudo-class is a keyword added to a selector that specifies
a special state of the selected element(s). For example, :hover
can be used to apply a style when the user hovers over a button.
div:hover {
background-color: #F89B4D;
}
And, from Pseudo-elements on MDN:
A CSS pseudo-element is a keyword added to a selector that lets you
style a specific part of the selected element(s). For example,
::first-line can be used to style the first line of a paragraph.
/* The first line of every <p> element. */
p::first-line {
color: blue;
text-transform: uppercase;
}

Find if class has border in css

Find if class has border in css only, by using attribute selector or by any other means.If it is not having then apply the border.Intention is Not to fall back on to either jquery. Is this possible to acheive?
Edited to include response from #nag (OP):
In IE8 there is no border for select. So I'm trying to do a css reset like this:
select, input[type="file"], textarea {
border: solid 1px #7F9DB9;
}
The problem is it is overriding any preexisiting style because of specificity. I tried to use expression filter but with DocType in IE8 it does not seem to work.
CSS has no concept, or implementation, of if/else statements, so this is not possible in CSS only.
However, if you define the border for an element, and then later redefine that border the second statement will override the first (assuming an equally specific selector), so I'm unsure as to why you need to apply a border only if the element doesn't already have a border defined:
div {
border: none; /* removes the border */
}
/* other stuff */
div {
border: 1px solid #f90; /* defines the border */
}
Similarly:
div {
border: 5px solid #0f0; /* defines the border */
}
/* other stuff */
div {
border: 1px solid #f90; /* re-defines the border */
}
If you can define your use-case it might be possible to help you further.
Edited to address the further information in the question:
In IE8 there is no border for select. So I'm trying to do a css reset like this:
select, input[type="file"], textarea {
border: solid 1px #7F9DB9;
}
The problem is it is overriding any preexisiting style because of specificity. I tried to use expression filter but with DocType in IE8 it does not seem to work.
If the problem is specificity, then the only options you have are to either increase the specificity of the selector you want to apply, ideally use an id, or multiple ids, in your selector (the id of an ancestor element is fine) since that's the most specific selector available.
Or, you can decrease the specificity of the selector you want to override.
It's worth noting that the select element is difficult to style reliably since it's often rendered by the underlying OS, rather than the browser itself, for a consistent look within that operating system.
You have three alternatives:
Use JavaScript - that has logic, so you can check whether it has a border or not and then do something with the result. You can use a library like jQuery or MooTools to make it easier.
Make this selector more specific, so that it only applies to elements that you want it to.
Make your other selectors more specific with classes, IDs, or nested selectors (like form textarea).

Resources